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; | 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) | const CarlaEngineBasePort* CarlaEngineClient::addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput) | ||||
| { | { | ||||
| qDebug("CarlaEngineClient::addPort(%i, \"%s\", %s)", portType, name, bool2str(isInput)); | qDebug("CarlaEngineClient::addPort(%i, \"%s\", %s)", portType, name, bool2str(isInput)); | ||||
| @@ -964,12 +977,23 @@ 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,6 +426,8 @@ public: | |||||
| bool isActive() const; | bool isActive() const; | ||||
| bool isOk() const; | bool isOk() const; | ||||
| void recomputeLatencies(); | |||||
| 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: | ||||
| @@ -444,6 +446,11 @@ public: | |||||
| virtual void initBuffer(CarlaEngine* const engine) = 0; | virtual void initBuffer(CarlaEngine* const engine) = 0; | ||||
| const CarlaEnginePortNativeHandle& getHandle() const | |||||
| { | |||||
| return handle; | |||||
| } | |||||
| protected: | protected: | ||||
| void* buffer; | void* buffer; | ||||
| const bool isInput; | const bool isInput; | ||||
| @@ -458,9 +465,15 @@ 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 | ||||
| @@ -79,6 +79,7 @@ public: | |||||
| jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this); | jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this); | ||||
| jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this); | jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this); | ||||
| jackbridge_set_process_callback(client, carla_jack_process_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); | jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this); | ||||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | 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_buffer_size_callback(client, carla_jack_bufsize_callback, this); | ||||
| jackbridge_set_freewheel_callback(client, carla_jack_freewheel_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_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); | jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this); | ||||
| #else | #else | ||||
| if (carlaOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) | if (carlaOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) | ||||
| @@ -196,6 +198,7 @@ public: | |||||
| { | { | ||||
| handle.jackClient = jackbridge_client_open(plugin->name(), JackNullOption, nullptr); | handle.jackClient = jackbridge_client_open(plugin->name(), JackNullOption, nullptr); | ||||
| jackbridge_set_process_callback(handle.jackClient, carla_jack_process_callback_plugin, plugin); | 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 | #endif | ||||
| @@ -457,6 +460,20 @@ protected: | |||||
| #endif | #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() | void handleShutdownCallback() | ||||
| { | { | ||||
| for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | ||||
| @@ -528,6 +545,23 @@ private: | |||||
| p->process(inBuffer, outBuffer, nframes); | 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) | static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg) | ||||
| { | { | ||||
| CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg; | CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg; | ||||
| @@ -570,6 +604,26 @@ private: | |||||
| return 0; | 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) | static void carla_jack_shutdown_callback(void* arg) | ||||
| { | { | ||||
| CarlaEngineJack* const _this_ = (CarlaEngineJack*)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); | 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(); | 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); | reloadPrograms(true); | ||||
| @@ -731,9 +731,18 @@ public: | |||||
| // check latency | // 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; | 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); | reloadPrograms(true); | ||||
| @@ -62,6 +62,29 @@ int jackbridge_port_name_size() | |||||
| #endif | #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) | int jackbridge_activate(jack_client_t* client) | ||||
| { | { | ||||
| #ifndef JACKBRIDGE_DUMMY | #ifndef JACKBRIDGE_DUMMY | ||||
| @@ -96,6 +119,15 @@ void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown | |||||
| #endif | #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) | int jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg) | ||||
| { | { | ||||
| #ifndef JACKBRIDGE_DUMMY | #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 int jackbridge_client_name_size(); | ||||
| CARLA_EXPORT char* jackbridge_get_client_name(jack_client_t* client); | CARLA_EXPORT char* jackbridge_get_client_name(jack_client_t* client); | ||||
| CARLA_EXPORT int jackbridge_port_name_size(); | 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_activate(jack_client_t* client); | ||||
| CARLA_EXPORT int jackbridge_deactivate(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_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_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_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); | 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_client_name_size jack_client_name_size | ||||
| #define jackbridge_get_client_name jack_get_client_name | #define jackbridge_get_client_name jack_get_client_name | ||||
| #define jackbridge_port_name_size jack_port_name_size | #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_activate jack_activate | ||||
| #define jackbridge_deactivate jack_deactivate | #define jackbridge_deactivate jack_deactivate | ||||
| #define jackbridge_on_shutdown jack_on_shutdown | #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_process_callback jack_set_process_callback | ||||
| #define jackbridge_set_freewheel_callback jack_set_freewheel_callback | #define jackbridge_set_freewheel_callback jack_set_freewheel_callback | ||||
| #define jackbridge_set_buffer_size_callback jack_set_buffer_size_callback | #define jackbridge_set_buffer_size_callback jack_set_buffer_size_callback | ||||