diff options
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | src/jack.c | 1 | ||||
-rw-r--r-- | src/jalv.c | 85 | ||||
-rw-r--r-- | src/jalv_internal.h | 4 | ||||
-rw-r--r-- | src/portaudio.c | 1 | ||||
-rw-r--r-- | src/process.c | 102 | ||||
-rw-r--r-- | src/process.h | 32 |
7 files changed, 141 insertions, 85 deletions
diff --git a/meson.build b/meson.build index 2a01647..98a7066 100644 --- a/meson.build +++ b/meson.build @@ -419,6 +419,7 @@ common_sources = files( 'src/jalv.c', 'src/log.c', 'src/lv2_evbuf.c', + 'src/process.c', 'src/state.c', 'src/string_utils.c', 'src/symap.c', @@ -10,6 +10,7 @@ #include "log.h" #include "lv2_evbuf.h" #include "port.h" +#include "process.h" #include "string_utils.h" #include "types.h" @@ -53,7 +53,6 @@ # include "suil/suil.h" #endif -#include <assert.h> #include <math.h> #include <signal.h> #include <stdbool.h> @@ -562,62 +561,6 @@ jalv_ui_is_resizable(Jalv* jalv) return !fs_matches && !nrs_matches; } -static int -ring_error(const char* const message) -{ - jalv_log(JALV_LOG_ERR, "%s", message); - return 1; -} - -static int -jalv_apply_ui_events(Jalv* jalv, uint32_t nframes) -{ - if (!jalv->has_ui) { - return 0; - } - - ZixRing* const ring = jalv->ui_to_plugin; - JalvMessageHeader header = {NO_MESSAGE, 0U}; - const size_t space = zix_ring_read_space(ring); - for (size_t i = 0; i < space; i += sizeof(header) + header.size) { - // Read message header (which includes the body size) - if (zix_ring_read(ring, &header, sizeof(header)) != sizeof(header)) { - return ring_error("Failed to read header from UI ring\n"); - } - - if (header.type == CONTROL_PORT_CHANGE) { - assert(header.size == sizeof(JalvControlChange)); - JalvControlChange msg = {0U, 0.0f}; - if (zix_ring_read(ring, &msg, sizeof(msg)) != sizeof(msg)) { - return ring_error("Failed to read control value from UI ring\n"); - } - - assert(msg.port_index < jalv->num_ports); - jalv->ports[msg.port_index].control = msg.value; - - } else if (header.type == EVENT_TRANSFER) { - assert(header.size <= jalv->msg_buf_size); - void* const body = jalv->audio_msg; - if (zix_ring_read(ring, body, header.size) != header.size) { - return ring_error("Failed to read event from UI ring\n"); - } - - const JalvEventTransfer* const msg = (const JalvEventTransfer*)body; - assert(msg->port_index < jalv->num_ports); - struct Port* const port = &jalv->ports[msg->port_index]; - LV2_Evbuf_Iterator e = lv2_evbuf_end(port->evbuf); - const LV2_Atom* const atom = &msg->atom; - lv2_evbuf_write( - &e, nframes, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)); - - } else { - return ring_error("Unknown message type received from UI ring\n"); - } - } - - return 0; -} - void jalv_init_ui(Jalv* jalv) { @@ -671,31 +614,11 @@ jalv_dump_atom(Jalv* const jalv, } } -bool -jalv_run(Jalv* jalv, uint32_t nframes) +static int +ring_error(const char* const message) { - // Read and apply control change events from UI - jalv_apply_ui_events(jalv, nframes); - - // Run plugin for this cycle - lilv_instance_run(jalv->instance, nframes); - - // Process any worker replies and end the cycle - LV2_Handle handle = lilv_instance_get_handle(jalv->instance); - jalv_worker_emit_responses(jalv->state_worker, handle); - jalv_worker_emit_responses(jalv->worker, handle); - jalv_worker_end_run(jalv->worker); - - // Check if it's time to send updates to the UI - jalv->event_delta_t += nframes; - bool send_ui_updates = false; - uint32_t update_frames = (uint32_t)(jalv->sample_rate / jalv->ui_update_hz); - if (jalv->has_ui && (jalv->event_delta_t > update_frames)) { - send_ui_updates = true; - jalv->event_delta_t = 0; - } - - return send_ui_updates; + jalv_log(JALV_LOG_ERR, "%s", message); + return 1; } int diff --git a/src/jalv_internal.h b/src/jalv_internal.h index 458f020..5b7f341 100644 --- a/src/jalv_internal.h +++ b/src/jalv_internal.h @@ -166,10 +166,6 @@ jalv_dump_atom(Jalv* jalv, const LV2_Atom* atom, int color); -/// Run plugin instance for one buffer -bool -jalv_run(Jalv* jalv, uint32_t nframes); - /// Periodically update user interface int jalv_update(Jalv* jalv); diff --git a/src/portaudio.c b/src/portaudio.c index 4760d48..3f65a19 100644 --- a/src/portaudio.c +++ b/src/portaudio.c @@ -7,6 +7,7 @@ #include "log.h" #include "lv2_evbuf.h" #include "port.h" +#include "process.h" #include "types.h" #include "lilv/lilv.h" diff --git a/src/process.c b/src/process.c new file mode 100644 index 0000000..11cf72e --- /dev/null +++ b/src/process.c @@ -0,0 +1,102 @@ +// Copyright 2016-2024 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#include "process.h" + +#include "comm.h" +#include "jalv_internal.h" +#include "log.h" +#include "lv2_evbuf.h" +#include "port.h" +#include "worker.h" + +#include "lilv/lilv.h" +#include "lv2/atom/atom.h" +#include "lv2/core/lv2.h" +#include "zix/ring.h" + +#include <assert.h> +#include <stddef.h> + +static int +ring_error(const char* const message) +{ + jalv_log(JALV_LOG_ERR, "%s", message); + return 1; +} + +static int +apply_ui_events(Jalv* const jalv, const uint32_t nframes) +{ + if (!jalv->has_ui) { + return 0; + } + + ZixRing* const ring = jalv->ui_to_plugin; + JalvMessageHeader header = {NO_MESSAGE, 0U}; + const size_t space = zix_ring_read_space(ring); + for (size_t i = 0; i < space; i += sizeof(header) + header.size) { + // Read message header (which includes the body size) + if (zix_ring_read(ring, &header, sizeof(header)) != sizeof(header)) { + return ring_error("Failed to read header from UI ring\n"); + } + + if (header.type == CONTROL_PORT_CHANGE) { + assert(header.size == sizeof(JalvControlChange)); + JalvControlChange msg = {0U, 0.0f}; + if (zix_ring_read(ring, &msg, sizeof(msg)) != sizeof(msg)) { + return ring_error("Failed to read control value from UI ring\n"); + } + + assert(msg.port_index < jalv->num_ports); + jalv->ports[msg.port_index].control = msg.value; + + } else if (header.type == EVENT_TRANSFER) { + assert(header.size <= jalv->msg_buf_size); + void* const body = jalv->audio_msg; + if (zix_ring_read(ring, body, header.size) != header.size) { + return ring_error("Failed to read event from UI ring\n"); + } + + const JalvEventTransfer* const msg = (const JalvEventTransfer*)body; + assert(msg->port_index < jalv->num_ports); + struct Port* const port = &jalv->ports[msg->port_index]; + LV2_Evbuf_Iterator e = lv2_evbuf_end(port->evbuf); + const LV2_Atom* const atom = &msg->atom; + lv2_evbuf_write( + &e, nframes, 0U, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)); + + } else { + return ring_error("Unknown message type received from UI ring\n"); + } + } + + return 0; +} + +bool +jalv_run(Jalv* const jalv, const uint32_t nframes) +{ + // Read and apply control change events from UI + apply_ui_events(jalv, nframes); + + // Run plugin for this cycle + lilv_instance_run(jalv->instance, nframes); + + // Process any worker replies and end the cycle + LV2_Handle handle = lilv_instance_get_handle(jalv->instance); + jalv_worker_emit_responses(jalv->state_worker, handle); + jalv_worker_emit_responses(jalv->worker, handle); + jalv_worker_end_run(jalv->worker); + + // Check if it's time to send updates to the UI + jalv->event_delta_t += nframes; + bool send_ui_updates = false; + uint32_t update_frames = (uint32_t)(jalv->sample_rate / jalv->ui_update_hz); + if (jalv->has_ui && (jalv->event_delta_t > update_frames)) { + send_ui_updates = true; + jalv->event_delta_t = 0U; + } + + return send_ui_updates; +} diff --git a/src/process.h b/src/process.h new file mode 100644 index 0000000..366d30e --- /dev/null +++ b/src/process.h @@ -0,0 +1,32 @@ +// Copyright 2016-2024 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef JALV_PROCESS_H +#define JALV_PROCESS_H + +#include "attributes.h" +#include "types.h" + +#include <stdbool.h> +#include <stdint.h> + +JALV_BEGIN_DECLS + +// Code and data used in the realtime process thread + +/** + Run the plugin for a block of frames. + + Applies any pending messages from the UI, runs the plugin instance, and + processes any worker replies. + + @param jalv Application state. + @param nframes Number of frames to process. + @return Whether output value updates should be sent to the UI now. +*/ +bool +jalv_run(Jalv* jalv, uint32_t nframes); + +JALV_END_DECLS + +#endif // JALV_PROCESS_H |