11namespace tracktion {
inline namespace engine
14namespace control_surface_utils
16inline void flipEndToEndIfNotAuto (InputDevice& in)
18 switch (in.getMonitorMode())
32ParameterSetting::ParameterSetting() noexcept
37void ParameterSetting::clear() noexcept
40 valueDescription[0] = 0;
44MarkerSetting::MarkerSetting() noexcept
49void MarkerSetting::clear() noexcept
57ControlSurface::ControlSurface (ExternalControllerManager& ecm)
58 : engine (ecm.engine), externalControllerManager (ecm)
62ControlSurface::~ControlSurface()
64 notifyListenersOfDeletion();
69 return deviceDescription;
72Edit* ControlSurface::getEditIfOnEditScreen()
const
74 if (engine.getUIBehaviour().getCurrentlyFocusedEdit() == getEdit())
80void ControlSurface::sendMidiCommandToController (
int idx,
const void* midiData,
int numBytes)
85void ControlSurface::sendMidiCommandToController (
int idx,
const juce::MidiMessage& m)
88 if (idx >= 0 && idx < (
int) owner->outputDevices.size())
89 if (
auto dev = owner->outputDevices[(
size_t) idx])
93bool ControlSurface::isSafeRecording()
const
95 return edit !=
nullptr && edit->getTransport().isSafeRecording();
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(); }
104#define RETURN_IF_SAFE_RECORDING if (isSafeRecording()) return;
106void ControlSurface::performIfNotSafeRecording (
const std::function<
void()>& f)
108 RETURN_IF_SAFE_RECORDING
112void ControlSurface::userMovedFader (
int channelNum,
float newSliderPos,
bool delta)
114 RETURN_IF_SAFE_RECORDING
115 if (delta || pickedUp (ctrlFader, channelNum, newSliderPos))
116 externalControllerManager.userMovedFader (owner->channelStart + channelNum, newSliderPos, delta);
119void ControlSurface::userMovedMasterLevelFader (
float newLevel,
bool delta)
121 RETURN_IF_SAFE_RECORDING
122 if (delta || pickedUp (ctrlMasterFader, newLevel))
123 externalControllerManager.userMovedMasterFader (getEdit(), newLevel, delta);
126void ControlSurface::userMovedMasterPanPot (
float newPan,
bool delta)
128 RETURN_IF_SAFE_RECORDING
129 if (delta || pickedUp (ctrlMasterPanPot, newPan))
130 externalControllerManager.userMovedMasterPanPot (getEdit(), newPan, delta);
133void ControlSurface::userMovedQuickParam (
float newLevel)
135 RETURN_IF_SAFE_RECORDING
136 externalControllerManager.userMovedQuickParam(newLevel);
139void ControlSurface::userMovedPanPot (
int channelNum,
float newPan,
bool delta)
141 RETURN_IF_SAFE_RECORDING
142 if (delta || pickedUp (ctrlPan, channelNum, newPan))
143 externalControllerManager.userMovedPanPot (owner->channelStart + channelNum, newPan, delta);
146void ControlSurface::userMovedAux (
int channelNum,
int auxNum,
float newPosition,
bool delta)
148 RETURN_IF_SAFE_RECORDING
149 if (delta || pickedUp (ctrlAux, channelNum, newPosition))
150 externalControllerManager.userMovedAux (owner->channelStart + channelNum, owner->auxBank + auxNum, auxMode, newPosition, delta);
153void ControlSurface::userPressedAux (
int channelNum,
int auxNum)
155 RETURN_IF_SAFE_RECORDING
156 externalControllerManager.userPressedAux (owner->channelStart + channelNum, owner->auxBank + auxNum);
159void ControlSurface::userPressedSolo (
int channelNum)
161 RETURN_IF_SAFE_RECORDING
162 externalControllerManager.userPressedSolo (owner->channelStart + channelNum);
165void ControlSurface::userPressedSoloIsolate (
int channelNum)
167 RETURN_IF_SAFE_RECORDING
168 externalControllerManager.userPressedSoloIsolate (owner->channelStart + channelNum);
171void ControlSurface::userPressedMute (
int channelNum,
bool muteVolumeControl)
173 RETURN_IF_SAFE_RECORDING
174 externalControllerManager.userPressedMute (owner->channelStart + channelNum, muteVolumeControl);
177void ControlSurface::userSelectedTrack (
int channelNum)
179 RETURN_IF_SAFE_RECORDING
180 externalControllerManager.userSelectedTrack (owner->channelStart + channelNum);
183void ControlSurface::userSelectedOneTrack (
int channelNum)
185 RETURN_IF_SAFE_RECORDING
186 externalControllerManager.userSelectedOneTrack (owner->channelStart + channelNum);
189void ControlSurface::userSelectedClipInTrack (
int channelNum)
191 RETURN_IF_SAFE_RECORDING
192 externalControllerManager.userSelectedClipInTrack (owner->channelStart + channelNum);
195void ControlSurface::userSelectedPluginInTrack (
int channelNum)
197 RETURN_IF_SAFE_RECORDING
198 externalControllerManager.userSelectedPluginInTrack (owner->channelStart + channelNum);
201void ControlSurface::userPressedClearAllSolo()
203 RETURN_IF_SAFE_RECORDING
205 if (
auto ed = getEditIfOnEditScreen())
210void ControlSurface::userPressedClearAllMute()
212 RETURN_IF_SAFE_RECORDING
214 if (
auto ed = getEditIfOnEditScreen())
219void ControlSurface::userPressedRecEnable (
int channelNum,
bool enableEtoE)
221 RETURN_IF_SAFE_RECORDING
223 if (
auto ed = getEditIfOnEditScreen())
225 channelNum += owner->channelStart;
227 if (
auto track = externalControllerManager.getChannelTrack (channelNum))
231 for (
auto in : ed->getAllInputDevices())
233 if (in->getTargets().contains (track->itemID))
235 if (in->isRecordingActive (track->itemID))
238 inactiveDev.
add (in);
244 for (
auto dev : activeDev)
245 control_surface_utils::flipEndToEndIfNotAuto (dev->owner);
247 for (
auto dev : inactiveDev)
248 control_surface_utils::flipEndToEndIfNotAuto (dev->owner);
252 if (activeDev.
size() > 0)
254 for (
auto dev : activeDev)
255 dev->setRecordingEnabled (track->itemID, false);
259 for (
auto dev : inactiveDev)
260 dev->setRecordingEnabled (track->itemID, true);
263 if (activeDev.
size() > 0 || inactiveDev.
size() > 0)
264 ed->restartPlayback();
270void ControlSurface::userLaunchedClip (
int channelNum,
int sceneNum)
272 RETURN_IF_SAFE_RECORDING
274 recentlyPressedPads.insert ({owner->channelStart + channelNum, owner->padStart + sceneNum});
276 externalControllerManager.userLaunchedClip (owner->channelStart + channelNum, owner->padStart + sceneNum);
277 externalControllerManager.updatePadColours();
280void ControlSurface::userStoppedClip (
int channelNum)
282 RETURN_IF_SAFE_RECORDING
284 externalControllerManager.userStoppedClip (owner->channelStart + channelNum);
287void ControlSurface::userLaunchedScene (
int sceneNum)
289 RETURN_IF_SAFE_RECORDING
291 externalControllerManager.userLaunchedScene (owner->padStart + sceneNum);
294void ControlSurface::userPressedHome() { performIfNotSafeRecording (&AppFunctions::goToStart); }
295void ControlSurface::userPressedEnd() { performIfNotSafeRecording (&AppFunctions::goToEnd); }
296void ControlSurface::userPressedMarkIn()
298 RETURN_IF_SAFE_RECORDING
299 AppFunctions::markIn (
true);
301void ControlSurface::userPressedMarkOut()
303 RETURN_IF_SAFE_RECORDING
304 AppFunctions::markOut (
true);
306void ControlSurface::userPressedPlay() { performIfNotSafeRecording (&AppFunctions::startStopPlay); }
307void ControlSurface::userPressedRecord() { performIfNotSafeRecording (&AppFunctions::record); }
309void ControlSurface::userPressedStop()
311 RETURN_IF_SAFE_RECORDING
313 if (
auto tc = getTransport())
315 if (tc->isPlaying() || tc->isRecording())
316 tc->stop (
false,
false);
318 tc->setPosition (0s);
322void ControlSurface::userPressedAutomationReading()
324 RETURN_IF_SAFE_RECORDING
326 if (
auto e = getEdit())
327 e->getAutomationRecordManager().setReadingAutomation (! e->getAutomationRecordManager().isReadingAutomation());
330void ControlSurface::userPressedAutomationWriting()
332 RETURN_IF_SAFE_RECORDING
334 if (
auto e = getEdit())
335 e->getAutomationRecordManager().toggleWriteAutomationMode();
338void ControlSurface::userToggledBeatsSecondsMode()
340 performIfNotSafeRecording (&AppFunctions::toggleTimecode);
343void ControlSurface::userChangedFaderBanks (
int channelNumDelta)
345 RETURN_IF_SAFE_RECORDING
346 owner->changeFaderBank (channelNumDelta, followsTrackSelection);
349void ControlSurface::userChangedPadBanks (
int padDelta)
351 RETURN_IF_SAFE_RECORDING
352 owner->changePadBank (padDelta);
355void ControlSurface::userChangedAuxBank (
int delta)
357 RETURN_IF_SAFE_RECORDING
358 owner->changeAuxBank (delta);
361void ControlSurface::userSetAuxBank (
int num)
363 RETURN_IF_SAFE_RECORDING
364 owner->setAuxBank (num);
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); }
385void ControlSurface::userChangedRewindButton (
bool isButtonDown)
387 RETURN_IF_SAFE_RECORDING
389 if (
auto tc = getTransport())
390 tc->setRewindButtonDown (isButtonDown);
393void ControlSurface::userChangedFastForwardButton (
bool isButtonDown)
395 RETURN_IF_SAFE_RECORDING
397 if (
auto tc = getTransport())
398 tc->setFastForwardButtonDown (isButtonDown);
401void ControlSurface::userMovedJogWheel (
float amount)
403 RETURN_IF_SAFE_RECORDING
405 if (
auto tc = getTransport())
409void ControlSurface::userMovedParameterControl (
int parameter,
float newValue,
bool delta)
411 RETURN_IF_SAFE_RECORDING
412 if (delta || pickedUp (ctrlParam, parameter, newValue))
413 owner->userMovedParameterControl (parameter, newValue, delta);
416void ControlSurface::userPressedParameterControl (
int paramNumber)
418 RETURN_IF_SAFE_RECORDING
419 owner->userPressedParameterControl (paramNumber);
422void ControlSurface::userPressedGoToMarker(
int marker)
424 RETURN_IF_SAFE_RECORDING
425 owner->userPressedGoToMarker (marker);
428void ControlSurface::selectOtherObject (SelectableClass::Relationship relationship,
bool moveFromCurrentPlugin)
430 owner->selectOtherObject (relationship, moveFromCurrentPlugin);
433void ControlSurface::muteOrUnmutePluginsInTrack()
435 owner->muteOrUnmutePluginsInTrack();
438void ControlSurface::userChangedParameterBank (
int deltaParams)
440 RETURN_IF_SAFE_RECORDING
441 owner->changeParamBank (deltaParams);
444void ControlSurface::userChangedMarkerBank (
int deltaMarkers)
446 RETURN_IF_SAFE_RECORDING
447 owner->changeMarkerBank (deltaMarkers);
450void ControlSurface::updateDeviceState()
452 owner->updateDeviceState();
453 owner->changeParamBank (0);
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); }
466void ControlSurface::userPressedCreateMarker()
468 RETURN_IF_SAFE_RECORDING
470 if (
auto ed = getEditIfOnEditScreen())
471 ed->getMarkerManager().createMarker (-1, ed->getTransport().getPosition(), {}, externalControllerManager.getSelectionManager());
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); }
485void ControlSurface::userPressedPaste (
bool insert)
487 performIfNotSafeRecording (insert ? &AppFunctions::insertPaste
488 : &AppFunctions::
paste);
491void ControlSurface::userPressedDelete (
bool marked)
493 performIfNotSafeRecording (marked ? &AppFunctions::deleteRegion
494 : &AppFunctions::deleteSelected);
497void ControlSurface::userPressedZoomFitToTracks() { performIfNotSafeRecording (&AppFunctions::zoomToFitVertically); }
498void ControlSurface::userPressedInsertTempoChange() { performIfNotSafeRecording (&AppFunctions::insertTempoChange); }
499void ControlSurface::userPressedInsertPitchChange() { performIfNotSafeRecording (&AppFunctions::insertPitchChange); }
500void ControlSurface::userPressedInsertTimeSigChange() { performIfNotSafeRecording (&AppFunctions::insertTimeSigChange); }
502void ControlSurface::userToggledVideoWindow() { performIfNotSafeRecording (&AppFunctions::showHideVideo); }
503void ControlSurface::userToggledMixerWindow (
bool fs)
505 RETURN_IF_SAFE_RECORDING
506 AppFunctions::showHideMixer (fs);
508void ControlSurface::userToggledMidiEditorWindow (
bool fs)
510 RETURN_IF_SAFE_RECORDING
511 AppFunctions::showHideMidiEditor (fs);
513void ControlSurface::userToggledTrackEditorWindow (
bool zoom)
515 RETURN_IF_SAFE_RECORDING
516 AppFunctions::showHideTrackEditor (zoom);
518void ControlSurface::userToggledBrowserWindow() { performIfNotSafeRecording (&AppFunctions::showHideBrowser); }
519void ControlSurface::userToggledActionsWindow() { performIfNotSafeRecording (&AppFunctions::showHideActions); }
520void ControlSurface::userPressedUserAction (
int action)
522 RETURN_IF_SAFE_RECORDING
523 AppFunctions::performUserAction (action);
526void ControlSurface::redrawSelectedPlugin() { owner->repaintParamSource(); }
527void ControlSurface::redrawSelectedTracks() { owner->redrawTracks(); }
529bool ControlSurface::pickedUp (ControlType type,
float value)
531 return pickedUp (type, 0, value);
534void ControlSurface::moveFader (
int channelNum,
float newSliderPos)
536 if (! pickUpMode)
return;
538 auto& info = pickUpMap[{ctrlFader, channelNum}];
539 info.lastOut = newSliderPos;
541 if (info.lastIn.has_value())
542 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
544 info.pickedUp =
false;
547void ControlSurface::movePanPot (
int channelNum,
float newPan)
549 if (! pickUpMode)
return;
551 auto& info = pickUpMap[{ctrlPan, channelNum}];
552 info.lastOut = newPan;
554 if (info.lastIn.has_value())
555 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
557 info.pickedUp =
false;
560void ControlSurface::moveAux (
int channel,
int auxNum,
const char*,
float newPos)
562 if (! pickUpMode)
return;
564 auto& info = pickUpMap[{ControlType (ctrlAux + auxNum), channel}];
565 info.lastOut = newPos;
567 if (info.lastIn.has_value())
568 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
570 info.pickedUp =
false;
573void ControlSurface::moveMasterLevelFader (
float newPos)
575 if (! pickUpMode)
return;
577 auto& info = pickUpMap[{ctrlMasterFader, 0}];
578 info.lastOut = newPos;
580 if (info.lastIn.has_value())
581 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
583 info.pickedUp =
false;
586void ControlSurface::moveMasterPanPot (
float newPan)
588 if (! pickUpMode)
return;
590 auto& info = pickUpMap[{ctrlMasterPanPot, 0}];
591 info.lastOut = newPan;
593 if (info.lastIn.has_value())
594 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
596 info.pickedUp =
false;
599void ControlSurface::parameterChanged (
int parameterNumber,
const ParameterSetting& newValue)
601 if (! pickUpMode)
return;
603 auto& info = pickUpMap[{ctrlParam, parameterNumber}];
604 info.lastOut = newValue.value;
606 if (info.lastIn.has_value())
607 info.pickedUp = std::abs (info.lastOut - *info.lastIn) <= 1.0f / 127.0f;
609 info.pickedUp =
false;
612bool ControlSurface::pickedUp (ControlType type,
int index,
float value)
614 if (! pickUpMode)
return true;
616 bool crossed =
false;
618 auto& info = pickUpMap[{type, index}];
619 if (! info.lastIn.has_value())
621 crossed = std::abs (value - info.lastOut) <= 1.0f / 127.0f;
626 auto v2 = *info.lastIn;
631 crossed = (info.lastOut >= v1 && info.lastOut <= v2);
636 info.pickedUp =
true;
638 return info.pickedUp;
641void ControlSurface::setFollowsTrackSelection (
bool f)
643 followsTrackSelection = f;
645 owner->followsTrackSelection = f;
int size() const noexcept
void add(const ElementType &newElement)
The Tracktion Edit class!
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.