diff options
author | David Robillard <d@drobilla.net> | 2024-11-15 21:40:19 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2024-11-24 19:01:32 -0500 |
commit | 20b20156cfdc62dc87e258e25d12d0011c7d6e91 (patch) | |
tree | 5adee3f35b141bd3299b42204adc8e0f16b8452f /src/process.c | |
parent | 5f6531ef7edfef8b2056f5a6010603f00f210475 (diff) | |
download | jalv-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.c | 102 |
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; +} |