aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2024-11-15 21:40:19 -0500
committerDavid Robillard <d@drobilla.net>2024-11-24 19:01:32 -0500
commit20b20156cfdc62dc87e258e25d12d0011c7d6e91 (patch)
tree5adee3f35b141bd3299b42204adc8e0f16b8452f /src/process.c
parent5f6531ef7edfef8b2056f5a6010603f00f210475 (diff)
downloadjalv-20b20156cfdc62dc87e258e25d12d0011c7d6e91.tar.gz
jalv-20b20156cfdc62dc87e258e25d12d0011c7d6e91.tar.bz2
jalv-20b20156cfdc62dc87e258e25d12d0011c7d6e91.zip
Move process thread code to a separate file
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c102
1 files changed, 102 insertions, 0 deletions
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;
+}