From 1d9ace6c2319e0865e27217f3a2629b187270fa2 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 26 Aug 2014 03:17:22 +0100 Subject: [PATCH] Allow to change between internal and external canvas (plugin vs jack) --- resources/ui/carla_host.ui | 19 +++++++ source/backend/CarlaEngine.hpp | 2 +- source/backend/CarlaHost.h | 4 +- source/backend/CarlaStandalone.cpp | 6 +-- source/backend/engine/CarlaEngineGraph.cpp | 5 +- source/backend/engine/CarlaEngineJack.cpp | 52 +++++++++++++------ source/backend/engine/CarlaEngineJuce.cpp | 7 +-- source/backend/engine/CarlaEngineNative.cpp | 4 +- source/backend/engine/CarlaEngineRtAudio.cpp | 11 ++-- source/carla | 2 + source/carla_backend.py | 8 +-- source/carla_host.py | 7 +++ source/carla_patchbay.py | 28 +++++++++- source/carla_shared.py | 3 ++ .../native-plugins/resources/carla-plugin | 3 +- 15 files changed, 124 insertions(+), 37 deletions(-) diff --git a/resources/ui/carla_host.ui b/resources/ui/carla_host.ui index c2b046fa5..255a90be7 100644 --- a/resources/ui/carla_host.ui +++ b/resources/ui/carla_host.ui @@ -243,6 +243,9 @@ + + + @@ -652,6 +655,22 @@ About &JUCE + + + true + + + Show Internal + + + + + true + + + Show External + + diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 9f063da13..e5760ec53 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -936,7 +936,7 @@ public: /*! * Force the engine to resend all patchbay clients, ports and connections again. */ - virtual bool patchbayRefresh(); + virtual bool patchbayRefresh(const bool external); #endif // ------------------------------------------------------------------- diff --git a/source/backend/CarlaHost.h b/source/backend/CarlaHost.h index 53dbc3790..65d17dde4 100644 --- a/source/backend/CarlaHost.h +++ b/source/backend/CarlaHost.h @@ -514,8 +514,10 @@ CARLA_EXPORT bool carla_patchbay_disconnect(uint connectionId); /*! * Force the engine to resend all patchbay clients, ports and connections again. + * @param external Wherever to show external/hardware ports instead of internal ones. + * Only valid in patchbay engine mode, other modes will ignore this. */ -CARLA_EXPORT bool carla_patchbay_refresh(); +CARLA_EXPORT bool carla_patchbay_refresh(bool external); /*! * Start playback of the engine transport. diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index d9b5a9284..f577716e5 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -1102,12 +1102,12 @@ bool carla_patchbay_disconnect(uint connectionId) return false; } -bool carla_patchbay_refresh() +bool carla_patchbay_refresh(bool external) { - carla_debug("carla_patchbay_refresh()"); + carla_debug("carla_patchbay_refresh(%s)", bool2str(external)); if (gStandalone.engine != nullptr) - return gStandalone.engine->patchbayRefresh(); + return gStandalone.engine->patchbayRefresh(external); carla_stderr2("Engine is not running"); gStandalone.lastError = "Engine is not running"; diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index 8dd917173..d43e8312e 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -1752,8 +1752,11 @@ bool CarlaEngine::patchbayDisconnect(const uint connectionId) return false; } -bool CarlaEngine::patchbayRefresh() +bool CarlaEngine::patchbayRefresh(const bool external) { + // subclasses should handle this + CARLA_SAFE_ASSERT_RETURN(! external, false); + if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) { // This is implemented in engine subclasses for MIDI support diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 5167948cc..53070e4b1 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -636,6 +636,7 @@ public: fClient(nullptr), fTransportPos(), fTransportState(JackTransportStopped), + fExternalPatchbay(true), fFreewheel(false), #ifdef BUILD_BRIDGE fIsRunning(false), @@ -712,8 +713,9 @@ public: CARLA_SAFE_ASSERT_RETURN(jackbridge_is_ok(), false); carla_debug("CarlaEngineJack::init(\"%s\")", clientName); - fFreewheel = false; - fTransportState = JackTransportStopped; + fFreewheel = false; + fTransportState = JackTransportStopped; + fExternalPatchbay = true; carla_zeroStruct(fTransportPos); @@ -761,13 +763,12 @@ public: const char* const jackClientName(jackbridge_get_client_name(fClient)); if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY) - { initJackPatchbay(jackClientName); - jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this); - jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this); - jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this); - jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this); - } + + jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this); + jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this); + jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this); + jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this); if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) @@ -786,7 +787,7 @@ public: else { pData->graph.create(false, pData->sampleRate, pData->bufferSize, 2, 2); - CarlaEngine::patchbayRefresh(); + patchbayRefresh(false); } } @@ -1051,7 +1052,7 @@ public: { CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false); - if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) + if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fExternalPatchbay) return CarlaEngine::patchbayConnect(groupA, portA, groupB, portB); const char* const fullPortNameA = fUsedPorts.getFullPortName(groupA, portA); @@ -1075,7 +1076,7 @@ public: { CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false); - if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) + if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fExternalPatchbay) return CarlaEngine::patchbayDisconnect(connectionId); for (LinkedList::Itenerator it = fUsedConnections.list.begin(); it.valid(); it.next()) @@ -1104,12 +1105,17 @@ public: return false; } - bool patchbayRefresh() override + bool patchbayRefresh(const bool external) override { CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false); if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) - return CarlaEngine::patchbayRefresh(); + { + fExternalPatchbay = external; + + if (! external) + return CarlaEngine::patchbayRefresh(false); + } fUsedGroups.clear(); fUsedPorts.clear(); @@ -1185,7 +1191,7 @@ public: CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr); - if (const char** connections = jackbridge_port_get_all_connections(fClient, jackPort)) + if (const char** const connections = jackbridge_port_get_all_connections(fClient, jackPort)) { for (int j=0; connections[j] != nullptr; ++j) { @@ -1456,6 +1462,9 @@ protected: { CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); + // ignore this if on internal patchbay mode + if (! fExternalPatchbay) return; + // do nothing on client registration, wait for first port if (reg) return; @@ -1473,6 +1482,9 @@ protected: void handleJackPortRegistrationCallback(const jack_port_id_t port, const bool reg) { + // ignore this if on internal patchbay mode + if (! fExternalPatchbay) return; + const jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port)); CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr,); @@ -1522,6 +1534,9 @@ protected: void handleJackPortConnectCallback(const jack_port_id_t a, const jack_port_id_t b, const bool connect) { + // ignore this if on internal patchbay mode + if (! fExternalPatchbay) return; + const jack_port_t* const jackPortA(jackbridge_port_by_id(fClient, a)); CARLA_SAFE_ASSERT_RETURN(jackPortA != nullptr,); @@ -1574,6 +1589,9 @@ protected: CARLA_SAFE_ASSERT_RETURN(oldName != nullptr && oldName[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0',); + // ignore this if on internal patchbay mode + if (! fExternalPatchbay) return; + for (LinkedList::Itenerator it = fUsedGroups.list.begin(); it.valid(); it.next()) { GroupNameToId& groupNameToId(it.getValue()); @@ -1592,6 +1610,9 @@ protected: CARLA_SAFE_ASSERT_RETURN(oldFullName != nullptr && oldFullName[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(newFullName != nullptr && newFullName[0] != '\0',); + // ignore this if on internal patchbay mode + if (! fExternalPatchbay) return; + const jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port)); CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr,); @@ -1670,6 +1691,7 @@ private: jack_client_t* fClient; jack_position_t fTransportPos; jack_transport_state_t fTransportState; + bool fExternalPatchbay; bool fFreewheel; // ------------------------------------------------------------------- @@ -1749,7 +1771,7 @@ private: void initJackPatchbay(const char* const ourName) { - CARLA_SAFE_ASSERT_RETURN(pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY,); + CARLA_SAFE_ASSERT_RETURN(pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY || fExternalPatchbay,); CARLA_SAFE_ASSERT_RETURN(ourName != nullptr && ourName[0] != '\0',); StringArray parsedGroups; diff --git a/source/backend/engine/CarlaEngineJuce.cpp b/source/backend/engine/CarlaEngineJuce.cpp index 4115c4ca2..0801539c3 100644 --- a/source/backend/engine/CarlaEngineJuce.cpp +++ b/source/backend/engine/CarlaEngineJuce.cpp @@ -173,8 +173,7 @@ public: fDevice->start(this); CarlaEngine::init(clientName); - - patchbayRefresh(); + patchbayRefresh(false); return true; } @@ -250,7 +249,7 @@ public: // ------------------------------------------------------------------- // Patchbay - bool patchbayRefresh() override + bool patchbayRefresh(const bool /*external*/) override { CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); @@ -471,6 +470,8 @@ public: { PatchbayGraph* const graph(pData->graph.getPatchbayGraph()); CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); + + graph->refreshConnections(this); } // ------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 303cb6d13..0ab0d1cb8 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -156,7 +156,7 @@ protected: else if (std::strcmp(msg, "patchbay_refresh") == 0) { try { - ok = fEngine->patchbayRefresh(); + ok = fEngine->patchbayRefresh(false); } CARLA_SAFE_EXCEPTION("patchbayRefresh"); } else if (std::strcmp(msg, "transport_play") == 0) @@ -1236,7 +1236,7 @@ protected: } if (fIsPatchbay) - patchbayRefresh(); + patchbayRefresh(false); } else { diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index e11429637..5bc81c72e 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -287,8 +287,7 @@ public: } CarlaEngine::init(clientName); - - patchbayRefresh(); + patchbayRefresh(false); return true; } @@ -380,7 +379,7 @@ public: // ------------------------------------------------------------------- // Patchbay - bool patchbayRefresh() override + bool patchbayRefresh(const bool /*external*/) override { CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); @@ -594,8 +593,10 @@ public: void patchbayRefreshPatchbay() noexcept { - // handled internally? - CarlaEngine::patchbayRefresh(); + PatchbayGraph* const graph(pData->graph.getPatchbayGraph()); + CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); + + graph->refreshConnections(this); } // ------------------------------------------------------------------- diff --git a/source/carla b/source/carla index d7f9078b0..01d9de424 100755 --- a/source/carla +++ b/source/carla @@ -68,6 +68,8 @@ class CarlaMultiW(QTabWidget): parent.ui.act_plugins_center.triggered.connect(self.fRack.slot_pluginsCenter) parent.ui.act_plugins_panic.triggered.connect(self.fRack.slot_pluginsDisable) + parent.ui.act_canvas_show_internal.triggered.connect(self.fPatchbay.slot_canvasShowInternal) + parent.ui.act_canvas_show_external.triggered.connect(self.fPatchbay.slot_canvasShowExternal) parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later parent.ui.act_canvas_arrange.triggered.connect(self.fPatchbay.slot_canvasArrange) parent.ui.act_canvas_refresh.triggered.connect(self.fPatchbay.slot_canvasRefresh) diff --git a/source/carla_backend.py b/source/carla_backend.py index 9a689ca6f..3b17d027e 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -1344,8 +1344,10 @@ class Host(object): return bool(self.lib.carla_patchbay_disconnect(connectionId)) # Force the engine to resend all patchbay clients, ports and connections again. - def patchbay_refresh(self): - return bool(self.lib.carla_patchbay_refresh()) + # @param external Wherever to show external/hardware ports instead of internal ones. + # Only valid in patchbay engine mode, other modes will ignore this. + def patchbay_refresh(self, external): + return bool(self.lib.carla_patchbay_refresh(external)) # Start playback of the engine transport. def transport_play(self): @@ -1809,7 +1811,7 @@ class Host(object): self.lib.carla_patchbay_disconnect.argtypes = [c_uint] self.lib.carla_patchbay_disconnect.restype = c_bool - self.lib.carla_patchbay_refresh.argtypes = None + self.lib.carla_patchbay_refresh.argtypes = [c_bool] self.lib.carla_patchbay_refresh.restype = c_bool self.lib.carla_transport_play.argtypes = None diff --git a/source/carla_host.py b/source/carla_host.py index 5e3041b0c..de877eacd 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -251,6 +251,13 @@ class HostWindow(QMainWindow): self.ui.act_engine_stop.setEnabled(False) self.ui.act_plugin_remove_all.setEnabled(False) + if gCarla.externalPatchbay: + self.ui.act_canvas_show_internal.setChecked(False) + self.ui.act_canvas_show_external.setChecked(True) + else: + self.ui.act_canvas_show_internal.setChecked(True) + self.ui.act_canvas_show_external.setChecked(False) + self.ui.menu_PluginMacros.setEnabled(False) self.ui.menu_Canvas.setEnabled(False) diff --git a/source/carla_patchbay.py b/source/carla_patchbay.py index d2cb52778..d839476c2 100644 --- a/source/carla_patchbay.py +++ b/source/carla_patchbay.py @@ -207,6 +207,8 @@ class CarlaPatchbayW(QFrame): parent.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter) parent.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable) + parent.ui.act_canvas_show_internal.triggered.connect(self.slot_canvasShowInternal) + parent.ui.act_canvas_show_external.triggered.connect(self.slot_canvasShowExternal) parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later parent.ui.act_canvas_arrange.triggered.connect(self.slot_canvasArrange) parent.ui.act_canvas_refresh.triggered.connect(self.slot_canvasRefresh) @@ -655,7 +657,7 @@ class CarlaPatchbayW(QFrame): self.slot_miniCanvasCheckAll() if gCarla.host.is_engine_running(): - gCarla.host.patchbay_refresh() + gCarla.host.patchbay_refresh(gCarla.externalPatchbay) # ----------------------------------------------------------------- @@ -948,12 +950,34 @@ class CarlaPatchbayW(QFrame): def slot_canvasArrange(self): patchcanvas.arrange() + @pyqtSlot() + def slot_canvasShowInternal(self): + gCarla.externalPatchbay = False + self.fParent.ui.act_canvas_show_internal.blockSignals(True) + self.fParent.ui.act_canvas_show_external.blockSignals(True) + self.fParent.ui.act_canvas_show_internal.setChecked(True) + self.fParent.ui.act_canvas_show_external.setChecked(False) + self.fParent.ui.act_canvas_show_internal.blockSignals(False) + self.fParent.ui.act_canvas_show_external.blockSignals(False) + self.slot_canvasRefresh() + + @pyqtSlot() + def slot_canvasShowExternal(self): + gCarla.externalPatchbay = True + self.fParent.ui.act_canvas_show_internal.blockSignals(True) + self.fParent.ui.act_canvas_show_external.blockSignals(True) + self.fParent.ui.act_canvas_show_internal.setChecked(False) + self.fParent.ui.act_canvas_show_external.setChecked(True) + self.fParent.ui.act_canvas_show_internal.blockSignals(False) + self.fParent.ui.act_canvas_show_external.blockSignals(False) + self.slot_canvasRefresh() + @pyqtSlot() def slot_canvasRefresh(self): patchcanvas.clear() if gCarla.host is not None and gCarla.host.is_engine_running(): - gCarla.host.patchbay_refresh() + gCarla.host.patchbay_refresh(gCarla.externalPatchbay) for pitem in self.fPluginList: if pitem is None: diff --git a/source/carla_shared.py b/source/carla_shared.py index 3148a15b4..d8107f81c 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -246,6 +246,8 @@ class CarlaObject(object): 'transportMode', # current max parameters 'maxParameters', + # wherever to use external patchbay mode + 'externalPatchbay', # wherever to use custom skins 'useCustomSkins', # binary dir @@ -276,6 +278,7 @@ gCarla.processMode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else EN gCarla.processModeForced = False gCarla.transportMode = ENGINE_TRANSPORT_MODE_JACK if LINUX else ENGINE_TRANSPORT_MODE_INTERNAL gCarla.maxParameters = MAX_DEFAULT_PARAMETERS +gCarla.externalPatchbay = False gCarla.useCustomSkins = True gCarla.pathBinaries = "" gCarla.pathResources = "" diff --git a/source/modules/native-plugins/resources/carla-plugin b/source/modules/native-plugins/resources/carla-plugin index 255dc63c0..9ac202807 100755 --- a/source/modules/native-plugins/resources/carla-plugin +++ b/source/modules/native-plugins/resources/carla-plugin @@ -275,7 +275,8 @@ class PluginHost(object): gCarla.gui.send(["patchbay_disconnect", connectionId]) return True - def patchbay_refresh(self): + def patchbay_refresh(self, external): + # don't send external param, never used in plugins gCarla.gui.send(["patchbay_refresh"]) return True