diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index f8cf8cb5d..d5be34a1e 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -34,103 +34,57 @@ using juce::jmax; CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- -// Graph Ports - -GraphPorts::GraphPorts() noexcept - : ins(), - outs() {} - -const char* GraphPorts::getName(const bool isInput, const uint portId) const noexcept -{ - for (LinkedList::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next()) - { - static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; - - const PortNameToId& portNameToId(it.getValue(portNameFallback)); - CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); - - if (portNameToId.port == portId) - return portNameToId.name; - } - - return nullptr; -} - -uint GraphPorts::getPortId(const bool isInput, const char portName[], bool* const ok) const noexcept -{ - for (LinkedList::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next()) - { - static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; - - const PortNameToId& portNameToId(it.getValue(portNameFallback)); - CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); - - if (std::strncmp(portNameToId.name, portName, STR_MAX) == 0) - { - if (ok != nullptr) - *ok = true; - return portNameToId.port; - } - } - - if (ok != nullptr) - *ok = false; - return 0; -} - -// ----------------------------------------------------------------------- -// Rack Graph stuff +// External Graph stuff static inline -uint getCarlaRackPortIdFromName(const char* const shortname) noexcept +uint getExternalGraphPortIdFromName(const char* const shortname) noexcept { if (std::strcmp(shortname, "AudioIn1") == 0 || std::strcmp(shortname, "audio-in1") == 0) - return RACK_GRAPH_CARLA_PORT_AUDIO_IN1; + return kExternalGraphCarlaPortAudioIn1; if (std::strcmp(shortname, "AudioIn2") == 0 || std::strcmp(shortname, "audio-in2") == 0) - return RACK_GRAPH_CARLA_PORT_AUDIO_IN2; + return kExternalGraphCarlaPortAudioIn2; if (std::strcmp(shortname, "AudioOut1") == 0 || std::strcmp(shortname, "audio-out1") == 0) - return RACK_GRAPH_CARLA_PORT_AUDIO_OUT1; + return kExternalGraphCarlaPortAudioOut1; if (std::strcmp(shortname, "AudioOut2") == 0 || std::strcmp(shortname, "audio-out2") == 0) - return RACK_GRAPH_CARLA_PORT_AUDIO_OUT2; + return kExternalGraphCarlaPortAudioOut2; if (std::strcmp(shortname, "MidiIn") == 0 || std::strcmp(shortname, "midi-in") == 0) - return RACK_GRAPH_CARLA_PORT_MIDI_IN; + return kExternalGraphCarlaPortMidiIn; if (std::strcmp(shortname, "MidiOut") == 0 || std::strcmp(shortname, "midi-out") == 0) - return RACK_GRAPH_CARLA_PORT_MIDI_OUT; + return kExternalGraphCarlaPortMidiOut; - carla_stderr("CarlaBackend::getCarlaRackPortIdFromName(%s) - invalid short name", shortname); - return RACK_GRAPH_CARLA_PORT_NULL; + carla_stderr("CarlaBackend::getExternalGraphPortIdFromName(%s) - invalid short name", shortname); + return kExternalGraphCarlaPortNull; } static inline -const char* getCarlaRackFullPortNameFromId(const /*RackGraphCarlaPortIds*/ uint portId) +const char* getExternalGraphFullPortNameFromId(const /*RackGraphCarlaPortIds*/ uint portId) { switch (portId) { - case RACK_GRAPH_CARLA_PORT_AUDIO_IN1: + case kExternalGraphCarlaPortAudioIn1: return "Carla:AudioIn1"; - case RACK_GRAPH_CARLA_PORT_AUDIO_IN2: + case kExternalGraphCarlaPortAudioIn2: return "Carla:AudioIn2"; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT1: + case kExternalGraphCarlaPortAudioOut1: return "Carla:AudioOut1"; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT2: + case kExternalGraphCarlaPortAudioOut2: return "Carla:AudioOut2"; - case RACK_GRAPH_CARLA_PORT_MIDI_IN: + case kExternalGraphCarlaPortMidiIn: return "Carla:MidiIn"; - case RACK_GRAPH_CARLA_PORT_MIDI_OUT: + case kExternalGraphCarlaPortMidiOut: return "Carla:MidiOut"; - //case RACK_GRAPH_CARLA_PORT_NULL: - //case RACK_GRAPH_CARLA_PORT_MAX: + //case kExternalGraphCarlaPortNull: + //case kExternalGraphCarlaPortMax: // break; } - carla_stderr("CarlaBackend::getCarlaRackFullPortNameFromId(%i) - invalid port id", portId); + carla_stderr("CarlaBackend::getExternalGraphFullPortNameFromId(%i) - invalid port id", portId); return nullptr; } // ----------------------------------------------------------------------- -// RackGraph Audio Buffers -RackGraph::AudioBuffers::AudioBuffers() noexcept +ExternalGraphBuffers::ExternalGraphBuffers() noexcept : mutex(), connectedIn1(), connectedIn2(), @@ -148,92 +102,139 @@ RackGraph::AudioBuffers::AudioBuffers() noexcept } #endif -// ----------------------------------------------------------------------- -// RackGraph - -RackGraph::RackGraph(CarlaEngine* const engine, const uint32_t ins, const uint32_t outs) noexcept - : connections(), - inputs(ins), - outputs(outs), - isOffline(false), - retCon(), - audioBuffers(), - audioPorts(), - midiPorts(), - kEngine(engine) -{ - setBufferSize(engine->getBufferSize()); -} - -RackGraph::~RackGraph() noexcept -{ - clearConnections(); - clearPorts(); -} - -void RackGraph::setBufferSize(const uint32_t bufferSize) noexcept +void ExternalGraphBuffers::setBufferSize(const uint32_t bufferSize, const bool createBuffers) noexcept { const int bufferSizei(static_cast(bufferSize)); - if (audioBuffers.inBuf[0] != nullptr) { delete[] audioBuffers.inBuf[0]; audioBuffers.inBuf[0] = nullptr; } - if (audioBuffers.inBuf[1] != nullptr) { delete[] audioBuffers.inBuf[1]; audioBuffers.inBuf[1] = nullptr; } - if (audioBuffers.inBufTmp[0] != nullptr) { delete[] audioBuffers.inBufTmp[0]; audioBuffers.inBufTmp[0] = nullptr; } - if (audioBuffers.inBufTmp[1] != nullptr) { delete[] audioBuffers.inBufTmp[1]; audioBuffers.inBufTmp[1] = nullptr; } - if (audioBuffers.outBuf[0] != nullptr) { delete[] audioBuffers.outBuf[0]; audioBuffers.outBuf[0] = nullptr; } - if (audioBuffers.outBuf[1] != nullptr) { delete[] audioBuffers.outBuf[1]; audioBuffers.outBuf[1] = nullptr; } + const CarlaRecursiveMutexLocker cml(mutex); + + if (inBuf[0] != nullptr) { delete[] inBuf[0]; inBuf[0] = nullptr; } + if (inBuf[1] != nullptr) { delete[] inBuf[1]; inBuf[1] = nullptr; } + if (inBufTmp[0] != nullptr) { delete[] inBufTmp[0]; inBufTmp[0] = nullptr; } + if (inBufTmp[1] != nullptr) { delete[] inBufTmp[1]; inBufTmp[1] = nullptr; } + if (outBuf[0] != nullptr) { delete[] outBuf[0]; outBuf[0] = nullptr; } + if (outBuf[1] != nullptr) { delete[] outBuf[1]; outBuf[1] = nullptr; } CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,); try { - audioBuffers.inBufTmp[0] = new float[bufferSize]; - audioBuffers.inBufTmp[1] = new float[bufferSize]; + inBufTmp[0] = new float[bufferSize]; + inBufTmp[1] = new float[bufferSize]; - if (inputs > 0 || outputs > 0) + if (createBuffers) { - audioBuffers.inBuf[0] = new float[bufferSize]; - audioBuffers.inBuf[1] = new float[bufferSize]; - audioBuffers.outBuf[0] = new float[bufferSize]; - audioBuffers.outBuf[1] = new float[bufferSize]; + inBuf[0] = new float[bufferSize]; + inBuf[1] = new float[bufferSize]; + outBuf[0] = new float[bufferSize]; + outBuf[1] = new float[bufferSize]; } } catch(...) { - if (audioBuffers.inBufTmp[0] != nullptr) { delete[] audioBuffers.inBufTmp[0]; audioBuffers.inBufTmp[0] = nullptr; } - if (audioBuffers.inBufTmp[1] != nullptr) { delete[] audioBuffers.inBufTmp[1]; audioBuffers.inBufTmp[1] = nullptr; } + if (inBufTmp[0] != nullptr) { delete[] inBufTmp[0]; inBufTmp[0] = nullptr; } + if (inBufTmp[1] != nullptr) { delete[] inBufTmp[1]; inBufTmp[1] = nullptr; } - if (inputs > 0 || outputs > 0) + if (createBuffers) { - if (audioBuffers.inBuf[0] != nullptr) { delete[] audioBuffers.inBuf[0]; audioBuffers.inBuf[0] = nullptr; } - if (audioBuffers.inBuf[1] != nullptr) { delete[] audioBuffers.inBuf[1]; audioBuffers.inBuf[1] = nullptr; } - if (audioBuffers.outBuf[0] != nullptr) { delete[] audioBuffers.outBuf[0]; audioBuffers.outBuf[0] = nullptr; } - if (audioBuffers.outBuf[1] != nullptr) { delete[] audioBuffers.outBuf[1]; audioBuffers.outBuf[1] = nullptr; } + if (inBuf[0] != nullptr) { delete[] inBuf[0]; inBuf[0] = nullptr; } + if (inBuf[1] != nullptr) { delete[] inBuf[1]; inBuf[1] = nullptr; } + if (outBuf[0] != nullptr) { delete[] outBuf[0]; outBuf[0] = nullptr; } + if (outBuf[1] != nullptr) { delete[] outBuf[1]; outBuf[1] = nullptr; } } return; } - FloatVectorOperations::clear(audioBuffers.inBufTmp[0], bufferSizei); - FloatVectorOperations::clear(audioBuffers.inBufTmp[1], bufferSizei); + FloatVectorOperations::clear(inBufTmp[0], bufferSizei); + FloatVectorOperations::clear(inBufTmp[1], bufferSizei); - if (inputs > 0 || outputs > 0) + if (createBuffers) { - FloatVectorOperations::clear(audioBuffers.inBuf[0], bufferSizei); - FloatVectorOperations::clear(audioBuffers.inBuf[1], bufferSizei); - FloatVectorOperations::clear(audioBuffers.outBuf[0], bufferSizei); - FloatVectorOperations::clear(audioBuffers.outBuf[1], bufferSizei); + FloatVectorOperations::clear(inBuf[0], bufferSizei); + FloatVectorOperations::clear(inBuf[1], bufferSizei); + FloatVectorOperations::clear(outBuf[0], bufferSizei); + FloatVectorOperations::clear(outBuf[1], bufferSizei); } } -void RackGraph::setOffline(const bool offline) noexcept +// ----------------------------------------------------------------------- + +ExternalGraphPorts::ExternalGraphPorts() noexcept + : ins(), + outs() {} + +const char* ExternalGraphPorts::getName(const bool isInput, const uint portId) const noexcept { - isOffline = offline; + for (LinkedList::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next()) + { + static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; + + const PortNameToId& portNameToId(it.getValue(portNameFallback)); + CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); + + if (portNameToId.port == portId) + return portNameToId.name; + } + + return nullptr; } -bool RackGraph::connect(const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept +uint ExternalGraphPorts::getPortId(const bool isInput, const char portName[], bool* const ok) const noexcept +{ + for (LinkedList::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next()) + { + static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; + + const PortNameToId& portNameToId(it.getValue(portNameFallback)); + CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); + + if (std::strncmp(portNameToId.name, portName, STR_MAX) == 0) + { + if (ok != nullptr) + *ok = true; + return portNameToId.port; + } + } + + if (ok != nullptr) + *ok = false; + return 0; +} + +// ----------------------------------------------------------------------- + +ExternalGraph::ExternalGraph(CarlaEngine* const engine) noexcept + : connections(), + audioBuffers(), + audioPorts(), + midiPorts(), + retCon(), + kEngine(engine) {} + +void ExternalGraph::clearConnections() noexcept +{ + audioBuffers.mutex.lock(); + audioBuffers.connectedIn1.clear(); + audioBuffers.connectedIn2.clear(); + audioBuffers.connectedOut1.clear(); + audioBuffers.connectedOut2.clear(); + audioBuffers.mutex.unlock(); + connections.clear(); +} + +void ExternalGraph::clearPorts() noexcept +{ + audioPorts.ins.clear(); + audioPorts.outs.clear(); + midiPorts.ins.clear(); + midiPorts.outs.clear(); +} + +bool ExternalGraph::connect(const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept { uint otherGroup, otherPort, carlaPort; - if (groupA == RACK_GRAPH_GROUP_CARLA) + if (groupA == kExternalGraphGroupCarla) { - CARLA_SAFE_ASSERT_RETURN(groupB != RACK_GRAPH_GROUP_CARLA, false); + CARLA_SAFE_ASSERT_RETURN(groupB != kExternalGraphGroupCarla, false); carlaPort = portA; otherGroup = groupB; @@ -241,56 +242,56 @@ bool RackGraph::connect(const uint groupA, const uint portA, const uint groupB, } else { - CARLA_SAFE_ASSERT_RETURN(groupB == RACK_GRAPH_GROUP_CARLA, false); + CARLA_SAFE_ASSERT_RETURN(groupB == kExternalGraphGroupCarla, false); carlaPort = portB; otherGroup = groupA; otherPort = portA; } - CARLA_SAFE_ASSERT_RETURN(carlaPort > RACK_GRAPH_CARLA_PORT_NULL && carlaPort < RACK_GRAPH_CARLA_PORT_MAX, false); - CARLA_SAFE_ASSERT_RETURN(otherGroup > RACK_GRAPH_GROUP_CARLA && otherGroup < RACK_GRAPH_GROUP_MAX, false); + CARLA_SAFE_ASSERT_RETURN(carlaPort > kExternalGraphCarlaPortNull && carlaPort < kExternalGraphCarlaPortMax, false); + CARLA_SAFE_ASSERT_RETURN(otherGroup > kExternalGraphGroupCarla && otherGroup < kExternalGraphGroupMax, false); bool makeConnection = false; switch (carlaPort) { - case RACK_GRAPH_CARLA_PORT_AUDIO_IN1: - CARLA_SAFE_ASSERT_RETURN(otherGroup == RACK_GRAPH_GROUP_AUDIO_IN, false); + case kExternalGraphCarlaPortAudioIn1: + CARLA_SAFE_ASSERT_RETURN(otherGroup == kExternalGraphGroupAudioIn, false); audioBuffers.mutex.lock(); makeConnection = audioBuffers.connectedIn1.append(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_IN2: - CARLA_SAFE_ASSERT_RETURN(otherGroup == RACK_GRAPH_GROUP_AUDIO_IN, false); + case kExternalGraphCarlaPortAudioIn2: + CARLA_SAFE_ASSERT_RETURN(otherGroup == kExternalGraphGroupAudioIn, false); audioBuffers.mutex.lock(); makeConnection = audioBuffers.connectedIn2.append(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT1: - CARLA_SAFE_ASSERT_RETURN(otherGroup == RACK_GRAPH_GROUP_AUDIO_OUT, false); + case kExternalGraphCarlaPortAudioOut1: + CARLA_SAFE_ASSERT_RETURN(otherGroup == kExternalGraphGroupAudioOut, false); audioBuffers.mutex.lock(); makeConnection = audioBuffers.connectedOut1.append(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT2: - CARLA_SAFE_ASSERT_RETURN(otherGroup == RACK_GRAPH_GROUP_AUDIO_OUT, false); + case kExternalGraphCarlaPortAudioOut2: + CARLA_SAFE_ASSERT_RETURN(otherGroup == kExternalGraphGroupAudioOut, false); audioBuffers.mutex.lock(); makeConnection = audioBuffers.connectedOut2.append(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_MIDI_IN: - CARLA_SAFE_ASSERT_RETURN(otherGroup == RACK_GRAPH_GROUP_MIDI_IN, false); + case kExternalGraphCarlaPortMidiIn: + CARLA_SAFE_ASSERT_RETURN(otherGroup == kExternalGraphGroupMidiIn, false); if (const char* const portName = midiPorts.getName(true, otherPort)) makeConnection = kEngine->connectRackMidiInPort(portName); break; - case RACK_GRAPH_CARLA_PORT_MIDI_OUT: - CARLA_SAFE_ASSERT_RETURN(otherGroup == RACK_GRAPH_GROUP_MIDI_OUT, false); + case kExternalGraphCarlaPortMidiOut: + CARLA_SAFE_ASSERT_RETURN(otherGroup == kExternalGraphGroupMidiOut, false); if (const char* const portName = midiPorts.getName(false, otherPort)) makeConnection = kEngine->connectRackMidiOutPort(portName); break; @@ -315,7 +316,7 @@ bool RackGraph::connect(const uint groupA, const uint portA, const uint groupB, return true; } -bool RackGraph::disconnect(const uint connectionId) noexcept +bool ExternalGraph::disconnect(const uint connectionId) noexcept { CARLA_SAFE_ASSERT_RETURN(connections.list.count() > 0, false); @@ -331,9 +332,9 @@ bool RackGraph::disconnect(const uint connectionId) noexcept uint otherGroup, otherPort, carlaPort; - if (connectionToId.groupA == RACK_GRAPH_GROUP_CARLA) + if (connectionToId.groupA == kExternalGraphGroupCarla) { - CARLA_SAFE_ASSERT_RETURN(connectionToId.groupB != RACK_GRAPH_GROUP_CARLA, false); + CARLA_SAFE_ASSERT_RETURN(connectionToId.groupB != kExternalGraphGroupCarla, false); carlaPort = connectionToId.portA; otherGroup = connectionToId.groupB; @@ -341,50 +342,50 @@ bool RackGraph::disconnect(const uint connectionId) noexcept } else { - CARLA_SAFE_ASSERT_RETURN(connectionToId.groupB == RACK_GRAPH_GROUP_CARLA, false); + CARLA_SAFE_ASSERT_RETURN(connectionToId.groupB == kExternalGraphGroupCarla, false); carlaPort = connectionToId.portB; otherGroup = connectionToId.groupA; otherPort = connectionToId.portA; } - CARLA_SAFE_ASSERT_RETURN(carlaPort > RACK_GRAPH_CARLA_PORT_NULL && carlaPort < RACK_GRAPH_CARLA_PORT_MAX, false); - CARLA_SAFE_ASSERT_RETURN(otherGroup > RACK_GRAPH_GROUP_CARLA && otherGroup < RACK_GRAPH_GROUP_MAX, false); + CARLA_SAFE_ASSERT_RETURN(carlaPort > kExternalGraphCarlaPortNull && carlaPort < kExternalGraphCarlaPortMax, false); + CARLA_SAFE_ASSERT_RETURN(otherGroup > kExternalGraphGroupCarla && otherGroup < kExternalGraphGroupMax, false); bool makeDisconnection = false; switch (carlaPort) { - case RACK_GRAPH_CARLA_PORT_AUDIO_IN1: + case kExternalGraphCarlaPortAudioIn1: audioBuffers.mutex.lock(); makeDisconnection = audioBuffers.connectedIn1.removeOne(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_IN2: + case kExternalGraphCarlaPortAudioIn2: audioBuffers.mutex.lock(); makeDisconnection = audioBuffers.connectedIn2.removeOne(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT1: + case kExternalGraphCarlaPortAudioOut1: audioBuffers.mutex.lock(); makeDisconnection = audioBuffers.connectedOut1.removeOne(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT2: + case kExternalGraphCarlaPortAudioOut2: audioBuffers.mutex.lock(); makeDisconnection = audioBuffers.connectedOut2.removeOne(otherPort); audioBuffers.mutex.unlock(); break; - case RACK_GRAPH_CARLA_PORT_MIDI_IN: + case kExternalGraphCarlaPortMidiIn: if (const char* const portName = midiPorts.getName(true, otherPort)) makeDisconnection = kEngine->disconnectRackMidiInPort(portName); break; - case RACK_GRAPH_CARLA_PORT_MIDI_OUT: + case kExternalGraphCarlaPortMidiOut: if (const char* const portName = midiPorts.getName(false, otherPort)) makeDisconnection = kEngine->disconnectRackMidiOutPort(portName); break; @@ -406,28 +407,7 @@ bool RackGraph::disconnect(const uint connectionId) noexcept return false; } -void RackGraph::clearPorts() noexcept -{ - audioPorts.ins.clear(); - audioPorts.outs.clear(); - - midiPorts.ins.clear(); - midiPorts.outs.clear(); -} - -void RackGraph::clearConnections() noexcept -{ - connections.clear(); - - audioBuffers.mutex.lock(); - audioBuffers.connectedIn1.clear(); - audioBuffers.connectedIn2.clear(); - audioBuffers.connectedOut1.clear(); - audioBuffers.connectedOut2.clear(); - audioBuffers.mutex.unlock(); -} - -void RackGraph::refresh(const char* const deviceName) +void ExternalGraph::refresh(const char* const deviceName) { CARLA_SAFE_ASSERT_RETURN(deviceName != nullptr,); @@ -435,14 +415,14 @@ void RackGraph::refresh(const char* const deviceName) // Main { - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_CARLA, PATCHBAY_ICON_CARLA, -1, 0.0f, kEngine->getName()); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupCarla, PATCHBAY_ICON_CARLA, -1, 0.0f, kEngine->getName()); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in1"); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in2"); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out1"); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out2"); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, "midi-in"); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, PATCHBAY_PORT_TYPE_MIDI, 0.0f, "midi-out"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioIn1, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in1"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioIn2, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in2"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioOut1, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out1"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioOut2, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out2"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupCarla, kExternalGraphCarlaPortMidiIn, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, "midi-in"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupCarla, kExternalGraphCarlaPortMidiOut, PATCHBAY_PORT_TYPE_MIDI, 0.0f, "midi-out"); } char strBuf[STR_MAX+1]; @@ -455,7 +435,7 @@ void RackGraph::refresh(const char* const deviceName) else std::strncpy(strBuf, "Capture", STR_MAX); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_AUDIO_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupAudioIn, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); const CarlaString groupName(strBuf); @@ -465,7 +445,7 @@ void RackGraph::refresh(const char* const deviceName) PortNameToId& portNameToId(it.getValue()); portNameToId.setFullName(groupName + portNameToId.name); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_AUDIO_IN, ++h, + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupAudioIn, ++h, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, portNameToId.name); } } @@ -477,7 +457,7 @@ void RackGraph::refresh(const char* const deviceName) else std::strncpy(strBuf, "Playback", STR_MAX); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_AUDIO_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupAudioOut, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); const CarlaString groupName(strBuf); @@ -487,14 +467,14 @@ void RackGraph::refresh(const char* const deviceName) PortNameToId& portNameToId(it.getValue()); portNameToId.setFullName(groupName + portNameToId.name); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_AUDIO_OUT, ++h, + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupAudioOut, ++h, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); } } // MIDI In { - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_MIDI_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupMidiIn, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports"); const CarlaString groupNamePlus("Readable MIDI ports:"); @@ -504,14 +484,14 @@ void RackGraph::refresh(const char* const deviceName) PortNameToId& portNameToId(it.getValue()); portNameToId.setFullName(groupNamePlus + portNameToId.name); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_MIDI_IN, ++h, + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupMidiIn, ++h, PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name); } } // MIDI Out { - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_MIDI_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports"); + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupMidiOut, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports"); const CarlaString groupNamePlus("Writable MIDI ports:"); @@ -521,7 +501,7 @@ void RackGraph::refresh(const char* const deviceName) PortNameToId& portNameToId(it.getValue()); portNameToId.setFullName(groupNamePlus + portNameToId.name); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_MIDI_OUT, ++h, + kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupMidiOut, ++h, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); } } @@ -536,7 +516,7 @@ void RackGraph::refresh(const char* const deviceName) CARLA_SAFE_ASSERT_CONTINUE(portId <= audioPorts.ins.count()); // FIXME <= ConnectionToId connectionToId; - connectionToId.setData(++(connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1); + connectionToId.setData(++(connections.lastId), kExternalGraphGroupAudioIn, portId, kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioIn1); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); @@ -552,7 +532,7 @@ void RackGraph::refresh(const char* const deviceName) CARLA_SAFE_ASSERT_CONTINUE(portId <= audioPorts.ins.count()); // FIXME <= ConnectionToId connectionToId; - connectionToId.setData(++(connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2); + connectionToId.setData(++(connections.lastId), kExternalGraphGroupAudioIn, portId, kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioIn2); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); @@ -568,7 +548,7 @@ void RackGraph::refresh(const char* const deviceName) CARLA_SAFE_ASSERT_CONTINUE(portId <= audioPorts.outs.count()); // FIXME <= ConnectionToId connectionToId; - connectionToId.setData(++(connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, RACK_GRAPH_GROUP_AUDIO_OUT, portId); + connectionToId.setData(++(connections.lastId), kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioOut1, kExternalGraphGroupAudioOut, portId); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); @@ -584,7 +564,7 @@ void RackGraph::refresh(const char* const deviceName) CARLA_SAFE_ASSERT_CONTINUE(portId <= audioPorts.outs.count()); // FIXME <= ConnectionToId connectionToId; - connectionToId.setData(++(connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId); + connectionToId.setData(++(connections.lastId), kExternalGraphGroupCarla, kExternalGraphCarlaPortAudioOut2, kExternalGraphGroupAudioOut, portId); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); @@ -596,7 +576,7 @@ void RackGraph::refresh(const char* const deviceName) audioBuffers.mutex.unlock(); } -const char* const* RackGraph::getConnections() const noexcept +const char* const* ExternalGraph::getConnections() const noexcept { if (connections.list.count() == 0) return nullptr; @@ -615,9 +595,9 @@ const char* const* RackGraph::getConnections() const noexcept uint otherGroup, otherPort, carlaPort; - if (connectionToId.groupA == RACK_GRAPH_GROUP_CARLA) + if (connectionToId.groupA == kExternalGraphGroupCarla) { - CARLA_SAFE_ASSERT_CONTINUE(connectionToId.groupB != RACK_GRAPH_GROUP_CARLA); + CARLA_SAFE_ASSERT_CONTINUE(connectionToId.groupB != kExternalGraphGroupCarla); carlaPort = connectionToId.portA; otherGroup = connectionToId.groupB; @@ -625,41 +605,41 @@ const char* const* RackGraph::getConnections() const noexcept } else { - CARLA_SAFE_ASSERT_CONTINUE(connectionToId.groupB == RACK_GRAPH_GROUP_CARLA); + CARLA_SAFE_ASSERT_CONTINUE(connectionToId.groupB == kExternalGraphGroupCarla); carlaPort = connectionToId.portB; otherGroup = connectionToId.groupA; otherPort = connectionToId.portA; } - CARLA_SAFE_ASSERT_CONTINUE(carlaPort > RACK_GRAPH_CARLA_PORT_NULL && carlaPort < RACK_GRAPH_CARLA_PORT_MAX); - CARLA_SAFE_ASSERT_CONTINUE(otherGroup > RACK_GRAPH_GROUP_CARLA && otherGroup < RACK_GRAPH_GROUP_MAX); + CARLA_SAFE_ASSERT_CONTINUE(carlaPort > kExternalGraphCarlaPortNull && carlaPort < kExternalGraphCarlaPortMax); + CARLA_SAFE_ASSERT_CONTINUE(otherGroup > kExternalGraphGroupCarla && otherGroup < kExternalGraphGroupMax); switch (carlaPort) { - case RACK_GRAPH_CARLA_PORT_AUDIO_IN1: - case RACK_GRAPH_CARLA_PORT_AUDIO_IN2: + case kExternalGraphCarlaPortAudioIn1: + case kExternalGraphCarlaPortAudioIn2: std::snprintf(strBuf, STR_MAX, "AudioIn:%s", audioPorts.getName(true, otherPort)); connList.append(strBuf); - connList.append(getCarlaRackFullPortNameFromId(carlaPort)); + connList.append(getExternalGraphFullPortNameFromId(carlaPort)); break; - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT1: - case RACK_GRAPH_CARLA_PORT_AUDIO_OUT2: + case kExternalGraphCarlaPortAudioOut1: + case kExternalGraphCarlaPortAudioOut2: std::snprintf(strBuf, STR_MAX, "AudioOut:%s", audioPorts.getName(false, otherPort)); - connList.append(getCarlaRackFullPortNameFromId(carlaPort)); + connList.append(getExternalGraphFullPortNameFromId(carlaPort)); connList.append(strBuf); break; - case RACK_GRAPH_CARLA_PORT_MIDI_IN: + case kExternalGraphCarlaPortMidiIn: std::snprintf(strBuf, STR_MAX, "MidiIn:%s", midiPorts.getName(true, otherPort)); connList.append(strBuf); - connList.append(getCarlaRackFullPortNameFromId(carlaPort)); + connList.append(getExternalGraphFullPortNameFromId(carlaPort)); break; - case RACK_GRAPH_CARLA_PORT_MIDI_OUT: + case kExternalGraphCarlaPortMidiOut: std::snprintf(strBuf, STR_MAX, "MidiOut:%s", midiPorts.getName(false, otherPort)); - connList.append(getCarlaRackFullPortNameFromId(carlaPort)); + connList.append(getExternalGraphFullPortNameFromId(carlaPort)); connList.append(strBuf); break; } @@ -673,21 +653,21 @@ const char* const* RackGraph::getConnections() const noexcept return retCon; } -bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept +bool ExternalGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept { CARLA_SAFE_ASSERT_RETURN(fullPortName != nullptr && fullPortName[0] != '\0', false); if (std::strncmp(fullPortName, "Carla:", 6) == 0) { - groupId = RACK_GRAPH_GROUP_CARLA; - portId = getCarlaRackPortIdFromName(fullPortName+6); + groupId = kExternalGraphGroupCarla; + portId = getExternalGraphPortIdFromName(fullPortName+6); - if (portId > RACK_GRAPH_CARLA_PORT_NULL && portId < RACK_GRAPH_CARLA_PORT_MAX) + if (portId > kExternalGraphCarlaPortNull && portId < kExternalGraphCarlaPortMax) return true; } else if (std::strncmp(fullPortName, "AudioIn:", 8) == 0) { - groupId = RACK_GRAPH_GROUP_AUDIO_IN; + groupId = kExternalGraphGroupAudioIn; if (const char* const portName = fullPortName+8) { @@ -698,7 +678,7 @@ bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, ui } else if (std::strncmp(fullPortName, "AudioOut:", 9) == 0) { - groupId = RACK_GRAPH_GROUP_AUDIO_OUT; + groupId = kExternalGraphGroupAudioOut; if (const char* const portName = fullPortName+9) { @@ -709,7 +689,7 @@ bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, ui } else if (std::strncmp(fullPortName, "MidiIn:", 7) == 0) { - groupId = RACK_GRAPH_GROUP_MIDI_IN; + groupId = kExternalGraphGroupMidiIn; if (const char* const portName = fullPortName+7) { @@ -720,7 +700,7 @@ bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, ui } else if (std::strncmp(fullPortName, "MidiOut:", 8) == 0) { - groupId = RACK_GRAPH_GROUP_MIDI_OUT; + groupId = kExternalGraphGroupMidiOut; if (const char* const portName = fullPortName+8) { @@ -733,6 +713,70 @@ bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, ui return false; } +// ----------------------------------------------------------------------- +// RackGraph + +RackGraph::RackGraph(CarlaEngine* const engine, const uint32_t ins, const uint32_t outs) noexcept + : extGraph(engine), + inputs(ins), + outputs(outs), + isOffline(false), + kEngine(engine) +{ + setBufferSize(engine->getBufferSize()); +} + +RackGraph::~RackGraph() noexcept +{ + extGraph.clearConnections(); + extGraph.clearPorts(); +} + +void RackGraph::setBufferSize(const uint32_t bufferSize) noexcept +{ + extGraph.audioBuffers.setBufferSize(bufferSize, (inputs > 0 || outputs > 0)); +} + +void RackGraph::setOffline(const bool offline) noexcept +{ + isOffline = offline; +} + +bool RackGraph::connect(const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept +{ + return extGraph.connect(groupA, portA, groupB, portB); +} + +bool RackGraph::disconnect(const uint connectionId) noexcept +{ + return extGraph.disconnect(connectionId); +} + +void RackGraph::clearPorts() noexcept +{ + extGraph.clearPorts(); +} + +void RackGraph::clearConnections() noexcept +{ + extGraph.clearConnections(); +} + +void RackGraph::refresh(const char* const deviceName) +{ + extGraph.refresh(deviceName); +} + +const char* const* RackGraph::getConnections() const noexcept +{ + return extGraph.getConnections(); +} + +bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept +{ + return extGraph.getGroupAndPortIdFromFullName(fullPortName, groupId, portId); +} + void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inBufReal[2], float* outBuf[2], const uint32_t frames) { CARLA_SAFE_ASSERT_RETURN(data != nullptr,); @@ -855,6 +899,9 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB void RackGraph::processHelper(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames) { + // FIXME + ExternalGraphBuffers& audioBuffers(extGraph.audioBuffers); + CARLA_SAFE_ASSERT_RETURN(audioBuffers.outBuf[1] != nullptr,); const int iframes(static_cast(frames)); @@ -1311,23 +1358,25 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons midiBuffer(), inputs(carla_fixValue(0U, MAX_PATCHBAY_PLUGINS-2, ins)), outputs(carla_fixValue(0U, MAX_PATCHBAY_PLUGINS-2, outs)), - ignorePathbay(false), retCon(), - audioPorts(), - midiPorts(), + usingExternal(false), + extGraph(engine), kEngine(engine) { - const int bufferSize(static_cast(engine->getBufferSize())); - const double sampleRate(engine->getSampleRate()); + const uint32_t bufferSize(engine->getBufferSize()); + const int bufferSizei(static_cast(bufferSize)); + const double sampleRate(engine->getSampleRate()); - graph.setPlayConfigDetails(static_cast(inputs), static_cast(outputs), sampleRate, bufferSize); - graph.prepareToPlay(sampleRate, bufferSize); + graph.setPlayConfigDetails(static_cast(inputs), static_cast(outputs), sampleRate, bufferSizei); + graph.prepareToPlay(sampleRate, bufferSizei); - audioBuffer.setSize(static_cast(jmax(inputs, outputs)), bufferSize); + audioBuffer.setSize(static_cast(jmax(inputs, outputs)), bufferSizei); midiBuffer.ensureSize(kMaxEngineEventInternalCount*2); midiBuffer.clear(); + extGraph.audioBuffers.setBufferSize(bufferSize, (inputs > 0 || outputs > 0)); + { AudioProcessorGraph::AudioGraphIOProcessor* const proc(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode)); AudioProcessorGraph::Node* const node(graph.addNode(proc)); @@ -1375,18 +1424,24 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons PatchbayGraph::~PatchbayGraph() { - clearConnections(); - clearPorts(); + clearInternalConnections(); + extGraph.clearConnections(); + extGraph.clearPorts(); + graph.releaseResources(); graph.clear(); audioBuffer.clear(); } -void PatchbayGraph::setBufferSize(const int bufferSize) +void PatchbayGraph::setBufferSize(const uint32_t bufferSize) { + const int bufferSizei(static_cast(bufferSize)); + graph.releaseResources(); - graph.prepareToPlay(kEngine->getSampleRate(), bufferSize); - audioBuffer.setSize(audioBuffer.getNumChannels(), bufferSize); + graph.prepareToPlay(kEngine->getSampleRate(), bufferSizei); + audioBuffer.setSize(audioBuffer.getNumChannels(), bufferSizei); + + extGraph.audioBuffers.setBufferSize(bufferSize, (inputs > 0 || outputs > 0)); } void PatchbayGraph::setSampleRate(const double sampleRate) @@ -1414,7 +1469,7 @@ void PatchbayGraph::addPlugin(CarlaPlugin* const plugin) node->properties.set("isPlugin", true); node->properties.set("pluginId", static_cast(plugin->getId())); - if (! ignorePathbay) + if (! usingExternal) addNodeToPatchbay(plugin->getEngine(), node->nodeId, static_cast(plugin->getId()), instance); } @@ -1428,7 +1483,7 @@ void PatchbayGraph::replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* con AudioProcessorGraph::Node* const oldNode(graph.getNodeForId(oldPlugin->getPatchbayNodeId())); CARLA_SAFE_ASSERT_RETURN(oldNode != nullptr,); - if (! ignorePathbay) + if (! usingExternal) { disconnectGroup(oldNode->nodeId); removeNodeFromPatchbay(kEngine, oldNode->nodeId, oldNode->getProcessor()); @@ -1447,7 +1502,7 @@ void PatchbayGraph::replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* con node->properties.set("isPlugin", true); node->properties.set("pluginId", static_cast(newPlugin->getId())); - if (! ignorePathbay) + if (! usingExternal) addNodeToPatchbay(newPlugin->getEngine(), node->nodeId, static_cast(newPlugin->getId()), instance); } @@ -1459,7 +1514,7 @@ void PatchbayGraph::removePlugin(CarlaPlugin* const plugin) AudioProcessorGraph::Node* const node(graph.getNodeForId(plugin->getPatchbayNodeId())); CARLA_SAFE_ASSERT_RETURN(node != nullptr,); - if (! ignorePathbay) + if (! usingExternal) { disconnectGroup(node->nodeId); removeNodeFromPatchbay(kEngine, node->nodeId, node->getProcessor()); @@ -1495,7 +1550,7 @@ void PatchbayGraph::removeAllPlugins() AudioProcessorGraph::Node* const node(graph.getNodeForId(plugin->getPatchbayNodeId())); CARLA_SAFE_ASSERT_CONTINUE(node != nullptr); - if (! ignorePathbay) + if (! usingExternal) { disconnectGroup(node->nodeId); removeNodeFromPatchbay(kEngine, node->nodeId, node->getProcessor()); @@ -1601,16 +1656,7 @@ void PatchbayGraph::disconnectGroup(const uint groupId) noexcept } } -void PatchbayGraph::clearPorts() noexcept -{ - audioPorts.ins.clear(); - audioPorts.outs.clear(); - - midiPorts.ins.clear(); - midiPorts.outs.clear(); -} - -void PatchbayGraph::clearConnections() +void PatchbayGraph::clearInternalConnections() { connections.clear(); @@ -1620,79 +1666,33 @@ void PatchbayGraph::clearConnections() void PatchbayGraph::refresh(const char* const deviceName) { + if (usingExternal) + return extGraph.refresh(deviceName); + CARLA_SAFE_ASSERT_RETURN(deviceName != nullptr,); connections.clear(); graph.removeIllegalConnections(); - if (! ignorePathbay) - { - for (int i=0, count=graph.getNumNodes(); igetProcessor()); - CARLA_SAFE_ASSERT_CONTINUE(proc != nullptr); - - int clientId = -1; - - // plugin node - if (node->properties.getWithDefault("isPlugin", false) == juce::var(true)) - { - clientId = node->properties.getWithDefault("pluginId", -1); - } -#if 0 - // hardware node - else - { - // skip hardware midi nodes - if (node->properties.getWithDefault("isMIDI", false) == juce::var(true)) - continue; - } -#endif - - addNodeToPatchbay(kEngine, node->nodeId, clientId, proc); - } - } - -#if 0 - // MIDI In + for (int i=0, count=graph.getNumNodes(); icallback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_MIDI_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports"); - - const CarlaString groupNamePlus("Readable MIDI ports:"); - - int h = 0; - for (LinkedList::Itenerator it = midiPorts.ins.begin(); it.valid(); it.next()) - { - PortNameToId& portNameToId(it.getValue()); - portNameToId.setFullName(groupNamePlus + portNameToId.name); - - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_MIDI_IN, ++h, - PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name); - } - } + AudioProcessorGraph::Node* const node(graph.getNode(i)); + CARLA_SAFE_ASSERT_CONTINUE(node != nullptr); - // MIDI Out - { - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_MIDI_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports"); + AudioProcessor* const proc(node->getProcessor()); + CARLA_SAFE_ASSERT_CONTINUE(proc != nullptr); - const CarlaString groupNamePlus("Writable MIDI ports:"); + int clientId = -1; - int h = 0; - for (LinkedList::Itenerator it = midiPorts.outs.begin(); it.valid(); it.next()) - { - PortNameToId& portNameToId(it.getValue()); - portNameToId.setFullName(groupNamePlus + portNameToId.name); + // plugin node + if (node->properties.getWithDefault("isPlugin", false) == juce::var(true)) + clientId = node->properties.getWithDefault("pluginId", -1); - kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_MIDI_OUT, ++h, - PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); - } + addNodeToPatchbay(kEngine, node->nodeId, clientId, proc); } -#endif char strBuf[STR_MAX+1]; + strBuf[STR_MAX] = '\0'; for (int i=0, count=graph.getNumConnections(); icallback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); @@ -1731,7 +1730,10 @@ void PatchbayGraph::refresh(const char* const deviceName) const char* const* PatchbayGraph::getConnections(const bool external) const { - if (connections.list.count() == 0 || external) + if (external) + return extGraph.getConnections(); + + if (connections.list.count() == 0) return nullptr; CarlaStringList connList; @@ -1773,8 +1775,11 @@ const char* const* PatchbayGraph::getConnections(const bool external) const return retCon; } -bool PatchbayGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const +bool PatchbayGraph::getGroupAndPortIdFromFullName(const bool external, const char* const fullPortName, uint& groupId, uint& portId) const { + if (external) + return extGraph.getGroupAndPortIdFromFullName(fullPortName, groupId, portId); + String groupName(String(fullPortName).upToFirstOccurrenceOf(":", false, false)); String portName(String(fullPortName).fromFirstOccurrenceOf(":", false, false)); @@ -1937,7 +1942,7 @@ void EngineInternalGraph::setBufferSize(const uint32_t bufferSize) else { CARLA_SAFE_ASSERT_RETURN(fPatchbay != nullptr,); - fPatchbay->setBufferSize(static_cast(bufferSize)); + fPatchbay->setBufferSize(bufferSize); } } @@ -2040,10 +2045,10 @@ void EngineInternalGraph::removeAllPlugins() fPatchbay->removeAllPlugins(); } -void EngineInternalGraph::setIgnorePatchbay(const bool ignore) noexcept +void EngineInternalGraph::setUsingExternal(const bool usingExternal) noexcept { CARLA_SAFE_ASSERT_RETURN(fPatchbay != nullptr,); - fPatchbay->ignorePathbay = ignore; + fPatchbay->usingExternal = usingExternal; } // ----------------------------------------------------------------------- @@ -2094,28 +2099,23 @@ bool CarlaEngine::patchbayRefresh(const bool external) // subclasses should handle this CARLA_SAFE_ASSERT_RETURN(! external, false); - // FIXME if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) { - // This is implemented in engine subclasses for MIDI support + // This is implemented in engine subclasses setLastError("Unsupported operation"); return false; } - if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) - { - if (RackGraph* const graph = pData->graph.getRackGraph()) - graph->refresh(""); - } - else + if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) { if (PatchbayGraph* const graph = pData->graph.getPatchbayGraph()) - { graph->refresh(""); - } + + return true; } - return true; + setLastError("Unsupported operation"); + return false; } // ----------------------------------------------------------------------- @@ -2170,10 +2170,9 @@ void CarlaEngine::restorePatchbayConnection(const bool external, const char* con PatchbayGraph* const graph = pData->graph.getPatchbayGraph(); CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); - // TODO external - if (! graph->getGroupAndPortIdFromFullName(sourcePort, groupA, portA)) + if (! graph->getGroupAndPortIdFromFullName(external, sourcePort, groupA, portA)) return; - if (! graph->getGroupAndPortIdFromFullName(targetPort, groupB, portB)) + if (! graph->getGroupAndPortIdFromFullName(external, targetPort, groupB, portB)) return; } diff --git a/source/backend/engine/CarlaEngineGraph.hpp b/source/backend/engine/CarlaEngineGraph.hpp index bfb61b0f9..05b8fea37 100644 --- a/source/backend/engine/CarlaEngineGraph.hpp +++ b/source/backend/engine/CarlaEngineGraph.hpp @@ -31,66 +31,84 @@ using juce::MidiBuffer; CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- +// External Graph stuff + +enum ExternalGraphGroupIds { + kExternalGraphGroupNull = 0, + kExternalGraphGroupCarla = 1, + kExternalGraphGroupAudioIn = 2, + kExternalGraphGroupAudioOut = 3, + kExternalGraphGroupMidiIn = 4, + kExternalGraphGroupMidiOut = 5, + kExternalGraphGroupMax = 6 +}; + +enum ExternalGraphCarlaPortIds { + kExternalGraphCarlaPortNull = 0, + kExternalGraphCarlaPortAudioIn1 = 1, + kExternalGraphCarlaPortAudioIn2 = 2, + kExternalGraphCarlaPortAudioOut1 = 3, + kExternalGraphCarlaPortAudioOut2 = 4, + kExternalGraphCarlaPortMidiIn = 5, + kExternalGraphCarlaPortMidiOut = 6, + kExternalGraphCarlaPortMax = 7 +}; -struct GraphPorts { +struct ExternalGraphBuffers { + CarlaRecursiveMutex mutex; + LinkedList connectedIn1; + LinkedList connectedIn2; + LinkedList connectedOut1; + LinkedList connectedOut2; + float* inBuf[2]; + float* inBufTmp[2]; + float* outBuf[2]; + ExternalGraphBuffers() noexcept; + void setBufferSize(const uint32_t bufferSize, const bool createBuffers) noexcept; + CARLA_PREVENT_HEAP_ALLOCATION + CARLA_DECLARE_NON_COPY_CLASS(ExternalGraphBuffers) +}; + +struct ExternalGraphPorts { LinkedList ins; LinkedList outs; const char* getName(const bool isInput, const uint portId) const noexcept; uint getPortId(const bool isInput, const char portName[], bool* const ok = nullptr) const noexcept; - GraphPorts() noexcept; + ExternalGraphPorts() noexcept; CARLA_PREVENT_HEAP_ALLOCATION - CARLA_DECLARE_NON_COPY_CLASS(GraphPorts) + CARLA_DECLARE_NON_COPY_CLASS(ExternalGraphPorts) }; -// ----------------------------------------------------------------------- -// Rack Graph stuff - -enum RackGraphGroupIds { - RACK_GRAPH_GROUP_NULL = 0, - RACK_GRAPH_GROUP_CARLA = 1, - RACK_GRAPH_GROUP_AUDIO_IN = 2, - RACK_GRAPH_GROUP_AUDIO_OUT = 3, - RACK_GRAPH_GROUP_MIDI_IN = 4, - RACK_GRAPH_GROUP_MIDI_OUT = 5, - RACK_GRAPH_GROUP_MAX = 6 -}; +struct ExternalGraph { + PatchbayConnectionList connections; + ExternalGraphBuffers audioBuffers; + ExternalGraphPorts audioPorts, midiPorts; + mutable CharStringListPtr retCon; + ExternalGraph(CarlaEngine* const engine) noexcept; + + void clearConnections() noexcept; + void clearPorts() noexcept; -enum RackGraphCarlaPortIds { - RACK_GRAPH_CARLA_PORT_NULL = 0, - RACK_GRAPH_CARLA_PORT_AUDIO_IN1 = 1, - RACK_GRAPH_CARLA_PORT_AUDIO_IN2 = 2, - RACK_GRAPH_CARLA_PORT_AUDIO_OUT1 = 3, - RACK_GRAPH_CARLA_PORT_AUDIO_OUT2 = 4, - RACK_GRAPH_CARLA_PORT_MIDI_IN = 5, - RACK_GRAPH_CARLA_PORT_MIDI_OUT = 6, - RACK_GRAPH_CARLA_PORT_MAX = 7 + bool connect(const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept; + bool disconnect(const uint connectionId) noexcept; + void refresh(const char* const deviceName); + + const char* const* getConnections() const noexcept; + bool getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept; + + CarlaEngine* const kEngine; + CARLA_PREVENT_HEAP_ALLOCATION + CARLA_DECLARE_NON_COPY_CLASS(ExternalGraph) }; // ----------------------------------------------------------------------- // RackGraph struct RackGraph { - PatchbayConnectionList connections; + ExternalGraph extGraph; const uint32_t inputs; const uint32_t outputs; bool isOffline; - mutable CharStringListPtr retCon; - - struct AudioBuffers { - CarlaRecursiveMutex mutex; - LinkedList connectedIn1; - LinkedList connectedIn2; - LinkedList connectedOut1; - LinkedList connectedOut2; - float* inBuf[2]; - float* inBufTmp[2]; - float* outBuf[2]; - AudioBuffers() noexcept; - CARLA_PREVENT_HEAP_ALLOCATION - CARLA_DECLARE_NON_COPY_CLASS(AudioBuffers) - } audioBuffers; - - GraphPorts audioPorts, midiPorts; RackGraph(CarlaEngine* const engine, const uint32_t inputs, const uint32_t outputs) noexcept; ~RackGraph() noexcept; @@ -127,15 +145,15 @@ struct PatchbayGraph { MidiBuffer midiBuffer; const uint32_t inputs; const uint32_t outputs; - bool ignorePathbay; mutable CharStringListPtr retCon; + bool usingExternal; - GraphPorts audioPorts, midiPorts; + ExternalGraph extGraph; PatchbayGraph(CarlaEngine* const engine, const uint32_t inputs, const uint32_t outputs); ~PatchbayGraph(); - void setBufferSize(const int bufferSize); + void setBufferSize(const uint32_t bufferSize); void setSampleRate(const double sampleRate); void setOffline(const bool offline); @@ -147,12 +165,11 @@ struct PatchbayGraph { bool connect(const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept; bool disconnect(const uint connectionId) noexcept; void disconnectGroup(const uint groupId) noexcept; - void clearPorts() noexcept; - void clearConnections(); + void clearInternalConnections(); void refresh(const char* const deviceName); const char* const* getConnections(const bool external) const; - bool getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const; + bool getGroupAndPortIdFromFullName(const bool external, const char* const fullPortName, uint& groupId, uint& portId) const; void process(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const int frames); diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 54c967692..580e33090 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -86,7 +86,7 @@ public: void removePlugin(CarlaPlugin* const plugin); void removeAllPlugins(); - void setIgnorePatchbay(const bool ignore) noexcept; + void setUsingExternal(const bool usingExternal) noexcept; private: bool fIsRack; diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index a8fb416d6..e5c3a396c 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -817,6 +817,7 @@ public: if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) { pData->graph.create(0, 0); + patchbayRefresh(true); } else { @@ -1154,7 +1155,7 @@ public: if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) { fExternalPatchbay = external; - pData->graph.setIgnorePatchbay(external); + pData->graph.setUsingExternal(external); if (! external) return CarlaEngine::patchbayRefresh(false); diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index 0e4c4d43e..bdf000ef1 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -403,7 +403,7 @@ public: // Patchbay template - void refreshGraphPorts(Graph* const graph) + bool refreshGraphPorts(Graph& graph) { char strBuf[STR_MAX+1]; strBuf[STR_MAX] = '\0'; @@ -411,7 +411,7 @@ public: // --------------------------------------------------------------- // clear last ports - graph->clearPorts(); + graph.clearPorts(); // --------------------------------------------------------------- // fill in new ones @@ -422,9 +422,9 @@ public: std::snprintf(strBuf, STR_MAX, "capture_%i", i+1); PortNameToId portNameToId; - portNameToId.setData(RACK_GRAPH_GROUP_AUDIO_IN, i+1, strBuf, ""); + portNameToId.setData(kExternalGraphGroupAudioIn, i+1, strBuf, ""); - graph->audioPorts.ins.append(portNameToId); + graph.audioPorts.ins.append(portNameToId); } // Audio Out @@ -433,9 +433,9 @@ public: std::snprintf(strBuf, STR_MAX, "playback_%i", i+1); PortNameToId portNameToId; - portNameToId.setData(RACK_GRAPH_GROUP_AUDIO_OUT, i+1, strBuf, ""); + portNameToId.setData(kExternalGraphGroupAudioOut, i+1, strBuf, ""); - graph->audioPorts.outs.append(portNameToId); + graph.audioPorts.outs.append(portNameToId); } // MIDI In @@ -445,9 +445,9 @@ public: for (uint i=0, count = midiIn.getPortCount(); i < count; ++i) { PortNameToId portNameToId; - portNameToId.setData(RACK_GRAPH_GROUP_MIDI_IN, i+1, midiIn.getPortName(i).c_str(), ""); + portNameToId.setData(kExternalGraphGroupMidiIn, i+1, midiIn.getPortName(i).c_str(), ""); - graph->midiPorts.ins.append(portNameToId); + graph.midiPorts.ins.append(portNameToId); } } @@ -458,16 +458,16 @@ public: for (uint i=0, count = midiOut.getPortCount(); i < count; ++i) { PortNameToId portNameToId; - portNameToId.setData(RACK_GRAPH_GROUP_MIDI_OUT, i+1, midiOut.getPortName(i).c_str(), ""); + portNameToId.setData(kExternalGraphGroupMidiOut, i+1, midiOut.getPortName(i).c_str(), ""); - graph->midiPorts.outs.append(portNameToId); + graph.midiPorts.outs.append(portNameToId); } } // --------------------------------------------------------------- // now refresh - graph->refresh(fDeviceName.buffer()); + graph.refresh(fDeviceName.buffer()); // --------------------------------------------------------------- // add midi connections @@ -479,17 +479,17 @@ public: const MidiInPort& inPort(it.getValue(fallback)); CARLA_SAFE_ASSERT_CONTINUE(inPort.port != nullptr); - const uint portId(graph->midiPorts.getPortId(true, inPort.name)); - CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midiPorts.ins.count()); + const uint portId(graph.midiPorts.getPortId(true, inPort.name)); + CARLA_SAFE_ASSERT_CONTINUE(portId < graph.midiPorts.ins.count()); ConnectionToId connectionToId; - connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_MIDI_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN); + connectionToId.setData(++(graph.connections.lastId), kExternalGraphGroupMidiIn, portId, kExternalGraphGroupCarla, kExternalGraphCarlaPortMidiIn); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); - graph->connections.list.append(connectionToId); + graph.connections.list.append(connectionToId); } fMidiOutMutex.lock(); @@ -501,39 +501,40 @@ public: const MidiOutPort& outPort(it.getValue(fallback)); CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); - const uint portId(graph->midiPorts.getPortId(false, outPort.name)); - CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midiPorts.outs.count()); + const uint portId(graph.midiPorts.getPortId(false, outPort.name)); + CARLA_SAFE_ASSERT_CONTINUE(portId < graph.midiPorts.outs.count()); ConnectionToId connectionToId; - connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, RACK_GRAPH_GROUP_MIDI_OUT, portId); + connectionToId.setData(++(graph.connections.lastId), kExternalGraphGroupCarla, kExternalGraphCarlaPortMidiOut, kExternalGraphGroupMidiOut, portId); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); - graph->connections.list.append(connectionToId); + graph.connections.list.append(connectionToId); } fMidiOutMutex.unlock(); + + return true; } - bool patchbayRefresh(const bool /*external*/) override + bool patchbayRefresh(const bool external) override { CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) { - RackGraph* const graph(pData->graph.getRackGraph()); - CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); - - refreshGraphPorts(graph); + return refreshGraphPorts(pData->graph.getRackGraph()->extGraph); } else { - PatchbayGraph* const graph(pData->graph.getPatchbayGraph()); - CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); + pData->graph.setUsingExternal(external); + + if (! external) + return CarlaEngine::patchbayRefresh(false); - refreshGraphPorts(graph); + return refreshGraphPorts(pData->graph.getPatchbayGraph()->extGraph); } return true; @@ -740,7 +741,7 @@ protected: RackGraph* const graph(pData->graph.getRackGraph()); CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(graph->midiPorts.ins.count() > 0, false); + CARLA_SAFE_ASSERT_RETURN(graph->extGraph.midiPorts.ins.count() > 0, false); CarlaString newRtMidiPortName; newRtMidiPortName += getName(); @@ -795,7 +796,7 @@ protected: RackGraph* const graph(pData->graph.getRackGraph()); CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(graph->midiPorts.ins.count() > 0, false); + CARLA_SAFE_ASSERT_RETURN(graph->extGraph.midiPorts.ins.count() > 0, false); CarlaString newRtMidiPortName; newRtMidiPortName += getName(); @@ -850,7 +851,7 @@ protected: RackGraph* const graph(pData->graph.getRackGraph()); CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(graph->midiPorts.ins.count() > 0, false); + CARLA_SAFE_ASSERT_RETURN(graph->extGraph.midiPorts.ins.count() > 0, false); for (LinkedList::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) { @@ -880,7 +881,7 @@ protected: RackGraph* const graph(pData->graph.getRackGraph()); CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(graph->midiPorts.outs.count() > 0, false); + CARLA_SAFE_ASSERT_RETURN(graph->extGraph.midiPorts.outs.count() > 0, false); const CarlaMutexLocker cml(fMidiOutMutex); diff --git a/source/carla_host.py b/source/carla_host.py index 908b28c3a..caa6abd5a 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -612,7 +612,7 @@ class HostWindow(QMainWindow): self.ui.act_canvas_show_internal.blockSignals(True) self.ui.act_canvas_show_external.blockSignals(True) - if processMode == ENGINE_PROCESS_MODE_PATCHBAY and driverName == "JACK": + if processMode == ENGINE_PROCESS_MODE_PATCHBAY and not self.host.isPlugin: self.ui.act_canvas_show_internal.setChecked(True) self.ui.act_canvas_show_internal.setVisible(True) self.ui.act_canvas_show_external.setChecked(False)