This adds the need of an internal buffer in the plugins to properly handle dry/wet on those with latencytags/v0.9.0
| @@ -886,6 +886,19 @@ bool CarlaEngineClient::isOk() const | |||
| return true; | |||
| } | |||
| void CarlaEngineClient::recomputeLatencies() | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.processMode != PROCESS_MODE_CONTINUOUS_RACK) | |||
| #endif | |||
| { | |||
| #ifdef CARLA_ENGINE_JACK | |||
| if (handle.type == CarlaEngineTypeJack) | |||
| jackbridge_recompute_total_latencies(handle.jackClient); | |||
| #endif | |||
| } | |||
| } | |||
| const CarlaEngineBasePort* CarlaEngineClient::addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput) | |||
| { | |||
| qDebug("CarlaEngineClient::addPort(%i, \"%s\", %s)", portType, name, bool2str(isInput)); | |||
| @@ -964,12 +977,23 @@ 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,6 +426,8 @@ public: | |||
| bool isActive() const; | |||
| bool isOk() const; | |||
| void recomputeLatencies(); | |||
| const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput); | |||
| private: | |||
| @@ -444,6 +446,11 @@ public: | |||
| virtual void initBuffer(CarlaEngine* const engine) = 0; | |||
| const CarlaEnginePortNativeHandle& getHandle() const | |||
| { | |||
| return handle; | |||
| } | |||
| protected: | |||
| void* buffer; | |||
| const bool isInput; | |||
| @@ -458,9 +465,15 @@ 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 | |||
| @@ -79,6 +79,7 @@ public: | |||
| jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this); | |||
| jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this); | |||
| jackbridge_set_process_callback(client, carla_jack_process_callback, this); | |||
| jackbridge_set_latency_callback(client, carla_jack_latency_callback, this); | |||
| jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this); | |||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| @@ -186,6 +187,7 @@ public: | |||
| jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this); | |||
| jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this); | |||
| jackbridge_set_process_callback(handle.jackClient, carla_jack_process_callback, this); | |||
| jackbridge_set_latency_callback(handle.jackClient, carla_jack_latency_callback, this); | |||
| jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this); | |||
| #else | |||
| if (carlaOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) | |||
| @@ -196,6 +198,7 @@ public: | |||
| { | |||
| handle.jackClient = jackbridge_client_open(plugin->name(), JackNullOption, nullptr); | |||
| jackbridge_set_process_callback(handle.jackClient, carla_jack_process_callback_plugin, plugin); | |||
| jackbridge_set_latency_callback(handle.jackClient, carla_jack_latency_callback_plugin, plugin); | |||
| } | |||
| #endif | |||
| @@ -457,6 +460,20 @@ protected: | |||
| #endif | |||
| } | |||
| void handleLatencyCallback() | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.processMode != PROCESS_MODE_SINGLE_CLIENT) | |||
| return; | |||
| #endif | |||
| for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | |||
| { | |||
| CarlaPlugin* const plugin = getPluginUnchecked(i); | |||
| latencyPlugin(plugin); | |||
| } | |||
| } | |||
| void handleShutdownCallback() | |||
| { | |||
| for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | |||
| @@ -528,6 +545,23 @@ private: | |||
| p->process(inBuffer, outBuffer, nframes); | |||
| } | |||
| static void latencyPlugin(CarlaPlugin* const p) | |||
| { | |||
| 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); | |||
| range.min += port->getLatency(); | |||
| range.max += port->getLatency(); | |||
| jackbridge_port_set_latency_range(jackPort, JackPlaybackLatency, &range); | |||
| } | |||
| } | |||
| static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg) | |||
| { | |||
| CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg; | |||
| @@ -570,6 +604,26 @@ private: | |||
| return 0; | |||
| } | |||
| 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(); | |||
| } | |||
| 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); | |||
| } | |||
| static void carla_jack_shutdown_callback(void* arg) | |||
| { | |||
| CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg; | |||
| @@ -737,7 +737,13 @@ public: | |||
| } | |||
| } | |||
| // TODO - adjust latency now | |||
| if (hasLatency) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| } | |||
| reloadPrograms(true); | |||
| @@ -706,7 +706,13 @@ public: | |||
| } | |||
| } | |||
| // TODO - adjust latency now | |||
| if (hasLatency) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| } | |||
| x_client->activate(); | |||
| @@ -1769,7 +1769,13 @@ public: | |||
| } | |||
| } | |||
| // TODO - adjust latency now | |||
| if (hasLatency) | |||
| { | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| } | |||
| reloadPrograms(true); | |||
| @@ -731,9 +731,18 @@ public: | |||
| // check latency | |||
| { | |||
| #ifdef VESTIGE_HEADER | |||
| char* const empty3Ptr = &effect->empty3[0]; | |||
| int32_t* initialDelayPtr = (int32_t*)empty3Ptr; | |||
| uint32_t latency = *initialDelayPtr; | |||
| #else | |||
| uint32_t latency = effect->initialDelay; | |||
| #endif | |||
| for (uint32_t i=0; i < aIn.count; i++) | |||
| aIn.ports[i]->setLatency(latency); | |||
| // TODO - adjust latency now | |||
| x_client->recomputeLatencies(); | |||
| } | |||
| reloadPrograms(true); | |||
| @@ -62,6 +62,29 @@ int jackbridge_port_name_size() | |||
| #endif | |||
| } | |||
| int jackbridge_recompute_total_latencies(jack_client_t* client) | |||
| { | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| return jack_recompute_total_latencies(client); | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| void jackbridge_port_get_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range) | |||
| { | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| jack_port_get_latency_range(port, mode, range); | |||
| #endif | |||
| } | |||
| void jackbridge_port_set_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range) | |||
| { | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| jack_port_set_latency_range(port, mode, range); | |||
| #endif | |||
| } | |||
| int jackbridge_activate(jack_client_t* client) | |||
| { | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| @@ -96,6 +119,15 @@ void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown | |||
| #endif | |||
| } | |||
| void jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg) | |||
| { | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| return jack_set_latency_callback(client, latency_callback, arg); | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| int jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg) | |||
| { | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| @@ -39,9 +39,13 @@ CARLA_EXPORT int jackbridge_client_close(jack_client_t* client); | |||
| CARLA_EXPORT int jackbridge_client_name_size(); | |||
| CARLA_EXPORT char* jackbridge_get_client_name(jack_client_t* client); | |||
| CARLA_EXPORT int jackbridge_port_name_size(); | |||
| CARLA_EXPORT int jackbridge_recompute_total_latencies(jack_client_t* client); | |||
| CARLA_EXPORT void jackbridge_port_get_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range); | |||
| CARLA_EXPORT void jackbridge_port_set_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range); | |||
| CARLA_EXPORT int jackbridge_activate(jack_client_t* client); | |||
| CARLA_EXPORT int jackbridge_deactivate(jack_client_t* client); | |||
| CARLA_EXPORT void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown_callback, void* arg); | |||
| CARLA_EXPORT void jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg); | |||
| CARLA_EXPORT int jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg); | |||
| CARLA_EXPORT int jackbridge_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback freewheel_callback, void* arg); | |||
| CARLA_EXPORT int jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg); | |||
| @@ -70,9 +74,13 @@ CARLA_EXPORT jack_transport_state_t jackbridge_transport_query(const jack_client | |||
| #define jackbridge_client_name_size jack_client_name_size | |||
| #define jackbridge_get_client_name jack_get_client_name | |||
| #define jackbridge_port_name_size jack_port_name_size | |||
| #define jackbridge_recompute_total_latencies jack_recompute_total_latencies | |||
| #define jackbridge_port_get_latency_range jack_port_get_latency_range | |||
| #define jackbridge_port_set_latency_range jack_port_set_latency_range | |||
| #define jackbridge_activate jack_activate | |||
| #define jackbridge_deactivate jack_deactivate | |||
| #define jackbridge_on_shutdown jack_on_shutdown | |||
| #define jackbridge_set_latency_callback jack_set_latency_callback | |||
| #define jackbridge_set_process_callback jack_set_process_callback | |||
| #define jackbridge_set_freewheel_callback jack_set_freewheel_callback | |||
| #define jackbridge_set_buffer_size_callback jack_set_buffer_size_callback | |||