From 98e47738743c28b45d9621e971b94a54fd0f7227 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 30 Oct 2012 08:51:58 +0000 Subject: [PATCH] Carla: Fix jack latency code I still don't understand how all of this is supposed to work... --- c++/carla-backend/carla_engine.cpp | 23 ++++----- c++/carla-backend/carla_engine.h | 10 ++-- c++/carla-backend/carla_engine_jack.cpp | 63 ++++++++++++++++--------- c++/carla-backend/dssi.cpp | 6 +-- c++/carla-backend/ladspa.cpp | 6 +-- c++/carla-backend/lv2.cpp | 6 +-- c++/carla-backend/vst.cpp | 6 +-- 7 files changed, 62 insertions(+), 58 deletions(-) diff --git a/c++/carla-backend/carla_engine.cpp b/c++/carla-backend/carla_engine.cpp index 170ebc2..23dacf7 100644 --- a/c++/carla-backend/carla_engine.cpp +++ b/c++/carla-backend/carla_engine.cpp @@ -810,7 +810,8 @@ CarlaEngineClient::CarlaEngineClient(const CarlaEngineClientNativeHandle& handle qDebug("CarlaEngineClient::CarlaEngineClient()"); CARLA_ASSERT(handle.type != CarlaEngineTypeNull); - m_active = false; + m_active = false; + m_latency = 0; } CarlaEngineClient::~CarlaEngineClient() @@ -895,8 +896,15 @@ bool CarlaEngineClient::isOk() const return true; } -void CarlaEngineClient::recomputeLatencies() +uint32_t CarlaEngineClient::getLatency() const +{ + return m_latency; +} + +void CarlaEngineClient::setLatency(const uint32_t samples) { + m_latency = samples; + #ifndef BUILD_BRIDGE if (carlaOptions.processMode != PROCESS_MODE_CONTINUOUS_RACK) #endif @@ -986,23 +994,12 @@ CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEnginePortNativeHandle& ha : CarlaEngineBasePort(handle, isInput) { qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); - latency = 0; } void CarlaEngineAudioPort::initBuffer(CarlaEngine* const /*engine*/) { } -uint32_t CarlaEngineAudioPort::getLatency() const -{ - return latency; -} - -void CarlaEngineAudioPort::setLatency(const uint32_t samples) -{ - latency = samples; -} - #ifdef CARLA_ENGINE_JACK float* CarlaEngineAudioPort::getJackAudioBuffer(uint32_t nframes) { diff --git a/c++/carla-backend/carla_engine.h b/c++/carla-backend/carla_engine.h index 0e73853..4249848 100644 --- a/c++/carla-backend/carla_engine.h +++ b/c++/carla-backend/carla_engine.h @@ -426,12 +426,14 @@ public: bool isActive() const; bool isOk() const; - void recomputeLatencies(); + uint32_t getLatency() const; + void setLatency(const uint32_t samples); const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput); private: bool m_active; + uint32_t m_latency; const CarlaEngineClientNativeHandle handle; }; @@ -465,15 +467,9 @@ public: void initBuffer(CarlaEngine* const engine); - uint32_t getLatency() const; - void setLatency(const uint32_t samples); - #ifdef CARLA_ENGINE_JACK float* getJackAudioBuffer(uint32_t nframes); #endif - -private: - uint32_t latency; }; // control diff --git a/c++/carla-backend/carla_engine_jack.cpp b/c++/carla-backend/carla_engine_jack.cpp index 52534c7..795803b 100644 --- a/c++/carla-backend/carla_engine_jack.cpp +++ b/c++/carla-backend/carla_engine_jack.cpp @@ -475,7 +475,7 @@ protected: #endif } - void handleLatencyCallback() + void handleLatencyCallback(jack_latency_callback_mode_t mode) { #ifndef BUILD_BRIDGE if (carlaOptions.processMode != PROCESS_MODE_SINGLE_CLIENT) @@ -485,7 +485,9 @@ protected: for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) { CarlaPlugin* const plugin = getPluginUnchecked(i); - latencyPlugin(plugin); + + if (plugin && plugin->enabled()) + latencyPlugin(plugin, mode); } } @@ -494,7 +496,9 @@ protected: for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) { CarlaPlugin* const plugin = getPluginUnchecked(i); - plugin->x_client = nullptr; + + if (plugin) + plugin->x_client = nullptr; } client = nullptr; @@ -569,20 +573,41 @@ private: zeroF(p->aOut.ports[i]->getJackAudioBuffer(nframes), nframes); } - static void latencyPlugin(CarlaPlugin* const p) + static void latencyPlugin(CarlaPlugin* const p, jack_latency_callback_mode_t mode) { - for (uint32_t i=0; i < p->aIn.count; i++) - { - const CarlaEngineAudioPort* const port = p->aIn.ports[i]; - jack_port_t* const jackPort = port->getHandle().jackPort; - jack_latency_range_t range; - - jackbridge_port_get_latency_range(jackPort, JackPlaybackLatency, &range); + jack_latency_range_t range; + uint32_t pluginLatency = p->x_client->getLatency(); - range.min += port->getLatency(); - range.max += port->getLatency(); + if (pluginLatency == 0) + return; - jackbridge_port_set_latency_range(jackPort, JackPlaybackLatency, &range); + if (mode == JackCaptureLatency) + { + for (uint32_t i=0; i < p->aIn.count; i++) + { + uint aOutI = (i >= p->aOut.count) ? p->aOut.count : i; + jack_port_t* const portIn = p->aIn.ports[i]->getHandle().jackPort; + jack_port_t* const portOut = p->aOut.ports[aOutI]->getHandle().jackPort; + + jackbridge_port_get_latency_range(portIn, mode, &range); + range.min += pluginLatency; + range.max += pluginLatency; + jackbridge_port_set_latency_range(portOut, mode, &range); + } + } + else + { + for (uint32_t i=0; i < p->aOut.count; i++) + { + uint aInI = (i >= p->aIn.count) ? p->aIn.count : i; + jack_port_t* const portIn = p->aIn.ports[aInI]->getHandle().jackPort; + jack_port_t* const portOut = p->aOut.ports[i]->getHandle().jackPort; + + jackbridge_port_get_latency_range(portOut, mode, &range); + range.min += pluginLatency; + range.max += pluginLatency; + jackbridge_port_set_latency_range(portIn, mode, &range); + } } } @@ -637,22 +662,16 @@ private: static void carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg) { - if (mode != JackPlaybackLatency) - return; - CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg; - _this_->handleLatencyCallback(); + _this_->handleLatencyCallback(mode); } static void carla_jack_latency_callback_plugin(jack_latency_callback_mode_t mode, void* arg) { - if (mode != JackPlaybackLatency) - return; - CarlaPlugin* const plugin = (CarlaPlugin*)arg; if (plugin && plugin->enabled()) - latencyPlugin(plugin); + latencyPlugin(plugin, mode); } static void carla_jack_shutdown_callback(void* arg) diff --git a/c++/carla-backend/dssi.cpp b/c++/carla-backend/dssi.cpp index 36ac630..dcd27ab 100644 --- a/c++/carla-backend/dssi.cpp +++ b/c++/carla-backend/dssi.cpp @@ -697,6 +697,7 @@ public: m_hints |= PLUGIN_CAN_FORCE_STEREO; // check latency + if (m_hints & PLUGIN_CAN_DRYWET) { bool hasLatency = false; m_latency = 0; @@ -739,10 +740,7 @@ public: if (hasLatency) { - for (uint32_t i=0; i < aIn.count; i++) - aIn.ports[i]->setLatency(m_latency); - - x_client->recomputeLatencies(); + x_client->setLatency(m_latency); recreateLatencyBuffers(); } } diff --git a/c++/carla-backend/ladspa.cpp b/c++/carla-backend/ladspa.cpp index 8f33dfc..2325918 100644 --- a/c++/carla-backend/ladspa.cpp +++ b/c++/carla-backend/ladspa.cpp @@ -666,6 +666,7 @@ public: m_hints |= PLUGIN_CAN_FORCE_STEREO; // check latency + if (m_hints & PLUGIN_CAN_DRYWET) { bool hasLatency = false; m_latency = 0; @@ -708,10 +709,7 @@ public: if (hasLatency) { - for (uint32_t i=0; i < aIn.count; i++) - aIn.ports[i]->setLatency(m_latency); - - x_client->recomputeLatencies(); + x_client->setLatency(m_latency); recreateLatencyBuffers(); } } diff --git a/c++/carla-backend/lv2.cpp b/c++/carla-backend/lv2.cpp index 230773b..2a85db5 100644 --- a/c++/carla-backend/lv2.cpp +++ b/c++/carla-backend/lv2.cpp @@ -1777,6 +1777,7 @@ public: } // check latency + if (m_hints & PLUGIN_CAN_DRYWET) { bool hasLatency = false; m_latency = 0; @@ -1810,10 +1811,7 @@ public: if (hasLatency) { - for (uint32_t i=0; i < aIn.count; i++) - aIn.ports[i]->setLatency(m_latency); - - x_client->recomputeLatencies(); + x_client->setLatency(m_latency); recreateLatencyBuffers(); } } diff --git a/c++/carla-backend/vst.cpp b/c++/carla-backend/vst.cpp index cc6f56b..8f09831 100644 --- a/c++/carla-backend/vst.cpp +++ b/c++/carla-backend/vst.cpp @@ -730,6 +730,7 @@ public: m_hints |= PLUGIN_CAN_FORCE_STEREO; // check latency + if (m_hints & PLUGIN_CAN_DRYWET) { #ifdef VESTIGE_HEADER char* const empty3Ptr = &effect->empty3[0]; @@ -739,10 +740,7 @@ public: m_latency = effect->initialDelay; #endif - for (uint32_t i=0; i < aIn.count; i++) - aIn.ports[i]->setLatency(m_latency); - - x_client->recomputeLatencies(); + x_client->setLatency(m_latency); recreateLatencyBuffers(); }