aboutsummaryrefslogtreecommitdiffstats
path: root/src/process_setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process_setup.c')
-rw-r--r--src/process_setup.c198
1 files changed, 185 insertions, 13 deletions
diff --git a/src/process_setup.c b/src/process_setup.c
index 3f64d02..0e03932 100644
--- a/src/process_setup.c
+++ b/src/process_setup.c
@@ -3,27 +3,94 @@
#include "process_setup.h"
-#include "jalv.h"
+#include "jalv_config.h"
+#include "log.h"
#include "lv2_evbuf.h"
-#include "port.h"
+#include "macros.h"
+#include "mapper.h"
+#include "nodes.h"
+#include "process.h"
+#include "query.h"
+#include "settings.h"
+#include "string_utils.h"
#include "types.h"
#include "urids.h"
+#include "worker.h"
#include <lilv/lilv.h>
+#include <lv2/atom/atom.h>
+#include <lv2/atom/forge.h>
+#include <zix/allocator.h>
+#include <zix/ring.h>
+#include <zix/sem.h>
-#include <stddef.h>
+#include <stdbool.h>
#include <stdint.h>
+#include <stdlib.h>
+
+int
+jalv_process_init(JalvProcess* const proc,
+ const JalvURIDs* const urids,
+ JalvMapper* const mapper,
+ const uint32_t update_frames)
+{
+ proc->get_msg.atom.size = sizeof(LV2_Atom_Object_Body);
+ proc->get_msg.atom.type = urids->atom_Object;
+ proc->get_msg.body.id = 0U;
+ proc->get_msg.body.otype = urids->patch_Get;
+
+ proc->instance = NULL;
+ proc->ui_to_plugin = NULL;
+ proc->plugin_to_ui = NULL;
+ proc->worker = NULL;
+ proc->state_worker = NULL;
+ proc->ports = NULL;
+ proc->process_msg_size = 1024U;
+ proc->process_msg = NULL;
+ proc->run_state = JALV_PAUSED;
+ proc->control_in = UINT32_MAX;
+ proc->num_ports = 0U;
+ proc->pending_frames = 0U;
+ proc->update_frames = update_frames;
+ proc->position = 0U;
+ proc->bpm = 120.0f;
+ proc->rolling = false;
+ proc->has_ui = false;
+
+ zix_sem_init(&proc->paused, 0);
+ lv2_atom_forge_init(&proc->forge, jalv_mapper_urid_map(mapper));
+
+ return 0;
+}
void
-jalv_allocate_port_buffers(Jalv* const jalv)
+jalv_process_cleanup(JalvProcess* const proc)
{
- const JalvURIDs* const urids = &jalv->urids;
+ zix_sem_destroy(&proc->paused);
+ jalv_worker_free(proc->worker);
+ jalv_worker_free(proc->state_worker);
+ zix_ring_free(proc->ui_to_plugin);
+ zix_ring_free(proc->plugin_to_ui);
+ zix_free(NULL, proc->process_msg);
- for (uint32_t i = 0; i < jalv->num_ports; ++i) {
- JalvPort* const port = &jalv->ports[i];
+ for (uint32_t i = 0U; i < proc->num_ports; ++i) {
+ jalv_process_port_cleanup(&proc->ports[i]);
+ }
+}
+
+void
+jalv_process_activate(JalvProcess* const proc,
+ const JalvURIDs* const urids,
+ LilvInstance* const instance,
+ const JalvSettings* const settings)
+{
+ proc->instance = instance;
+
+ for (uint32_t i = 0U; i < proc->num_ports; ++i) {
+ JalvProcessPort* const port = &proc->ports[i];
if (port->type == TYPE_EVENT) {
const size_t size =
- port->buf_size ? port->buf_size : jalv->settings.midi_buf_size;
+ port->buf_size ? port->buf_size : settings->midi_buf_size;
lv2_evbuf_free(port->evbuf);
port->evbuf =
@@ -31,16 +98,121 @@ jalv_allocate_port_buffers(Jalv* const jalv)
lv2_evbuf_reset(port->evbuf, port->flow == FLOW_INPUT);
lilv_instance_connect_port(
- jalv->instance, i, lv2_evbuf_get_buffer(port->evbuf));
+ proc->instance, i, lv2_evbuf_get_buffer(port->evbuf));
+
+ if (port->flow == FLOW_INPUT) {
+ proc->process_msg_size = MAX(proc->process_msg_size, port->buf_size);
+ }
}
}
+
+ // Allocate UI<=>process communication rings and process receive buffer
+ proc->ui_to_plugin = zix_ring_new(NULL, settings->ring_size);
+ proc->plugin_to_ui = zix_ring_new(NULL, settings->ring_size);
+ proc->process_msg = zix_aligned_alloc(NULL, 8U, proc->process_msg_size);
+ zix_ring_mlock(proc->ui_to_plugin);
+ zix_ring_mlock(proc->plugin_to_ui);
+ zix_ring_mlock(proc->process_msg);
+}
+
+void
+jalv_process_deactivate(JalvProcess* const proc)
+{
+ zix_free(NULL, proc->process_msg);
+ proc->process_msg = NULL;
+
+ for (uint32_t i = 0U; i < proc->num_ports; ++i) {
+ lv2_evbuf_free(proc->ports[i].evbuf);
+ lilv_instance_connect_port(proc->instance, i, NULL);
+ proc->ports[i].evbuf = NULL;
+ }
+}
+
+int
+jalv_process_port_init(JalvProcessPort* const port,
+ const JalvNodes* const nodes,
+ const LilvPlugin* const lilv_plugin,
+ const LilvPort* const lilv_port)
+{
+ const LilvNode* const symbol = lilv_port_get_symbol(lilv_plugin, lilv_port);
+
+ port->type = TYPE_UNKNOWN;
+ port->flow = FLOW_UNKNOWN;
+ port->sys_port = NULL;
+ port->evbuf = NULL;
+ port->buf_size = 0U;
+ port->reports_latency = false;
+
+ const bool optional = lilv_port_has_property(
+ lilv_plugin, lilv_port, nodes->lv2_connectionOptional);
+
+ // Set port flow (input or output)
+ if (lilv_port_is_a(lilv_plugin, lilv_port, nodes->lv2_InputPort)) {
+ port->flow = FLOW_INPUT;
+ } else if (lilv_port_is_a(lilv_plugin, lilv_port, nodes->lv2_OutputPort)) {
+ port->flow = FLOW_OUTPUT;
+ } else if (!optional) {
+ jalv_log(JALV_LOG_ERR,
+ "Mandatory port \"%s\" is neither input nor output\n",
+ lilv_node_as_string(symbol));
+ return 1;
+ }
+
+ // Set port type
+ if (lilv_port_is_a(lilv_plugin, lilv_port, nodes->lv2_ControlPort)) {
+ port->type = TYPE_CONTROL;
+ } else if (lilv_port_is_a(lilv_plugin, lilv_port, nodes->lv2_AudioPort)) {
+ port->type = TYPE_AUDIO;
+#if USE_JACK_METADATA
+ } else if (lilv_port_is_a(lilv_plugin, lilv_port, nodes->lv2_CVPort)) {
+ port->type = TYPE_CV;
+#endif
+ } else if (lilv_port_is_a(lilv_plugin, lilv_port, nodes->atom_AtomPort)) {
+ port->type = TYPE_EVENT;
+ } else if (!optional) {
+ jalv_log(JALV_LOG_ERR,
+ "Mandatory port \"%s\" has unknown data type\n",
+ lilv_node_as_string(symbol));
+ return 1;
+ }
+
+ // Set symbol and label
+ LilvNode* const name = lilv_port_get_name(lilv_plugin, lilv_port);
+ port->symbol = symbol ? jalv_strdup(lilv_node_as_string(symbol)) : NULL;
+ port->label = name ? jalv_strdup(lilv_node_as_string(name)) : NULL;
+
+ // Set buffer size
+ LilvNode* const min_size =
+ lilv_port_get(lilv_plugin, lilv_port, nodes->rsz_minimumSize);
+ if (min_size && lilv_node_is_int(min_size)) {
+ port->buf_size = (uint32_t)MAX(lilv_node_as_int(min_size), 0);
+ }
+ lilv_node_free(min_size);
+
+ // Set reports_latency flag
+ if (port->flow == FLOW_OUTPUT && port->type == TYPE_CONTROL &&
+ (lilv_port_has_property(
+ lilv_plugin, lilv_port, nodes->lv2_reportsLatency) ||
+ jalv_port_has_designation(
+ nodes, lilv_plugin, lilv_port, nodes->lv2_latency))) {
+ port->reports_latency = true;
+ }
+
+ // Set supports_midi flag
+ port->supports_midi =
+ lilv_port_supports_event(lilv_plugin, lilv_port, nodes->midi_MidiEvent);
+
+ return 0;
}
void
-jalv_free_port_buffers(Jalv* const jalv)
+jalv_process_port_cleanup(JalvProcessPort* const port)
{
- for (uint32_t i = 0; i < jalv->num_ports; ++i) {
- lv2_evbuf_free(jalv->ports[i].evbuf);
- lilv_instance_connect_port(jalv->instance, i, NULL);
+ if (port) {
+ if (port->evbuf) {
+ lv2_evbuf_free(port->evbuf);
+ }
+ free(port->label);
+ free(port->symbol);
}
}