From f5377f922a41200b15d5d0b56d6dbbf82bed1b52 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 19 Jun 2011 16:42:43 +0000 Subject: Support control changes from UI. git-svn-id: http://svn.drobilla.net/lad/trunk/jalv@3403 a436a847-0d15-0410-975c-d299462d15a1 --- src/jalv.c | 46 +++++++++++++++++++++++++++++++++++++++------- src/jalv_internal.h | 30 ++++++++++++++++-------------- 2 files changed, 55 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/jalv.c b/src/jalv.c index 42bcd3d..de50521 100644 --- a/src/jalv.c +++ b/src/jalv.c @@ -25,7 +25,9 @@ #include #include -#include +#ifdef JALV_JACK_SESSION +# include +#endif #include "lv2/lv2plug.in/ns/ext/event/event-helpers.h" #include "lv2/lv2plug.in/ns/ext/event/event.h" @@ -42,6 +44,11 @@ sem_t exit_sem; /**< Exit semaphore */ #define MIDI_BUFFER_SIZE 1024 +typedef struct { + uint32_t index; + float value; +} ControlChange; + enum PortType { CONTROL, AUDIO, @@ -114,6 +121,10 @@ create_port(Jalv* host, const LilvNode* symbol = lilv_port_get_symbol(host->plugin, port->lilv_port); const char* symbol_str = lilv_node_as_string(symbol); + const bool optional = lilv_port_has_property(host->plugin, + port->lilv_port, + host->optional); + enum JackPortFlags jack_flags = 0; if (lilv_port_is_a(host->plugin, port->lilv_port, host->input_class)) { jack_flags = JackPortIsInput; @@ -121,10 +132,11 @@ create_port(Jalv* host, } else if (lilv_port_is_a(host->plugin, port->lilv_port, host->output_class)) { jack_flags = JackPortIsOutput; port->is_input = false; - } else if (lilv_port_has_property(host->plugin, port->lilv_port, host->optional)) { + } else if (optional) { lilv_instance_connect_port(host->instance, port_index, NULL); + return; } else { - die("Mandatory port has unknown type (neither input or output)"); + die("Mandatory port has unknown type (neither input nor output)"); } /* Set control values */ @@ -136,6 +148,11 @@ create_port(Jalv* host, port->type = AUDIO; } else if (lilv_port_is_a(host->plugin, port->lilv_port, host->event_class)) { port->type = EVENT; + } else if (optional) { + lilv_instance_connect_port(host->instance, port_index, NULL); + return; + } else { + die("Mandatory port has unknown type (neither control nor audio nor event)"); } /* Connect the port based on its type */ @@ -154,9 +171,7 @@ create_port(Jalv* host, lilv_instance_connect_port(host->instance, port_index, port->ev_buffer); break; default: - /* FIXME: check if port connection is optional and die if not */ - lilv_instance_connect_port(host->instance, port_index, NULL); - fprintf(stderr, "WARNING: Unknown port type, port not connected.\n"); + break; } } @@ -201,6 +216,14 @@ jack_process_cb(jack_nframes_t nframes, void* data) } } + /* Read and apply control change events from UI */ + ControlChange ev; + size_t ev_read_size = jack_ringbuffer_read_space(host->events); + for (size_t i = 0; i < ev_read_size; i += sizeof(ev)) { + jack_ringbuffer_read(host->events, (char*)&ev, sizeof(ev)); + host->ports[ev.index].control = ev.value; + } + /* Run plugin for this cycle */ lilv_instance_run(host->instance, nframes); @@ -265,7 +288,12 @@ lv2_ui_write(SuilController controller, uint32_t format, const void* buffer) { - fprintf(stderr, "UI WRITE\n"); + + Jalv* host = (Jalv*)controller; + + // FIXME: not guaranteed to be a float change... + const ControlChange ev = { port_index, *(float*)buffer }; + jack_ringbuffer_write(host->events, (const char*)&ev, sizeof(ev)); } static void @@ -284,6 +312,9 @@ main(int argc, char** argv) host.num_ports = 0; host.ports = NULL; + host.events = jack_ringbuffer_create(4096); + jack_ringbuffer_mlock(host.events); + sem_init(&exit_sem, 0, 0); host.done = &exit_sem; @@ -462,6 +493,7 @@ main(int argc, char** argv) /* Clean up */ free(host.ports); + jack_ringbuffer_free(host.events); lilv_node_free(native_ui_type); lilv_node_free(host.input_class); lilv_node_free(host.output_class); diff --git a/src/jalv_internal.h b/src/jalv_internal.h index f4dc6d4..aa50df0 100644 --- a/src/jalv_internal.h +++ b/src/jalv_internal.h @@ -20,6 +20,7 @@ #include #include +#include #include "lilv/lilv.h" @@ -30,20 +31,21 @@ extern "C" { #endif typedef struct { - LilvWorld* world; /**< Lilv World */ - jack_client_t* jack_client; /**< Jack client */ - sem_t* done; /**< Exit semaphore */ - const LilvPlugin* plugin; /**< Plugin class (RDF data) */ - LilvInstance* instance; /**< Plugin instance (shared library) */ - uint32_t num_ports; /**< Size of the two following arrays: */ - struct Port* ports; /**< Port array of size num_ports */ - LilvNode* input_class; /**< Input port class (URI) */ - LilvNode* output_class; /**< Output port class (URI) */ - LilvNode* control_class; /**< Control port class (URI) */ - LilvNode* audio_class; /**< Audio port class (URI) */ - LilvNode* event_class; /**< Event port class (URI) */ - LilvNode* midi_class; /**< MIDI event class (URI) */ - LilvNode* optional; /**< lv2:connectionOptional port property */ + LilvWorld* world; /**< Lilv World */ + jack_client_t* jack_client; /**< Jack client */ + jack_ringbuffer_t* events; /***< Control change events */ + sem_t* done; /**< Exit semaphore */ + const LilvPlugin* plugin; /**< Plugin class (RDF data) */ + LilvInstance* instance; /**< Plugin instance (shared library) */ + uint32_t num_ports; /**< Size of the two following arrays: */ + struct Port* ports; /**< Port array of size num_ports */ + LilvNode* input_class; /**< Input port class (URI) */ + LilvNode* output_class; /**< Output port class (URI) */ + LilvNode* control_class; /**< Control port class (URI) */ + LilvNode* audio_class; /**< Audio port class (URI) */ + LilvNode* event_class; /**< Event port class (URI) */ + LilvNode* midi_class; /**< MIDI event class (URI) */ + LilvNode* optional; /**< lv2:connectionOptional port property */ } Jalv; void -- cgit v1.2.1