diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend.h | 4 | ||||
-rw-r--r-- | src/comm.h | 11 | ||||
-rw-r--r-- | src/jack.c | 27 | ||||
-rw-r--r-- | src/jalv.c | 2 | ||||
-rw-r--r-- | src/portaudio.c | 5 |
5 files changed, 45 insertions, 4 deletions
diff --git a/src/backend.h b/src/backend.h index 2965378..f48287c 100644 --- a/src/backend.h +++ b/src/backend.h @@ -33,6 +33,10 @@ jalv_backend_close(Jalv* jalv); void jalv_backend_activate_port(Jalv* jalv, uint32_t port_index); +/// Recompute latencies based on plugin port latencies if necessary +void +jalv_backend_recompute_latencies(Jalv* jalv); + JALV_END_DECLS #endif // JALV_BACKEND_H @@ -22,6 +22,7 @@ typedef enum { NO_MESSAGE, ///< Sentinel type for uninitialized messages CONTROL_PORT_CHANGE, ///< Value change for a control port (float) EVENT_TRANSFER, ///< Event transfer for a sequence port (atom) + LATENCY_CHANGE, ///< Change to plugin latency } JalvMessageType; /** @@ -59,6 +60,16 @@ typedef struct { } JalvEventTransfer; /** + The payload of a LATENCY_CHANGE message. + + This message has a fixed sized, and is described in its entirety by this + struct. +*/ +typedef struct { + float value; ///< Latency in frames at the current sample rate +} JalvLatencyChange; + +/** Write a message in two parts to a ring. This is used to conveniently write a message with a fixed-size header and @@ -1,4 +1,4 @@ -// Copyright 2007-2022 David Robillard <d@drobilla.net> +// Copyright 2007-2024 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #include "backend.h" @@ -46,6 +46,9 @@ struct JalvBackendImpl { bool is_internal_client; ///< Running inside jackd }; +/// Maximum supported latency in frames (at most 2^24 so all integers work) +static const float max_latency = 16777216.0f; + /// Internal Jack client initialization entry point int jack_initialize(jack_client_t* client, const char* load_init); @@ -201,9 +204,19 @@ jack_process_cb(jack_nframes_t nframes, void* data) struct Port* const port = &jalv->ports[p]; if (port->flow == FLOW_OUTPUT && port->type == TYPE_CONTROL && port->reports_latency) { - if (jalv->plugin_latency != port->control) { - jalv->plugin_latency = port->control; - jack_recompute_total_latencies(client); + // Get the latency in frames from the control output truncated to integer + const float value = port->control; + const uint32_t frames = + (value >= 0.0f && value <= max_latency) ? (uint32_t)value : 0U; + + if (jalv->plugin_latency != frames) { + // Update the cached value and notify the UI if the latency changed + jalv->plugin_latency = frames; + + const JalvLatencyChange body = {frames}; + const JalvMessageHeader header = {LATENCY_CHANGE, sizeof(body)}; + jalv_write_split_message( + jalv->plugin_to_ui, &header, sizeof(header), &body, sizeof(body)); } } else if (port->flow == FLOW_OUTPUT && port->type == TYPE_EVENT) { void* buf = NULL; @@ -461,6 +474,12 @@ jalv_backend_activate_port(Jalv* jalv, uint32_t port_index) #endif } +void +jalv_backend_recompute_latencies(Jalv* const jalv) +{ + jack_recompute_total_latencies(jalv->backend->client); +} + int jack_initialize(jack_client_t* const client, const char* const load_init) { @@ -737,6 +737,8 @@ jalv_update(Jalv* jalv) sizeof(LV2_Atom) + msg->atom.size, jalv->urids.atom_eventTransfer, &msg->atom); + } else if (header.type == LATENCY_CHANGE) { + jalv_backend_recompute_latencies(jalv); } else { return ring_error("Unknown message type received from process ring\n"); } diff --git a/src/portaudio.c b/src/portaudio.c index 9e37d29..4760d48 100644 --- a/src/portaudio.c +++ b/src/portaudio.c @@ -11,6 +11,7 @@ #include "lilv/lilv.h" #include "lv2/atom/atom.h" +#include "zix/attributes.h" #include <portaudio.h> #include <stdbool.h> @@ -215,3 +216,7 @@ jalv_backend_activate_port(Jalv* jalv, uint32_t port_index) lilv_instance_connect_port(jalv->instance, port_index, &port->control); } } + +void +jalv_backend_recompute_latencies(Jalv* const ZIX_UNUSED(jalv)) +{} |