11namespace tracktion {
inline namespace engine
14bool ColourArea::contains (ClipSlot& clipSlot)
const
19 auto t = clipSlot.track.getIndexInEditTrackList();
20 auto s = clipSlot.getIndex();
22 if (t >= t1 && t <= t2 && s >= firstScene && s <= lastScene)
28bool ColourArea::isLeft (ClipSlot& clipSlot)
const
32 auto t = clipSlot.track.getIndexInEditTrackList();
33 auto s = clipSlot.getIndex();
35 if (t == t1 && s >= firstScene && s <= lastScene)
41bool ColourArea::isRight (ClipSlot& clipSlot)
const
45 auto t = clipSlot.track.getIndexInEditTrackList();
46 auto s = clipSlot.getIndex();
48 if (t == t2 && s >= firstScene && s <= lastScene)
54bool ColourArea::isTop (ClipSlot& clipSlot)
const
59 auto t = clipSlot.track.getIndexInEditTrackList();
60 auto s = clipSlot.getIndex();
62 if (t >= t1 && t <= t2 && s == firstScene)
68bool ColourArea::isBottom (ClipSlot& clipSlot)
const
73 auto t = clipSlot.track.getIndexInEditTrackList();
74 auto s = clipSlot.getIndex();
76 if (t >= t1 && t <= t2 && s == lastScene)
102 updatePads.
set (
true);
116 if (v.hasType (IDs::MARKERCLIP))
122 if (i == IDs::colour)
123 updatePads.
set (
true);
125 else if (v.hasType (IDs::PLUGIN))
127 if (i == IDs::volume || i == IDs::pan)
129 else if (i == IDs::auxSendSliderPos && v.getProperty (IDs::type) == AuxSendPlugin::xmlTypeName)
132 else if (v.hasType (IDs::TRACK))
135 owner.updateDeviceState();
141 if (c.hasType (IDs::MARKERCLIP))
147 if (c.hasType (IDs::MARKERCLIP))
151 void valueTreeChildOrderChanged (
juce::ValueTree&,
int,
int)
override {}
154 void timerCallback()
override
160 for (
int i = plugins.
size(); --i >= 0;)
168 owner.updateVolumePlugin (*mv);
175 if (
auto vp =
dynamic_cast<VolumeAndPanPlugin*
> (p.get()))
176 owner.updateVolumePlugin (*vp);
177 else if (
auto vca =
dynamic_cast<VCAPlugin*
> (p.get()))
178 owner.updateVCAPlugin (*vca);
184 owner.auxSendLevelsChanged();
187 owner.updatePadColours();
190 void handleAsyncUpdate()
override
192 owner.updateMarkers();
199ExternalControllerManager::ExternalControllerManager (
Engine& e) : engine (e)
202 masterLevelsTimer.setCallback ([
this]
204 if (currentEdit ==
nullptr)
207 auto ctx = currentEdit->getCurrentPlaybackContext();
211 auto l = ctx->masterLevels.getLevelCache();
212 masterLevelsChanged (dbToGain (l.first), dbToGain (l.second));
216ExternalControllerManager::~ExternalControllerManager()
218 jassert (currentEdit ==
nullptr);
221 setCurrentEdit (
nullptr,
nullptr);
224void ExternalControllerManager::initialise()
227 TRACKTION_LOG (
"Creating Default Controllers...");
229 #if TRACKTION_ENABLE_CONTROL_SURFACES
232 if (controllers.mackieMCU)
234 auto mcu =
new MackieMCU (*
this);
235 addNewController (mcu);
237 for (
int i = 0; i < getXTCount (mcu->deviceDescription); ++i)
238 addNewController (
new MackieXT (*
this, *mcu, i));
243 #if TRACKTION_ENABLE_CONTROL_SURFACE_MACKIEC4
244 if (controllers.mackieC4) addNewController (
new MackieC4 (*
this));
247 if (controllers.iconProG2)
249 auto icon =
new IconProG2 (*
this);
250 addNewController (icon);
251 for (
int i = 0; i < getXTCount (icon->deviceDescription); ++i)
252 addNewController (
new MackieXT (*
this, *icon, i));
255 if (controllers.tranzport) addNewController (
new TranzportControlSurface (*
this));
256 if (controllers.alphaTrack) addNewController (
new AlphaTrackControlSurface (*
this));
257 if (controllers.remoteSL) addNewController (
new NovationRemoteSl (*
this));
259 #if TRACKTION_ENABLE_AUTOMAP
260 if (controllers.automap)
262 automap =
new NovationAutomap (*
this);
263 addNewController (automap);
268 if (controllers.remoteSLCompact) addNewController (
new RemoteSLCompact (*
this));
272 TRACKTION_LOG (
"Loading Custom Controllers...");
274 for (
auto mc : CustomControlSurface::getCustomSurfaces (*this))
275 addNewController (mc);
281void ExternalControllerManager::shutdown()
284 jassert (currentEdit ==
nullptr && currentSelectionManager ==
nullptr);
285 setCurrentEdit (
nullptr,
nullptr);
288 currentEdit =
nullptr;
291ExternalController* ExternalControllerManager::addNewController (ControlSurface* cs)
293 return devices.add (
new ExternalController (engine, cs));
296#define FOR_EACH_DEVICE(x) \
297 for (auto device : devices) { device->x; }
299#define FOR_EACH_ACTIVE_DEVICE(x) \
300 for (auto device : devices) { if (device->isEnabled()) device->x; }
302void ExternalControllerManager::setCurrentEdit (Edit* newEdit, SelectionManager* newSM)
304 if (newEdit != currentEdit)
306 editTreeWatcher =
nullptr;
308 if (currentEdit !=
nullptr)
311 currentEdit = newEdit;
313 if (currentEdit !=
nullptr)
315 masterLevelsTimer.startTimer (1000 / 50);
325 if (newSM != currentSelectionManager)
327 if (currentSelectionManager !=
nullptr)
330 currentSelectionManager = newSM;
332 if (currentSelectionManager !=
nullptr)
336 FOR_EACH_ACTIVE_DEVICE (currentEditChanged (currentEdit));
337 FOR_EACH_ACTIVE_DEVICE (currentSelectionManagerChanged (currentSelectionManager));
340bool ExternalControllerManager::isAttachedToEdit (
const Edit* ed)
const noexcept
342 return currentEdit !=
nullptr && currentEdit == ed;
345bool ExternalControllerManager::isAttachedToEdit (
const Edit& e)
const noexcept
347 return isAttachedToEdit (&e);
350SelectionManager* ExternalControllerManager::getSelectionManager() const noexcept
352 return currentSelectionManager;
355void ExternalControllerManager::detachFromEdit (Edit* ed)
357 if (isAttachedToEdit (ed))
358 setCurrentEdit (
nullptr,
nullptr);
361void ExternalControllerManager::detachFromSelectionManager (SelectionManager* sm)
363 if (currentSelectionManager == sm)
364 setCurrentEdit (currentEdit,
nullptr);
367bool ExternalControllerManager::createCustomController (
const juce::String& name, Protocol protocol)
371 int outPort = 9000, inPort = 8000;
375 for (
auto device : devices)
377 if (device->needsOSCSocket())
379 outPort =
std::max (outPort, device->getOSCOutputPort() + 1);
380 inPort =
std::max (inPort, device->getOSCInputPort() + 1);
385 if (
auto ec = addNewController (
new CustomControlSurface (*
this, name, protocol)))
389 ec->setOSCOutputPort (outPort);
390 ec->setOSCInputPort (inPort);
398ExternalController* ExternalControllerManager::addController (ControlSurface* c)
402 int outPort = 9000, inPort = 8000;
404 if (c->needsOSCSocket)
406 for (
auto device : devices)
408 if (device->needsOSCSocket())
410 outPort =
std::max (outPort, device->getOSCOutputPort() + 1);
411 inPort =
std::max (inPort, device->getOSCInputPort() + 1);
416 if (
auto ec = addNewController (c))
418 if (c->needsOSCSocket)
420 ec->setOSCOutputPort (outPort);
421 ec->setOSCInputPort (inPort);
429void ExternalControllerManager::deleteController (ExternalController* c)
433 if (devices.contains (c))
435 #if TRACKTION_ENABLE_AUTOMAP && TRACKTION_ENABLE_CONTROL_SURFACES
436 if (c->controlSurface.get() == automap)
440 c->deleteController();
441 devices.removeObject (c);
450 for (
auto ec : devices)
456ExternalController* ExternalControllerManager::getActiveCustomController()
458 for (
auto ec : devices)
459 if (ec->isEnabled() && ec->isDeletable())
465void ExternalControllerManager::midiInOutDevicesChanged() { FOR_EACH_DEVICE (midiInOutDevicesChanged()); }
466void ExternalControllerManager::updateDeviceState() { FOR_EACH_ACTIVE_DEVICE (updateDeviceState()); }
467void ExternalControllerManager::updateParameters() { FOR_EACH_ACTIVE_DEVICE (updateParameters()); }
468void ExternalControllerManager::updateMarkers() { FOR_EACH_ACTIVE_DEVICE (updateMarkers()); }
469void ExternalControllerManager::updateTrackRecordLights() { FOR_EACH_ACTIVE_DEVICE (updateTrackRecordLights()); }
470void ExternalControllerManager::updatePunchLights() { FOR_EACH_ACTIVE_DEVICE (updatePunchLights()); }
471void ExternalControllerManager::updateScrollLights() { FOR_EACH_ACTIVE_DEVICE (updateScrollLights()); }
472void ExternalControllerManager::updateUndoLights() { FOR_EACH_ACTIVE_DEVICE (updateUndoLights()); }
473void ExternalControllerManager::updatePadColours() { FOR_EACH_ACTIVE_DEVICE (updatePadColours()); }
475void ExternalControllerManager::changeListenerCallback (
ChangeBroadcaster* source)
479 if (
auto tc =
dynamic_cast<TransportControl*
> (source))
481 playStateChanged (tc->isPlaying());
482 recordStateChanged (tc->isRecording());
485 else if (currentSelectionManager !=
nullptr)
487 auto& selectionManager = *currentSelectionManager;
489 if (selectionManager.getNumObjectsSelected() == 1 && selectionManager.containsType<Plugin>())
491 FOR_EACH_ACTIVE_DEVICE (selectedPluginChanged());
493 else if (
auto track = selectionManager.getFirstItemOfType<Track>())
495 int num = mapTrackNumToChannelNum (track->getIndexInEditTrackList());
497 for (
auto device : devices)
498 if (device->isEnabled())
499 if (device->followsTrackSelection)
500 if (num != -1 && num != device->channelStart)
501 device->changeFaderBank (num - device->channelStart, false);
503 FOR_EACH_ACTIVE_DEVICE (updateTrackSelectLights());
507void ExternalControllerManager::updateAllDevices()
513 if (now - lastUpdate > 250)
528void ExternalControllerManager::timerCallback()
541ExternalControllerManager::BlinkTimer::BlinkTimer (ExternalControllerManager& e) : ecm (e)
546void ExternalControllerManager::BlinkTimer::timerCallback()
548 isBright = ! isBright;
556 for (
auto d : devices)
558 activeDevices.add (d);
560 return activeDevices;
563void ExternalControllerManager::blinkNow()
565 updateMuteSoloLights (
true);
568void ExternalControllerManager::updateMuteSoloLights (
bool onlyUpdateFlashingLights)
570 if (currentEdit ==
nullptr)
573 const auto activeDevices = getActiveDevices();
579 const bool isBright = blinkTimer->isBright;
580 bool anySolo =
false;
584 if (t.isSolo (
false))
587 auto mappedChan = mapTrackNumToChannelNum (i);
591 const auto flags = t.getMuteAndSoloLightState();
594 || ! onlyUpdateFlashingLights)
596 for (
auto d : activeDevices)
597 d->updateSoloAndMute (mappedChan, flags, isBright);
605 for (
auto d : activeDevices)
606 d->soloCountChanged (blinkTimer->isBright && anySolo);
610void ExternalControllerManager::moveFader (
int channelNum,
float newSliderPos)
612 auto chan = mapTrackNumToChannelNum (channelNum);
614 FOR_EACH_ACTIVE_DEVICE (moveFader (chan, newSliderPos));
617void ExternalControllerManager::movePanPot (
int channelNum,
float newPan)
619 auto chan = mapTrackNumToChannelNum (channelNum);
621 FOR_EACH_ACTIVE_DEVICE (movePanPot (chan, newPan));
624void ExternalControllerManager::updateVolumePlugin (VolumeAndPanPlugin& vp)
626 if (
auto t =
dynamic_cast<AudioTrack*
> (vp.getOwnerTrack()))
628 if (t->getVolumePlugin() == &vp)
630 auto chan = mapTrackNumToChannelNum (t->getIndexInEditTrackList());
632 for (
auto c : devices)
636 c->moveFader (chan, vp.getSliderPos());
637 c->movePanPot (chan, vp.getPan());
644 if (vp.edit.getMasterVolumePlugin().get() == &vp)
646 FOR_EACH_ACTIVE_DEVICE (moveMasterFader (vp.getSliderPos()));
647 FOR_EACH_ACTIVE_DEVICE (moveMasterPanPot (vp.getPan()));
652void ExternalControllerManager::updateVCAPlugin (VCAPlugin& vca)
656 if (
auto t =
dynamic_cast<FolderTrack*
> (vca.getOwnerTrack()))
658 if (t->getVCAPlugin() == &vca)
660 auto chan = mapTrackNumToChannelNum (t->getIndexInEditTrackList());
662 for (
auto c : devices)
666 c->moveFader (chan, vca.getSliderPos());
667 c->movePanPot (chan, 0.0f);
674void ExternalControllerManager::moveMasterFader (
float newPos)
677 FOR_EACH_ACTIVE_DEVICE (moveMasterFader (newPos));
680void ExternalControllerManager::moveMasterPanPot (
float newPan)
683 FOR_EACH_ACTIVE_DEVICE (moveMasterPanPot (newPan));
686void ExternalControllerManager::soloCountChanged (
bool anySoloTracks)
689 FOR_EACH_ACTIVE_DEVICE (soloCountChanged (anySoloTracks));
692void ExternalControllerManager::playStateChanged (
bool isPlaying)
695 FOR_EACH_ACTIVE_DEVICE (playStateChanged (isPlaying));
698void ExternalControllerManager::recordStateChanged (
bool isRecording)
701 FOR_EACH_ACTIVE_DEVICE (recordStateChanged (
isRecording));
704void ExternalControllerManager::automationModeChanged (
bool isReading,
bool isWriting)
707 FOR_EACH_ACTIVE_DEVICE (automationModeChanged (isReading, isWriting));
710void ExternalControllerManager::channelLevelChanged (
int channel,
float l,
float r)
716 if (currentEdit ==
nullptr)
719 auto getChannelNum = [&]
722 channelNum = mapTrackNumToChannelNum (channel);
727 FOR_EACH_ACTIVE_DEVICE (channelLevelChanged (getChannelNum(), l, r));
730void ExternalControllerManager::masterLevelsChanged (
float leftLevel,
float rightLevel)
733 FOR_EACH_ACTIVE_DEVICE (masterLevelsChanged (leftLevel, rightLevel));
736void ExternalControllerManager::timecodeChanged (
int barsOrHours,
int beatsOrMinutes,
int ticksOrSeconds,
737 int millisecs,
bool isBarsBeats,
bool isFrames)
740 FOR_EACH_ACTIVE_DEVICE (timecodeChanged (barsOrHours, beatsOrMinutes, ticksOrSeconds, millisecs, isBarsBeats, isFrames));
743void ExternalControllerManager::snapChanged (
bool isOn)
746 FOR_EACH_ACTIVE_DEVICE (snapChanged (isOn));
749void ExternalControllerManager::loopChanged (
bool isOn)
752 FOR_EACH_ACTIVE_DEVICE (loopChanged (isOn));
755void ExternalControllerManager::clickChanged (
bool isOn)
758 FOR_EACH_ACTIVE_DEVICE (clickChanged (isOn));
761void ExternalControllerManager::editPositionChanged (Edit* ed, TimePosition newCursorPosition)
767 ed->getTimecodeFormat().getPartStrings (TimecodeDuration::fromSecondsOnly (toDuration (newCursorPosition)),
771 if (ed->getTimecodeFormat().isBarsBeats())
773 timecodeChanged (parts[2].getIntValue(),
774 parts[1].getIntValue(),
775 parts[0].getIntValue(),
777 ed->getTimecodeFormat().isBarsBeats(),
778 ed->getTimecodeFormat().isSMPTE());
782 timecodeChanged (parts[3].getIntValue(),
783 parts[2].getIntValue(),
784 parts[1].getIntValue(),
785 parts[0].getIntValue(),
786 ed->getTimecodeFormat().isBarsBeats(),
787 ed->getTimecodeFormat().isSMPTE());
793void ExternalControllerManager::auxSendLevelsChanged()
796 FOR_EACH_ACTIVE_DEVICE (auxSendLevelsChanged());
800void ExternalControllerManager::userMovedFader (
int channelNum,
float newSliderPos,
bool delta)
803 auto track = getChannelTrack (channelNum);
805 if (
auto at =
dynamic_cast<AudioTrack*
> (track))
807 if (
auto vp = at->getVolumePlugin())
808 vp->setSliderPos (delta ? vp->getSliderPos() + newSliderPos : newSliderPos);
810 moveFader (mapTrackNumToChannelNum (channelNum), decibelsToVolumeFaderPosition (0.0f));
813 if (
auto ft =
dynamic_cast<FolderTrack*
> (track))
815 if (
auto vca = ft->getVCAPlugin())
816 vca->setSliderPos (delta ? vca->getSliderPos() + delta : newSliderPos);
817 else if (
auto vp = ft->getVolumePlugin())
818 vp->setSliderPos (delta ? vp->getSliderPos() + delta : newSliderPos);
820 moveFader (mapTrackNumToChannelNum (channelNum), decibelsToVolumeFaderPosition (0.0f));
824void ExternalControllerManager::userMovedMasterFader (Edit* ed,
float newLevel,
bool delta)
829 ed->setMasterVolumeSliderPos (ed->getMasterSliderPosParameter()->getCurrentValue() + newLevel);
831 ed->setMasterVolumeSliderPos (newLevel);
835void ExternalControllerManager::userMovedMasterPanPot (Edit* ed,
float newPos,
bool delta)
838 ed->setMasterPanPos (delta ? ed->getMasterPanParameter()->getCurrentValue() + newPos : newPos);
841void ExternalControllerManager::userMovedPanPot (
int channelNum,
float newPan,
bool delta)
843 auto track = getChannelTrack (channelNum);
845 if (
auto t =
dynamic_cast<AudioTrack*
> (track))
847 if (
auto vp = t->getVolumePlugin())
848 vp->setPan (delta ? vp->getPan() + newPan : newPan);
850 else if (
auto ft =
dynamic_cast<FolderTrack*
> (track))
852 if (
auto vp = ft->getVolumePlugin())
853 vp->setPan (delta ? vp->getPan() + newPan : newPan);
857void ExternalControllerManager::userMovedAux (
int channelNum,
int auxNum, AuxPosition ap,
float newPosition,
bool delta)
859 if (
auto t =
dynamic_cast<AudioTrack*
> (getChannelTrack (channelNum)))
860 if (
auto aux = t->getAuxSendPlugin (auxNum, ap))
861 aux->setGainDb (volumeFaderPositionToDB (delta ? decibelsToVolumeFaderPosition (aux->getGainDb()) + newPosition : newPosition));
864void ExternalControllerManager::userPressedAux (
int channelNum,
int auxNum)
866 if (
auto t =
dynamic_cast<AudioTrack*
> (getChannelTrack (channelNum)))
867 if (
auto aux = t->getAuxSendPlugin (auxNum))
868 aux->setMute (! aux->isMute());
871void ExternalControllerManager::userLaunchedClip (
int channelNum,
int sceneNum)
874 if (
auto t = getChannelTrack (channelNum))
878void ExternalControllerManager::userStoppedClip (
int channelNum)
884 auto t = getChannelTrack (channelNum);
894void ExternalControllerManager::userLaunchedScene (
int sceneNum)
900void ExternalControllerManager::userMovedQuickParam (
float newLevel)
902 if (currentSelectionManager !=
nullptr)
903 if (
auto f = currentSelectionManager->getFirstItemOfType<Plugin>())
904 if (
auto param = f->getQuickControlParameter())
905 param->midiControllerMoved (newLevel);
908void ExternalControllerManager::userPressedSolo (
int channelNum)
910 if (
auto t = getChannelTrack (channelNum))
911 t->setSolo (! t->isSolo (
false));
914void ExternalControllerManager::userPressedSoloIsolate (
int channelNum)
916 if (
auto t = getChannelTrack (channelNum))
917 t->setSoloIsolate (! t->isSoloIsolate (
false));
920void ExternalControllerManager::userPressedMute (
int channelNum,
bool muteVolumeControl)
922 if (
auto t = getChannelTrack (channelNum))
924 if (muteVolumeControl)
926 if (
auto at =
dynamic_cast<AudioTrack*
> (t))
927 if (
auto vp = at->getVolumePlugin())
932 t->setMute (! t->isMuted (
false));
937void ExternalControllerManager::userSelectedTrack (
int channelNum)
939 if (
auto t = getChannelTrack (channelNum))
941 if (currentSelectionManager !=
nullptr)
943 if (currentSelectionManager->isSelected (t))
944 currentSelectionManager->deselect (t);
946 currentSelectionManager->addToSelection (t);
951void ExternalControllerManager::userSelectedOneTrack (
int channelNum)
953 if (
auto t = getChannelTrack (channelNum))
955 if (currentSelectionManager !=
nullptr)
956 currentSelectionManager->selectOnly (t);
961void ExternalControllerManager::userSelectedClipInTrack (
int channelNum)
963 if (currentSelectionManager !=
nullptr)
964 if (
auto t = getChannelTrack (channelNum))
965 if (t->getNumTrackItems() > 0)
966 if (
auto ti = t->getTrackItem (0))
967 currentSelectionManager->selectOnly (ti);
970void ExternalControllerManager::userSelectedPluginInTrack (
int channelNum)
972 if (currentSelectionManager !=
nullptr)
973 if (
auto t = getChannelTrack (channelNum))
974 if (
auto f = t->pluginList.getPlugins().getFirst())
975 currentSelectionManager->selectOnly (f.get());
979int ExternalControllerManager::getNumChannelTracks()
const
997Track* ExternalControllerManager::getChannelTrack (
int index)
const
999 Track* result =
nullptr;
1003 int i = 0, trackNum = 0;
1009 if (trackNum == index)
1026int ExternalControllerManager::mapTrackNumToChannelNum (
int index)
const
1028 if (currentEdit ==
nullptr || index < 0)
1037 int result = -1, i = 0, trackNum = 0;
1059bool ExternalControllerManager::shouldTrackBeColoured (
int channelNum)
1061 if (! devices.isEmpty())
1063 auto cn = mapTrackNumToChannelNum (channelNum);
1065 for (
auto& d : devices)
1066 if (d->shouldTrackBeColoured (cn))
1077 for (
auto device : devices)
1078 if (device->isEnabled())
1079 if (auto area = device->getColouredArea (e); area.has_value())
1085juce::Colour ExternalControllerManager::getTrackColour (
int channelNum)
1089 if (devices.isEmpty())
1092 auto activeDevices = getActiveDevices();
1097 auto cn = mapTrackNumToChannelNum (channelNum);
1099 for (
auto d : activeDevices)
1100 d->getTrackColour (cn, c);
1106void ExternalControllerManager::repaintTrack (
int channelNum)
1108 if (
auto t = getChannelTrack (channelNum))
1112void ExternalControllerManager::repaintSlots (
int channelNum)
1114 if (
auto t = getChannelTrack (channelNum))
1118bool ExternalControllerManager::shouldPluginBeColoured (Plugin* plugin)
1120 for (
auto d : devices)
1122 if (d->shouldPluginBeColoured (plugin))
1128juce::Colour ExternalControllerManager::getPluginColour (Plugin* plugin)
1131 FOR_EACH_ACTIVE_DEVICE (getPluginColour (plugin, c));
1135void ExternalControllerManager::repaintPlugin (Plugin& plugin)
1137 if (
auto c = PluginComponent::getComponentFor (plugin))
1141int ExternalControllerManager::getXTCount (
const juce::String& desc)
1143 if (desc ==
"Mackie Control Universal")
1149void ExternalControllerManager::setXTCount (
const juce::String& desc,
int after)
1154 #if TRACKTION_ENABLE_CONTROL_SURFACES
1155 for (
int devIdx = 0; devIdx < devices.size(); devIdx++)
1157 auto device = devices[devIdx];
1158 if (
auto mcu = device->getControlSurfaceIfType<MackieMCU>(); mcu !=
nullptr && mcu->deviceDescription == desc)
1160 int before = getXTCount (desc);
1161 int diff = after - before;
1165 for (
int i = 0; i < diff; ++i)
1166 devices.insert (devIdx + before + i + 1,
new ExternalController (engine,
new MackieXT (*
this, *mcu, before + i)));
1170 for (
int i = 0; i < std::abs (diff); ++i)
1171 devices.remove (devIdx + before - i);
1174 if (desc ==
"Mackie Control Universal")
1185void ExternalControllerManager::refreshXTOrder()
1189 #if TRACKTION_ENABLE_CONTROL_SURFACES
1190 for (
auto device : devices)
1192 if (
auto mcu = device->getControlSurfaceIfType<MackieMCU>())
1194 MackieXT* xt[MackieMCU::maxNumSurfaces - 1] = {};
1196 int offset = devices.indexOf (device);
1197 for (
int i = 0; i < getXTCount (mcu->deviceDescription); ++i)
1198 xt[i] = devices[offset + 1 + i] ? devices[offset + 1 + i]->getControlSurfaceIfType<MackieXT>() :
nullptr;
1201 if (mcu->deviceDescription ==
"Mackie Control Universal")
1204 indices.
addTokens (engine.
getPropertyStorage().getPropertyItem (SettingID::xtIndices, mcu->deviceDescription,
"0 1 2 3").toString(),
false);
1206 for (
int i = indices.
size(); --i >= 0;)
1207 if (indices[i].getIntValue() > getXTCount (mcu->deviceDescription))
1210 mcu->setDeviceIndex (indices.
indexOf (
"0"));
1212 if (xt[0] !=
nullptr) xt[0]->setDeviceIndex (indices.
indexOf (
"1"));
1213 if (xt[1] !=
nullptr) xt[1]->setDeviceIndex (indices.
indexOf (
"2"));
1214 if (xt[2] !=
nullptr) xt[2]->setDeviceIndex (indices.
indexOf (
"3"));
void swapWith(OtherArrayType &otherArray) noexcept
ElementType getUnchecked(int index) const
bool isEmpty() const noexcept
int size() const noexcept
bool addIfNotAlreadyThere(ParameterType newElement)
void triggerAsyncUpdate()
ChangeBroadcaster() noexcept
void addChangeListener(ChangeListener *listener)
void removeChangeListener(ChangeListener *listener)
int indexOf(StringRef stringToLookFor, bool ignoreCase=false, int startIndex=0) const
int size() const noexcept
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
static uint32 getMillisecondCounter() noexcept
void stopTimer() noexcept
bool isTimerRunning() const noexcept
void startTimer(int intervalInMilliseconds) noexcept
void addListener(Listener *listener)
void removeListener(Listener *listener)
static bool isClipState(const juce::ValueTree &)
Checks whether a ValueTree is some kind of clip state.
The Tracktion Edit class!
VolumeAndPanPlugin::Ptr getMasterVolumePlugin() const
Returns the master VolumeAndPanPlugin.
juce::ValueTree state
The ValueTree of the Edit state.
TransportControl & getTransport() const noexcept
Returns the TransportControl which is used to stop/stop/position playback and recording.
SceneList & getSceneList()
Returns a list of Scenes in the Edit.
PluginCache & getPluginCache() noexcept
Returns the PluginCache which manages all active Plugin[s] for this Edit.
void visitAllTracksRecursive(std::function< bool(Track &)>) const
Visits all tracks in the Edit with the given function.
virtual ControlSurfaces getDesiredControlSurfaces()
Return the control surfaces you want enabled in the engine.
PropertyStorage & getPropertyStorage() const
Returns the PropertyStorage user settings customisable XML file.
EngineBehaviour & getEngineBehaviour() const
Returns the EngineBehaviour instance.
Keeps a list of external controllers and keeps them connected to the right MIDI in/out devices.
std::function< void(Edit &, int)> launchScene
Launch scene by index.
std::function< void(Edit &, Track &, int)> launchClip
Launch clip by track and index.
std::function< int(Edit &, int)> mapEditTrackNumToControlSurfaceChannelNum
Optional callback that can be set to map an Edit track number to a control surface channel number.
std::function< void(Edit &, Track *)> stopClip
Stop all clips on track.
std::function< bool(const Track &)> isVisibleOnControlSurface
Callback that can be set to determine if a track is visible on a controller or not.
SceneWatcher sceneWatcher
A SceneWatcher you can listen to in order to be notified of changes to Slots.
void removeListener(Listener *)
Removes a previously added Listener.
void addListener(Listener *)
Adds a Listener.
int getIndexInEditTrackList() const
Returns the index of this track in a flat list of tracks contained in an Edit.
@ muteFlashing
Track is implicitly muted.
@ soloFlashing
Track is implicitly soloed.
void ignoreUnused(Types &&...) noexcept
juce::String getName(LaunchQType t)
Retuns the name of a LaunchQType for display purposes.
bool isRecording(EditPlaybackContext &epc)
Returns true if any inputs are currently recording.
void set(Type newValue) noexcept
bool compareAndSetBool(Type newValue, Type valueToCompare) noexcept
void slotUpdated(int, int) override
Destructor.
#define CRASH_TRACER
This macro adds the current location to a stack which gets logged if a crash happens.