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()"); | qDebug("CarlaEngineClient::CarlaEngineClient()"); | ||||
| CARLA_ASSERT(handle.type != CarlaEngineTypeNull); | CARLA_ASSERT(handle.type != CarlaEngineTypeNull); | ||||
| m_active = false; | |||||
| m_active = false; | |||||
| m_latency = 0; | |||||
| } | } | ||||
| CarlaEngineClient::~CarlaEngineClient() | CarlaEngineClient::~CarlaEngineClient() | ||||
| @@ -895,8 +896,15 @@ bool CarlaEngineClient::isOk() const | |||||
| return true; | 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 | #ifndef BUILD_BRIDGE | ||||
| if (carlaOptions.processMode != PROCESS_MODE_CONTINUOUS_RACK) | if (carlaOptions.processMode != PROCESS_MODE_CONTINUOUS_RACK) | ||||
| #endif | #endif | ||||
| @@ -986,23 +994,12 @@ CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEnginePortNativeHandle& ha | |||||
| : CarlaEngineBasePort(handle, isInput) | : CarlaEngineBasePort(handle, isInput) | ||||
| { | { | ||||
| qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); | qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); | ||||
| latency = 0; | |||||
| } | } | ||||
| void CarlaEngineAudioPort::initBuffer(CarlaEngine* const /*engine*/) | 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 | #ifdef CARLA_ENGINE_JACK | ||||
| float* CarlaEngineAudioPort::getJackAudioBuffer(uint32_t nframes) | float* CarlaEngineAudioPort::getJackAudioBuffer(uint32_t nframes) | ||||
| { | { | ||||
| @@ -426,12 +426,14 @@ public: | |||||
| bool isActive() const; | bool isActive() const; | ||||
| bool isOk() 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); | const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput); | ||||
| private: | private: | ||||
| bool m_active; | bool m_active; | ||||
| uint32_t m_latency; | |||||
| const CarlaEngineClientNativeHandle handle; | const CarlaEngineClientNativeHandle handle; | ||||
| }; | }; | ||||
| @@ -465,15 +467,9 @@ public: | |||||
| void initBuffer(CarlaEngine* const engine); | void initBuffer(CarlaEngine* const engine); | ||||
| uint32_t getLatency() const; | |||||
| void setLatency(const uint32_t samples); | |||||
| #ifdef CARLA_ENGINE_JACK | #ifdef CARLA_ENGINE_JACK | ||||
| float* getJackAudioBuffer(uint32_t nframes); | float* getJackAudioBuffer(uint32_t nframes); | ||||
| #endif | #endif | ||||
| private: | |||||
| uint32_t latency; | |||||
| }; | }; | ||||
| // control | // control | ||||
| @@ -475,7 +475,7 @@ protected: | |||||
| #endif | #endif | ||||
| } | } | ||||
| void handleLatencyCallback() | |||||
| void handleLatencyCallback(jack_latency_callback_mode_t mode) | |||||
| { | { | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| if (carlaOptions.processMode != PROCESS_MODE_SINGLE_CLIENT) | if (carlaOptions.processMode != PROCESS_MODE_SINGLE_CLIENT) | ||||
| @@ -485,7 +485,9 @@ protected: | |||||
| for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | ||||
| { | { | ||||
| CarlaPlugin* const plugin = getPluginUnchecked(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++) | for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | ||||
| { | { | ||||
| CarlaPlugin* const plugin = getPluginUnchecked(i); | CarlaPlugin* const plugin = getPluginUnchecked(i); | ||||
| plugin->x_client = nullptr; | |||||
| if (plugin) | |||||
| plugin->x_client = nullptr; | |||||
| } | } | ||||
| client = nullptr; | client = nullptr; | ||||
| @@ -569,20 +573,41 @@ private: | |||||
| zeroF(p->aOut.ports[i]->getJackAudioBuffer(nframes), nframes); | 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) | static void carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg) | ||||
| { | { | ||||
| if (mode != JackPlaybackLatency) | |||||
| return; | |||||
| CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg; | 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) | static void carla_jack_latency_callback_plugin(jack_latency_callback_mode_t mode, void* arg) | ||||
| { | { | ||||
| if (mode != JackPlaybackLatency) | |||||
| return; | |||||
| CarlaPlugin* const plugin = (CarlaPlugin*)arg; | CarlaPlugin* const plugin = (CarlaPlugin*)arg; | ||||
| if (plugin && plugin->enabled()) | if (plugin && plugin->enabled()) | ||||
| latencyPlugin(plugin); | |||||
| latencyPlugin(plugin, mode); | |||||
| } | } | ||||
| static void carla_jack_shutdown_callback(void* arg) | static void carla_jack_shutdown_callback(void* arg) | ||||
| @@ -697,6 +697,7 @@ public: | |||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | m_hints |= PLUGIN_CAN_FORCE_STEREO; | ||||
| // check latency | // check latency | ||||
| if (m_hints & PLUGIN_CAN_DRYWET) | |||||
| { | { | ||||
| bool hasLatency = false; | bool hasLatency = false; | ||||
| m_latency = 0; | m_latency = 0; | ||||
| @@ -739,10 +740,7 @@ public: | |||||
| if (hasLatency) | 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(); | recreateLatencyBuffers(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -666,6 +666,7 @@ public: | |||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | m_hints |= PLUGIN_CAN_FORCE_STEREO; | ||||
| // check latency | // check latency | ||||
| if (m_hints & PLUGIN_CAN_DRYWET) | |||||
| { | { | ||||
| bool hasLatency = false; | bool hasLatency = false; | ||||
| m_latency = 0; | m_latency = 0; | ||||
| @@ -708,10 +709,7 @@ public: | |||||
| if (hasLatency) | 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(); | recreateLatencyBuffers(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1777,6 +1777,7 @@ public: | |||||
| } | } | ||||
| // check latency | // check latency | ||||
| if (m_hints & PLUGIN_CAN_DRYWET) | |||||
| { | { | ||||
| bool hasLatency = false; | bool hasLatency = false; | ||||
| m_latency = 0; | m_latency = 0; | ||||
| @@ -1810,10 +1811,7 @@ public: | |||||
| if (hasLatency) | 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(); | recreateLatencyBuffers(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -730,6 +730,7 @@ public: | |||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | m_hints |= PLUGIN_CAN_FORCE_STEREO; | ||||
| // check latency | // check latency | ||||
| if (m_hints & PLUGIN_CAN_DRYWET) | |||||
| { | { | ||||
| #ifdef VESTIGE_HEADER | #ifdef VESTIGE_HEADER | ||||
| char* const empty3Ptr = &effect->empty3[0]; | char* const empty3Ptr = &effect->empty3[0]; | ||||
| @@ -739,10 +740,7 @@ public: | |||||
| m_latency = effect->initialDelay; | m_latency = effect->initialDelay; | ||||
| #endif | #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(); | recreateLatencyBuffers(); | ||||
| } | } | ||||