11namespace tracktion {
inline namespace engine
15 : engine (e), type (t), deviceID (
std::
move (idToUse)), name (n)
17 alias = e.getPropertyStorage().getPropertyItem (SettingID::invalid, getAliasPropName());
20InputDevice::~InputDevice()
26 return type +
"in_" + name +
"_alias";
29bool InputDevice::isTrackDevice()
const
31 return getDeviceType() == trackWaveDevice
32 || getDeviceType() == trackMidiDevice;
37 if (alias.trim().isNotEmpty())
52 if (alias.isNotEmpty())
53 engine.getPropertyStorage().setPropertyItem (SettingID::invalid, getAliasPropName(), alias);
55 engine.getPropertyStorage().removePropertyItem (SettingID::invalid, getAliasPropName());
59bool InputDevice::isEnabled()
const
64void InputDevice::setMonitorMode (MonitorMode newMode)
66 if (monitorMode == newMode)
69 monitorMode = newMode;
70 TransportControl::restartAllTransports (engine,
false);
77 return name +
" (" + type +
")";
84 for (
auto* idi : devices)
85 idi->getInputDevice().retrospectiveRecordLock = lock;
90 : state (c.edit.getEditInputDevices().getInstanceStateForInputDevice (d)), owner (d), context (c), edit (c.edit)
92 trackDeviceEnabler.setFunction ([
this]
96 if (owner.isTrackDevice())
98 owner.setEnabled (destinations.size() > 0);
100 if (! owner.isEnabled())
101 state.getParent().removeChild (state, nullptr);
105 recordStatusUpdater.setFunction ([
this] { updateRecordingStatus(); });
107 state.addListener (
this);
120 if (ref.wasObjectDeleted())
123 if (!
owner.isEnabled())
129 if (
auto tID = dest->targetID; tID.isValid())
135tl::expected<InputDeviceInstance::Destination*, juce::String>
140 ClipSlot* clipSlot = track !=
nullptr ? nullptr
143 if (! (track || clipSlot))
147 return tl::unexpected (
TRANS(
"Can't change tracks whilst recording is active"));
149 if (
owner.isTrackDevice() || move)
156 [[ maybe_unused ]]
auto res =
removeTarget (targetID, um);
160 v.setProperty (IDs::targetID, targetID,
nullptr);
162 if (index.has_value())
163 v.setProperty (IDs::targetIndex, *index,
nullptr);
182 if (dt.targetID == targetID)
192 if (dest->recordEnabled)
201 if (targetID == dest->targetID)
202 return dest->recordEnabled;
210 if (dest->targetID == targetID)
211 if (dest->recordEnabled)
220 if (dest->targetID == targetID)
221 dest->recordEnabled = b;
226 if (! t.acceptsInput())
231 if (dest->targetID != t.itemID)
234 switch (
owner.getMonitorMode())
247 if (v.getParent() == state)
249 if (
id == IDs::armed ||
id == IDs::targetID)
251 const auto targetID = EditItemID::fromVar (v[IDs::targetID]);
253 if (
id == IDs::targetID)
257 changedTargetTrackIDs.push_back (targetID);
265 if (p == state && c.hasType (IDs::INPUTDEVICEDESTINATION))
267 const auto targetID = EditItemID::fromVar (c[IDs::targetID]);
272 changedTargetTrackIDs.push_back (targetID);
279 if (p == state && c.hasType (IDs::INPUTDEVICEDESTINATION))
281 const auto targetID = EditItemID::fromVar (c[IDs::targetID]);
286 changedTargetTrackIDs.push_back (targetID);
291ClipSlot* InputDeviceInstance::getFreeSlot (AudioTrack& t)
293 for (
auto slot : t.getClipSlotList().getClipSlots())
294 if (slot->getClip() == nullptr)
300 return t.getClipSlotList().getClipSlots().getLast();
303void InputDeviceInstance::updateRecordingStatus()
307 auto targetID = dest->targetID;
309 if (
std::find (changedTargetTrackIDs.begin(), changedTargetTrackIDs.end(), targetID) == changedTargetTrackIDs.end())
317 InputDeviceInstance::StopRecordingParameters params;
318 params.targetsToStop = { targetID };
319 params.unloopedTimeToEndRecording =
context.getUnloopedPosition();
320 params.isLooping =
context.transport.looping;
322 params.discardRecordings =
false;
324 Clip::Array clips = res.value_or (Clip::Array());
326 const bool wasRecording = ! clips.isEmpty();
330 if (! wasRecording && wasLivePlayActive != isLivePlayActive)
333 wasLivePlayActive = isLivePlayActive;
339 changedTargetTrackIDs.clear();
349 tracks.
add ({ at, dest->targetIndex });
367 if (at == &track && idx == index)
381 if (
auto res = instance.
removeTarget (targetID, um); ! res)
396 if (dest->targetID == track.itemID && dest->targetIndex == index)
405 if (dest->targetID == cs.
itemID)
414 if (dest->state == destinationState)
void add(const ElementType &newElement)
void handleUpdateNowIfNeeded()
void triggerAsyncUpdate()
CriticalSection & getAudioCallbackLock() noexcept
static Result fail(const String &errorMessage) noexcept
static Result ok() noexcept
String substring(int startIndex, int endIndex) const
void removeChild(const ValueTree &child, UndoManager *undoManager)
void addChild(const ValueTree &child, int index, UndoManager *undoManager)
Represents a slot on a track that a Clip can live in to be played as a launched clip.
const EditItemID itemID
Every EditItem has an ID which is unique within the edit.
void restartPlayback()
Use this to tell the play engine to rebuild the audio graph if the toplogy has changed.
SceneList & getSceneList()
Returns a list of Scenes in the Edit.
The Engine is the central class for all tracktion sessions.
DeviceManager & getDeviceManager() const
Returns the DeviceManager instance for handling audio / MIDI devices.
void ensureNumberOfScenes(int numScenes)
Adds Scenes to ensure numScenes are preset in the list.
static bool isSelectableValid(const Selectable *) noexcept
checks whether this object has been deleted.
Base class for tracks which contain clips and plugins and can be added to Edit[s].
TimeRange getLoopRange() const noexcept
Returns the loop range.
#define TRANS(stringLiteral)
juce::String getName(LaunchQType t)
Retuns the name of a LaunchQType for display purposes.
bool isAttached(InputDeviceInstance &instance)
Returns true if this input is assigned to a target.
juce::Array< std::pair< AudioTrack *, int > > getTargetTracksAndIndexes(InputDeviceInstance &instance)
Returns the AudioTracks and their indexes this instance is assigned to.
juce::Result clearFromTargets(InputDeviceInstance &instance, juce::UndoManager *um)
Removes this instance from all assigned targets.
ClipSlot * findClipSlotForID(const Edit &edit, EditItemID id)
Returns the ClipSlot for the given ID.
bool isOnTargetTrack(InputDeviceInstance &instance, const Track &track, int index)
Returns true if this instance is assigned to the given Track at the given index .
juce::Result prepareAndPunchRecord(InputDeviceInstance &instance, EditItemID targetID)
Starts an InputDeviceInstance recording to the given target without any count-in etc.
Track * findTrackForID(const Edit &edit, EditItemID id)
Returns the Track with a given ID if contained in the Edit.
AudioTrack * findAudioTrackForID(const Edit &edit, EditItemID id)
Returns the AudioTrack with a given ID if contained in the Edit.
InputDeviceInstance::Destination * getDestination(InputDeviceInstance &instance, const Track &track, int index)
Returns the destination if one has been assigned for the given arguments.
juce::Array< AudioTrack * > getTargetTracks(InputDeviceInstance &instance)
Returns the AudioTracks this instance is assigned to.
ID for objects of type EditElement - e.g.