aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend.h4
-rw-r--r--src/comm.h11
-rw-r--r--src/jack.c27
-rw-r--r--src/jalv.c2
-rw-r--r--src/portaudio.c5
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
diff --git a/src/comm.h b/src/comm.h
index e4579eb..11d7dc3 100644
--- a/src/comm.h
+++ b/src/comm.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
diff --git a/src/jack.c b/src/jack.c
index cf633f9..ea37ac5 100644
--- a/src/jack.c
+++ b/src/jack.c
@@ -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)
{
diff --git a/src/jalv.c b/src/jalv.c
index ea0e13b..beb36ca 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -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))
+{}