Browse Source

Carla: Impelment jack-side latency, EXPERIMENTAL

This adds the need of an internal buffer in the plugins to properly handle dry/wet on those with latency
tags/v0.9.0
falkTX 13 years ago
parent
commit
edf7b549ac
9 changed files with 162 additions and 4 deletions
  1. +24
    -0
      c++/carla-backend/carla_engine.cpp
  2. +13
    -0
      c++/carla-backend/carla_engine.h
  3. +54
    -0
      c++/carla-backend/carla_engine_jack.cpp
  4. +7
    -1
      c++/carla-backend/dssi.cpp
  5. +7
    -1
      c++/carla-backend/ladspa.cpp
  6. +7
    -1
      c++/carla-backend/lv2.cpp
  7. +10
    -1
      c++/carla-backend/vst.cpp
  8. +32
    -0
      c++/carla-jackbridge/carla_jackbridge.cpp
  9. +8
    -0
      c++/carla-jackbridge/carla_jackbridge.h

+ 24
- 0
c++/carla-backend/carla_engine.cpp View File

@@ -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)
{


+ 13
- 0
c++/carla-backend/carla_engine.h View File

@@ -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


+ 54
- 0
c++/carla-backend/carla_engine_jack.cpp View File

@@ -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;


+ 7
- 1
c++/carla-backend/dssi.cpp View File

@@ -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);


+ 7
- 1
c++/carla-backend/ladspa.cpp View File

@@ -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();


+ 7
- 1
c++/carla-backend/lv2.cpp View File

@@ -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);


+ 10
- 1
c++/carla-backend/vst.cpp View File

@@ -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);


+ 32
- 0
c++/carla-jackbridge/carla_jackbridge.cpp View File

@@ -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


+ 8
- 0
c++/carla-jackbridge/carla_jackbridge.h View File

@@ -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


Loading…
Cancel
Save