I still don't understand how all of this is supposed to work...tags/v0.9.0
| @@ -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) | |||
| { | |||
| @@ -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 | |||
| @@ -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) | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||