tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_ControlSurface.cpp
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
14namespace control_surface_utils
15{
16inline void flipEndToEndIfNotAuto (InputDevice& in)
17{
18 switch (in.getMonitorMode())
19 {
21 return;
23 in.setMonitorMode (InputDevice::MonitorMode::off);
24 break;
26 in.setMonitorMode (InputDevice::MonitorMode::on);
27 return;
28 }
29}
30}
31
32ParameterSetting::ParameterSetting() noexcept
33{
34 clear();
35}
36
37void ParameterSetting::clear() noexcept
38{
39 label[0] = 0;
40 valueDescription[0] = 0;
41 value = 0.0f;
42}
43
44MarkerSetting::MarkerSetting() noexcept
45{
46 clear();
47}
48
49void MarkerSetting::clear() noexcept
50{
51 label[0] = 0;
52 number = 0;
53 absolute = 0;
54}
55
56//==============================================================================
57ControlSurface::ControlSurface (ExternalControllerManager& ecm)
58 : engine (ecm.engine), externalControllerManager (ecm)
59{
60}
61
62ControlSurface::~ControlSurface()
63{
64 notifyListenersOfDeletion();
65}
66
67juce::String ControlSurface::getSelectableDescription()
68{
69 return deviceDescription;
70}
71
72Edit* ControlSurface::getEditIfOnEditScreen() const
73{
74 if (engine.getUIBehaviour().getCurrentlyFocusedEdit() == getEdit())
75 return getEdit();
76
77 return {};
78}
79
80void ControlSurface::sendMidiCommandToController (int idx, const void* midiData, int numBytes)
81{
82 sendMidiCommandToController (idx, juce::MidiMessage (midiData, numBytes));
83}
84
85void ControlSurface::sendMidiCommandToController (int idx, const juce::MidiMessage& m)
86{
87 if (owner != nullptr)
88 if (idx >= 0 && idx < (int) owner->outputDevices.size())
89 if (auto dev = owner->outputDevices[(size_t) idx])
90 dev->fireMessage (m);
91}
92
93bool ControlSurface::isSafeRecording() const
94{
95 return edit != nullptr && edit->getTransport().isSafeRecording();
96}
97
98int ControlSurface::getMarkerBankOffset() const { return owner->getMarkerBankOffset(); }
99int ControlSurface::getFaderBankOffset() const { return owner->getFaderBankOffset(); }
100int ControlSurface::getAuxBankOffset() const { return owner->getAuxBankOffset(); }
101int ControlSurface::getParamBankOffset() const { return owner->getParamBankOffset(); }
102int ControlSurface::getClipSlotOffset() const { return owner->getClipSlotOffset(); }
103
104#define RETURN_IF_SAFE_RECORDING if (isSafeRecording()) return;
105
106void ControlSurface::performIfNotSafeRecording (const std::function<void()>& f)
107{
108 RETURN_IF_SAFE_RECORDING
109 f();
110}
111
112void ControlSurface::userMovedFader (int channelNum, float newSliderPos, bool delta)
113{
114 RETURN_IF_SAFE_RECORDING
115 if (delta || pickedUp (ctrlFader, channelNum, newSliderPos))
116 externalControllerManager.userMovedFader (owner->channelStart + channelNum, newSliderPos, delta);
117}
118
119void ControlSurface::userMovedMasterLevelFader (float newLevel, bool delta)
120{
121 RETURN_IF_SAFE_RECORDING
122 if (delta || pickedUp (ctrlMasterFader, newLevel))
123 externalControllerManager.userMovedMasterFader (getEdit(), newLevel, delta);
124}
125
126void ControlSurface::userMovedMasterPanPot (float newPan, bool delta)
127{
128 RETURN_IF_SAFE_RECORDING
129 if (delta || pickedUp (ctrlMasterPanPot, newPan))
130 externalControllerManager.userMovedMasterPanPot (getEdit(), newPan, delta);
131}
132
133void ControlSurface::userMovedQuickParam (float newLevel)
134{
135 RETURN_IF_SAFE_RECORDING
136 externalControllerManager.userMovedQuickParam(newLevel);
137}
138
139void ControlSurface::userMovedPanPot (int channelNum, float newPan, bool delta)
140{
141 RETURN_IF_SAFE_RECORDING
142 if (delta || pickedUp (ctrlPan, channelNum, newPan))
143 externalControllerManager.userMovedPanPot (owner->channelStart + channelNum, newPan, delta);
144}
145
146void ControlSurface::userMovedAux (int channelNum, int auxNum, float newPosition, bool delta)
147{
148 RETURN_IF_SAFE_RECORDING
149 if (delta || pickedUp (ctrlAux, channelNum, newPosition))
150 externalControllerManager.userMovedAux (owner->channelStart + channelNum, owner->auxBank + auxNum, auxMode, newPosition, delta);
151}
152
153void ControlSurface::userPressedAux (int channelNum, int auxNum)
154{
155 RETURN_IF_SAFE_RECORDING
156 externalControllerManager.userPressedAux (owner->channelStart + channelNum, owner->auxBank + auxNum);
157}
158
159void ControlSurface::userPressedSolo (int channelNum)
160{
161 RETURN_IF_SAFE_RECORDING
162 externalControllerManager.userPressedSolo (owner->channelStart + channelNum);
163}
164
165void ControlSurface::userPressedSoloIsolate (int channelNum)
166{
167 RETURN_IF_SAFE_RECORDING
168 externalControllerManager.userPressedSoloIsolate (owner->channelStart + channelNum);
169}
170
171void ControlSurface::userPressedMute (int channelNum, bool muteVolumeControl)
172{
173 RETURN_IF_SAFE_RECORDING
174 externalControllerManager.userPressedMute (owner->channelStart + channelNum, muteVolumeControl);
175}
176
177void ControlSurface::userSelectedTrack (int channelNum)
178{
179 RETURN_IF_SAFE_RECORDING
180 externalControllerManager.userSelectedTrack (owner->channelStart + channelNum);
181}
182
183void ControlSurface::userSelectedOneTrack (int channelNum)
184{
185 RETURN_IF_SAFE_RECORDING
186 externalControllerManager.userSelectedOneTrack (owner->channelStart + channelNum);
187}
188
189void ControlSurface::userSelectedClipInTrack (int channelNum)
190{
191 RETURN_IF_SAFE_RECORDING
192 externalControllerManager.userSelectedClipInTrack (owner->channelStart + channelNum);
193}
194
195void ControlSurface::userSelectedPluginInTrack (int channelNum)
196{
197 RETURN_IF_SAFE_RECORDING
198 externalControllerManager.userSelectedPluginInTrack (owner->channelStart + channelNum);
199}
200
201void ControlSurface::userPressedClearAllSolo()
202{
203 RETURN_IF_SAFE_RECORDING
204
205 if (auto ed = getEditIfOnEditScreen())
206 for (auto t : getAllTracks (*ed))
207 t->setSolo (false);
208}
209
210void ControlSurface::userPressedClearAllMute()
211{
212 RETURN_IF_SAFE_RECORDING
213
214 if (auto ed = getEditIfOnEditScreen())
215 for (auto t : getAllTracks (*ed))
216 t->setMute (false);
217}
218
219void ControlSurface::userPressedRecEnable (int channelNum, bool enableEtoE)
220{
221 RETURN_IF_SAFE_RECORDING
222
223 if (auto ed = getEditIfOnEditScreen())
224 {
225 channelNum += owner->channelStart;
226
227 if (auto track = externalControllerManager.getChannelTrack (channelNum))
228 {
229 juce::Array<InputDeviceInstance*> activeDev, inactiveDev;
230
231 for (auto in : ed->getAllInputDevices())
232 {
233 if (in->getTargets().contains (track->itemID))
234 {
235 if (in->isRecordingActive (track->itemID))
236 activeDev.add (in);
237 else
238 inactiveDev.add (in);
239 }
240 }
241
242 if (enableEtoE)
243 {
244 for (auto dev : activeDev)
245 control_surface_utils::flipEndToEndIfNotAuto (dev->owner);
246
247 for (auto dev : inactiveDev)
248 control_surface_utils::flipEndToEndIfNotAuto (dev->owner);
249 }
250 else
251 {
252 if (activeDev.size() > 0)
253 {
254 for (auto dev : activeDev)
255 dev->setRecordingEnabled (track->itemID, false);
256 }
257 else
258 {
259 for (auto dev : inactiveDev)
260 dev->setRecordingEnabled (track->itemID, true);
261 }
262
263 if (activeDev.size() > 0 || inactiveDev.size() > 0)
264 ed->restartPlayback();
265 }
266 }
267 }
268}
269
270void ControlSurface::userLaunchedClip (int channelNum, int sceneNum)
271{
272 RETURN_IF_SAFE_RECORDING
273
274 recentlyPressedPads.insert ({owner->channelStart + channelNum, owner->padStart + sceneNum});
275
276 externalControllerManager.userLaunchedClip (owner->channelStart + channelNum, owner->padStart + sceneNum);
277 externalControllerManager.updatePadColours();
278}
279
280void ControlSurface::userStoppedClip (int channelNum)
281{
282 RETURN_IF_SAFE_RECORDING
283
284 externalControllerManager.userStoppedClip (owner->channelStart + channelNum);
285}
286
287void ControlSurface::userLaunchedScene (int sceneNum)
288{
289 RETURN_IF_SAFE_RECORDING
290
291 externalControllerManager.userLaunchedScene (owner->padStart + sceneNum);
292}
293
294void ControlSurface::userPressedHome() { performIfNotSafeRecording (&AppFunctions::goToStart); }
295void ControlSurface::userPressedEnd() { performIfNotSafeRecording (&AppFunctions::goToEnd); }
296void ControlSurface::userPressedMarkIn()
297{
298 RETURN_IF_SAFE_RECORDING
299 AppFunctions::markIn (true);
300}
301void ControlSurface::userPressedMarkOut()
302{
303 RETURN_IF_SAFE_RECORDING
304 AppFunctions::markOut (true);
305}
306void ControlSurface::userPressedPlay() { performIfNotSafeRecording (&AppFunctions::startStopPlay); }
307void ControlSurface::userPressedRecord() { performIfNotSafeRecording (&AppFunctions::record); }
308
309void ControlSurface::userPressedStop()
310{
311 RETURN_IF_SAFE_RECORDING
312
313 if (auto tc = getTransport())
314 {
315 if (tc->isPlaying() || tc->isRecording())
316 tc->stop (false, false);
317 else
318 tc->setPosition (0s);
319 }
320}
321
322void ControlSurface::userPressedAutomationReading()
323{
324 RETURN_IF_SAFE_RECORDING
325
326 if (auto e = getEdit())
327 e->getAutomationRecordManager().setReadingAutomation (! e->getAutomationRecordManager().isReadingAutomation());
328}
329
330void ControlSurface::userPressedAutomationWriting()
331{
332 RETURN_IF_SAFE_RECORDING
333
334 if (auto e = getEdit())
335 e->getAutomationRecordManager().toggleWriteAutomationMode();
336}
337
338void ControlSurface::userToggledBeatsSecondsMode()
339{
340 performIfNotSafeRecording (&AppFunctions::toggleTimecode);
341}
342
343void ControlSurface::userChangedFaderBanks (int channelNumDelta)
344{
345 RETURN_IF_SAFE_RECORDING
346 owner->changeFaderBank (channelNumDelta, followsTrackSelection);
347}
348
349void ControlSurface::userChangedPadBanks (int padDelta)
350{
351 RETURN_IF_SAFE_RECORDING
352 owner->changePadBank (padDelta);
353}
354
355void ControlSurface::userChangedAuxBank (int delta)
356{
357 RETURN_IF_SAFE_RECORDING
358 owner->changeAuxBank (delta);
359}
360
361void ControlSurface::userSetAuxBank (int num)
362{
363 RETURN_IF_SAFE_RECORDING
364 owner->setAuxBank (num);
365}
366
367void ControlSurface::userToggledLoopOnOff() { performIfNotSafeRecording (&AppFunctions::toggleLoop); }
368void ControlSurface::userToggledPunchOnOff() { performIfNotSafeRecording (&AppFunctions::togglePunch); }
369void ControlSurface::userToggledSnapOnOff() { performIfNotSafeRecording (&AppFunctions::toggleSnap); }
370void ControlSurface::userToggledClickOnOff() { performIfNotSafeRecording (&AppFunctions::toggleClick); }
371void ControlSurface::userToggledSlaveOnOff() { performIfNotSafeRecording (&AppFunctions::toggleMidiChase); }
372void ControlSurface::userSkippedToNextMarkerLeft() { performIfNotSafeRecording (&AppFunctions::tabBack); }
373void ControlSurface::userSkippedToNextMarkerRight() { performIfNotSafeRecording (&AppFunctions::tabForward); }
374void ControlSurface::userNudgedLeft() { performIfNotSafeRecording (&AppFunctions::nudgeLeft); }
375void ControlSurface::userNudgedRight() { performIfNotSafeRecording (&AppFunctions::nudgeRight); }
376void ControlSurface::userZoomedIn() { performIfNotSafeRecording (&AppFunctions::zoomIn); }
377void ControlSurface::userZoomedOut() { performIfNotSafeRecording (&AppFunctions::zoomOut); }
378void ControlSurface::userScrolledTracksUp() { performIfNotSafeRecording (&AppFunctions::scrollTracksUp); }
379void ControlSurface::userScrolledTracksDown() { performIfNotSafeRecording (&AppFunctions::scrollTracksDown); }
380void ControlSurface::userScrolledTracksLeft() { performIfNotSafeRecording (&AppFunctions::scrollTracksLeft); }
381void ControlSurface::userScrolledTracksRight() { performIfNotSafeRecording (&AppFunctions::scrollTracksRight); }
382void ControlSurface::userZoomedTracksIn() { performIfNotSafeRecording (&AppFunctions::zoomTracksIn); }
383void ControlSurface::userZoomedTracksOut() { performIfNotSafeRecording (&AppFunctions::zoomTracksOut); }
384
385void ControlSurface::userChangedRewindButton (bool isButtonDown)
386{
387 RETURN_IF_SAFE_RECORDING
388
389 if (auto tc = getTransport())
390 tc->setRewindButtonDown (isButtonDown);
391}
392
393void ControlSurface::userChangedFastForwardButton (bool isButtonDown)
394{
395 RETURN_IF_SAFE_RECORDING
396
397 if (auto tc = getTransport())
398 tc->setFastForwardButtonDown (isButtonDown);
399}
400
401void ControlSurface::userMovedJogWheel (float amount)
402{
403 RETURN_IF_SAFE_RECORDING
404
405 if (auto tc = getTransport())
406 scrub (*tc, amount);
407}
408
409void ControlSurface::userMovedParameterControl (int parameter, float newValue, bool delta)
410{
411 RETURN_IF_SAFE_RECORDING
412 if (delta || pickedUp (ctrlParam, parameter, newValue))
413 owner->userMovedParameterControl (parameter, newValue, delta);
414}
415
416void ControlSurface::userPressedParameterControl (int paramNumber)
417{
418 RETURN_IF_SAFE_RECORDING
419 owner->userPressedParameterControl (paramNumber);
420}
421
422void ControlSurface::userPressedGoToMarker(int marker)
423{
424 RETURN_IF_SAFE_RECORDING
425 owner->userPressedGoToMarker (marker);
426}
427
428void ControlSurface::selectOtherObject (SelectableClass::Relationship relationship, bool moveFromCurrentPlugin)
429{
430 owner->selectOtherObject (relationship, moveFromCurrentPlugin);
431}
432
433void ControlSurface::muteOrUnmutePluginsInTrack()
434{
435 owner->muteOrUnmutePluginsInTrack();
436}
437
438void ControlSurface::userChangedParameterBank (int deltaParams)
439{
440 RETURN_IF_SAFE_RECORDING
441 owner->changeParamBank (deltaParams);
442}
443
444void ControlSurface::userChangedMarkerBank (int deltaMarkers)
445{
446 RETURN_IF_SAFE_RECORDING
447 owner->changeMarkerBank (deltaMarkers);
448}
449
450void ControlSurface::updateDeviceState()
451{
452 owner->updateDeviceState();
453 owner->changeParamBank (0);
454}
455
456void ControlSurface::userToggledEtoE() { performIfNotSafeRecording (&AppFunctions::toggleEndToEnd); }
457void ControlSurface::userPressedSave() { performIfNotSafeRecording (&AppFunctions::saveEdit); }
458void ControlSurface::userPressedSaveAs() { performIfNotSafeRecording (&AppFunctions::saveEditAs); }
459void ControlSurface::userPressedArmAll() { performIfNotSafeRecording (&AppFunctions::armOrDisarmAllInputs); }
460void ControlSurface::userPressedJumpToMarkIn() { performIfNotSafeRecording (&AppFunctions::goToMarkIn); }
461void ControlSurface::userPressedJumpToMarkOut() { performIfNotSafeRecording (&AppFunctions::goToMarkOut); }
462void ControlSurface::userPressedZoomIn() { performIfNotSafeRecording (&AppFunctions::zoomIn); }
463void ControlSurface::userPressedZoomOut() { performIfNotSafeRecording (&AppFunctions::zoomOut); }
464void ControlSurface::userPressedZoomToFit() { performIfNotSafeRecording (&AppFunctions::zoomToFitHorizontally); }
465
466void ControlSurface::userPressedCreateMarker()
467{
468 RETURN_IF_SAFE_RECORDING
469
470 if (auto ed = getEditIfOnEditScreen())
471 ed->getMarkerManager().createMarker (-1, ed->getTransport().getPosition(), {}, externalControllerManager.getSelectionManager());
472}
473
474void ControlSurface::userPressedNextMarker() { performIfNotSafeRecording (&AppFunctions::moveToNextMarker); }
475void ControlSurface::userPressedPreviousMarker() { performIfNotSafeRecording (&AppFunctions::moveToPrevMarker); }
476void ControlSurface::userPressedRedo() { performIfNotSafeRecording (&AppFunctions::redo); }
477void ControlSurface::userPressedUndo() { performIfNotSafeRecording (&AppFunctions::undo); }
478void ControlSurface::userToggledScroll() { performIfNotSafeRecording (&AppFunctions::toggleScroll); }
479void ControlSurface::userPressedAbort() { performIfNotSafeRecording (&AppFunctions::stopRecordingAndDiscard); }
480void ControlSurface::userPressedAbortRestart() { performIfNotSafeRecording (&AppFunctions::stopRecordingAndRestart); }
481void ControlSurface::userPressedCut() { performIfNotSafeRecording (&AppFunctions::cut); }
482void ControlSurface::userPressedCopy() { performIfNotSafeRecording (&AppFunctions::copy); }
483void ControlSurface::userPressedFreeze() { performIfNotSafeRecording (&AppFunctions::toggleTrackFreeze); }
484
485void ControlSurface::userPressedPaste (bool insert)
486{
487 performIfNotSafeRecording (insert ? &AppFunctions::insertPaste
488 : &AppFunctions::paste);
489}
490
491void ControlSurface::userPressedDelete (bool marked)
492{
493 performIfNotSafeRecording (marked ? &AppFunctions::deleteRegion
494 : &AppFunctions::deleteSelected);
495}
496
497void ControlSurface::userPressedZoomFitToTracks() { performIfNotSafeRecording (&AppFunctions::zoomToFitVertically); }
498void ControlSurface::userPressedInsertTempoChange() { performIfNotSafeRecording (&AppFunctions::insertTempoChange); }
499void ControlSurface::userPressedInsertPitchChange() { performIfNotSafeRecording (&AppFunctions::insertPitchChange); }
500void ControlSurface::userPressedInsertTimeSigChange() { performIfNotSafeRecording (&AppFunctions::insertTimeSigChange); }
501
502void ControlSurface::userToggledVideoWindow() { performIfNotSafeRecording (&AppFunctions::showHideVideo); }
503void ControlSurface::userToggledMixerWindow (bool fs)
504{
505 RETURN_IF_SAFE_RECORDING
506 AppFunctions::showHideMixer (fs);
507}
508void ControlSurface::userToggledMidiEditorWindow (bool fs)
509{
510 RETURN_IF_SAFE_RECORDING
511 AppFunctions::showHideMidiEditor (fs);
512}
513void ControlSurface::userToggledTrackEditorWindow (bool zoom)
514{
515 RETURN_IF_SAFE_RECORDING
516 AppFunctions::showHideTrackEditor (zoom);
517}
518void ControlSurface::userToggledBrowserWindow() { performIfNotSafeRecording (&AppFunctions::showHideBrowser); }
519void ControlSurface::userToggledActionsWindow() { performIfNotSafeRecording (&AppFunctions::showHideActions); }
520void ControlSurface::userPressedUserAction (int action)
521{
522 RETURN_IF_SAFE_RECORDING
523 AppFunctions::performUserAction (action);
524}
525
526void ControlSurface::redrawSelectedPlugin() { owner->repaintParamSource(); }
527void ControlSurface::redrawSelectedTracks() { owner->redrawTracks(); }
528
529bool ControlSurface::pickedUp (ControlType type, float value)
530{
531 return pickedUp (type, 0, value);
532}
533
534void ControlSurface::moveFader (int channelNum, float newSliderPos)
535{
536 if (! pickUpMode) return;
537
538 auto& info = pickUpMap[{ctrlFader, channelNum}];
539 info.lastOut = newSliderPos;
540
541 if (info.lastIn.has_value())
542 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
543 else
544 info.pickedUp = false;
545}
546
547void ControlSurface::movePanPot (int channelNum, float newPan)
548{
549 if (! pickUpMode) return;
550
551 auto& info = pickUpMap[{ctrlPan, channelNum}];
552 info.lastOut = newPan;
553
554 if (info.lastIn.has_value())
555 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
556 else
557 info.pickedUp = false;
558}
559
560void ControlSurface::moveAux (int channel, int auxNum, const char*, float newPos)
561{
562 if (! pickUpMode) return;
563
564 auto& info = pickUpMap[{ControlType (ctrlAux + auxNum), channel}];
565 info.lastOut = newPos;
566
567 if (info.lastIn.has_value())
568 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
569 else
570 info.pickedUp = false;
571}
572
573void ControlSurface::moveMasterLevelFader (float newPos)
574{
575 if (! pickUpMode) return;
576
577 auto& info = pickUpMap[{ctrlMasterFader, 0}];
578 info.lastOut = newPos;
579
580 if (info.lastIn.has_value())
581 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
582 else
583 info.pickedUp = false;
584}
585
586void ControlSurface::moveMasterPanPot (float newPan)
587{
588 if (! pickUpMode) return;
589
590 auto& info = pickUpMap[{ctrlMasterPanPot, 0}];
591 info.lastOut = newPan;
592
593 if (info.lastIn.has_value())
594 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
595 else
596 info.pickedUp = false;
597}
598
599void ControlSurface::parameterChanged (int parameterNumber, const ParameterSetting& newValue)
600{
601 if (! pickUpMode) return;
602
603 auto& info = pickUpMap[{ctrlParam, parameterNumber}];
604 info.lastOut = newValue.value;
605
606 if (info.lastIn.has_value())
607 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
608 else
609 info.pickedUp = false;
610}
611
612bool ControlSurface::pickedUp (ControlType type, int index, float value)
613{
614 if (! pickUpMode) return true;
615
616 bool crossed = false;
617
618 auto& info = pickUpMap[{type, index}];
619 if (! info.lastIn.has_value())
620 {
621 crossed = std::abs (value - info.lastOut) <= 1.0f / 127.0f;
622 }
623 else
624 {
625 auto v1 = value;
626 auto v2 = *info.lastIn;
627
628 if (v1 > v2)
629 std::swap (v1, v2);
630
631 crossed = (info.lastOut >= v1 && info.lastOut <= v2);
632 }
633
634 info.lastIn = value;
635 if (crossed)
636 info.pickedUp = true;
637
638 return info.pickedUp;
639}
640
641void ControlSurface::setFollowsTrackSelection (bool f)
642{
643 followsTrackSelection = f;
644 if (owner)
645 owner->followsTrackSelection = f;
646}
647
648}} // namespace tracktion { inline namespace engine
int size() const noexcept
void add(const ElementType &newElement)
The Tracktion Edit class!
@ automatic
Live input is audible when record is enabled.
@ off
Live input is never audible.
@ on
Live input is always audible.
juce::Array< Track * > getAllTracks(const Edit &edit)
Returns all the tracks in an Edit.
void scrub(TransportControl &tc, double units)
Scrubs back and forth in 'units', where a unit is about 1/50th of the width of the strip window.
T swap(T... args)