diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jalv.c | 35 | ||||
-rw-r--r-- | src/jalv_internal.h | 2 | ||||
-rw-r--r-- | src/lv2_evbuf.c | 201 | ||||
-rw-r--r-- | src/lv2_evbuf.h | 35 |
4 files changed, 185 insertions, 88 deletions
@@ -42,6 +42,8 @@ #include "lv2_evbuf.h" +#define NS_ATOM "http://lv2plug.in/ns/ext/atom#" + sem_t exit_sem; /**< Exit semaphore */ /** @@ -101,12 +103,12 @@ lv2_ui_resize(LV2_UI_Resize_Feature_Data data, int width, int height) LV2_UI_Resize_Feature ui_resize = { NULL, &lv2_ui_resize }; static const LV2_Feature ui_resize_feature = { NS_EXT "ui-resize#UIResize", &ui_resize }; -const LV2_Feature* features[4] = { - &uri_map_feature, &instance_feature, &ui_resize_feature +const LV2_Feature* features[5] = { + &uri_map_feature, &mapper_feature, &instance_feature, &ui_resize_feature }; #else -const LV2_Feature* features[3] = { - &uri_map_feature, &instance_feature, NULL +const LV2_Feature* features[4] = { + &uri_map_feature, &mapper_feature, &instance_feature, NULL }; #endif @@ -161,6 +163,10 @@ create_port(Jalv* host, port->type = TYPE_AUDIO; } else if (lilv_port_is_a(host->plugin, port->lilv_port, host->event_class)) { port->type = TYPE_EVENT; + port->old_api = true; + } else if (lilv_port_is_a(host->plugin, port->lilv_port, host->aevent_class)) { + port->type = TYPE_EVENT; + port->old_api = false; } else if (!optional) { die("Mandatory port has unknown type (neither control nor audio nor event)"); } @@ -199,7 +205,9 @@ jalv_allocate_port_buffers(Jalv* jalv) switch (port->type) { case TYPE_EVENT: lv2_evbuf_free(port->evbuf); - port->evbuf = lv2_evbuf_new(jalv->midi_buf_size); + port->evbuf = lv2_evbuf_new( + jalv->midi_buf_size, + port->old_api ? LV2_EVBUF_EVENT : LV2_EVBUF_ATOM); lilv_instance_connect_port( jalv->instance, i, lv2_evbuf_get_buffer(port->evbuf)); default: break; @@ -207,7 +215,6 @@ jalv_allocate_port_buffers(Jalv* jalv) } } - /** Get a port structure by symbol. @@ -311,9 +318,7 @@ jack_process_cb(jack_nframes_t nframes, void* data) void* buf = jack_port_get_buffer(host->ports[p].jack_port, nframes); - LV2_Evbuf_Iterator iter; - lv2_evbuf_begin(&iter, host->ports[p].evbuf); - + LV2_Evbuf_Iterator iter = lv2_evbuf_begin(host->ports[p].evbuf); for (uint32_t i = 0; i < jack_midi_get_event_count(buf); ++i) { jack_midi_event_t ev; jack_midi_event_get(&ev, buf, i); @@ -358,17 +363,15 @@ jack_process_cb(jack_nframes_t nframes, void* data) jack_midi_clear_buffer(buf); - LV2_Evbuf_Iterator iter; - lv2_evbuf_begin(&iter, host->ports[p].evbuf); - - const uint32_t event_count = lv2_evbuf_get_event_count(iter.evbuf); + LV2_Evbuf_Iterator iter = lv2_evbuf_begin(host->ports[p].evbuf); + const uint32_t event_count = lv2_evbuf_get_event_count(iter.evbuf); for (uint32_t i = 0; i < event_count; ++i) { uint32_t frames, subframes, type, size; uint8_t* data; - lv2_evbuf_get(&iter, &frames, &subframes, + lv2_evbuf_get(iter, &frames, &subframes, &type, &size, &data); jack_midi_event_write(buf, frames, data, size); - lv2_evbuf_increment(&iter); + iter = lv2_evbuf_next(iter); } } else if (send_ui_updates && !host->ports[p].flow == FLOW_INPUT @@ -465,6 +468,7 @@ main(int argc, char** argv) host.symap = symap_new(); uri_map.callback_data = &host; + mapper.handle = &host; host.midi_event_id = uri_to_id(&host, "http://lv2plug.in/ns/ext/event", "http://lv2plug.in/ns/ext/midi#MidiEvent"); @@ -493,6 +497,7 @@ main(int argc, char** argv) host.control_class = lilv_new_uri(world, LILV_URI_CONTROL_PORT); host.audio_class = lilv_new_uri(world, LILV_URI_AUDIO_PORT); host.event_class = lilv_new_uri(world, LILV_URI_EVENT_PORT); + host.aevent_class = lilv_new_uri(world, NS_ATOM "EventPort"); host.midi_class = lilv_new_uri(world, LILV_URI_MIDI_EVENT); host.optional = lilv_new_uri(world, LILV_NS_LV2 "connectionOptional"); diff --git a/src/jalv_internal.h b/src/jalv_internal.h index c171b72..e2f5dd5 100644 --- a/src/jalv_internal.h +++ b/src/jalv_internal.h @@ -57,6 +57,7 @@ struct Port { jack_port_t* jack_port; /**< For audio/MIDI ports, otherwise NULL */ float control; /**< For control ports, otherwise 0.0f */ LV2_Evbuf* evbuf; /**< For MIDI ports, otherwise NULL */ + bool old_api; /**< True for event, false for atom */ }; struct Property { @@ -102,6 +103,7 @@ typedef struct { LilvNode* control_class; /**< Control port class (URI) */ LilvNode* audio_class; /**< Audio port class (URI) */ LilvNode* event_class; /**< Event port class (URI) */ + LilvNode* aevent_class; /**< Atom event port class (URI) */ LilvNode* midi_class; /**< MIDI event class (URI) */ LilvNode* optional; /**< lv2:connectionOptional port property */ uint32_t midi_event_id; /**< MIDI event class ID */ diff --git a/src/lv2_evbuf.c b/src/lv2_evbuf.c index 8426297..8fab7f5 100644 --- a/src/lv2_evbuf.c +++ b/src/lv2_evbuf.c @@ -18,7 +18,6 @@ #include <stdbool.h> #include <string.h> #include <stdlib.h> -#include <assert.h> #include "lv2/lv2plug.in/ns/ext/atom/atom-buffer.h" #include "lv2/lv2plug.in/ns/ext/event/event.h" @@ -28,7 +27,7 @@ struct LV2_Evbuf_Impl { union { LV2_Event_Buffer event; - LV2_Atom_Buffer atom_event; + LV2_Atom_Buffer atom; } buf; LV2_Evbuf_Type type; }; @@ -40,11 +39,17 @@ lv2_evbuf_pad_size(uint32_t size) } LV2_Evbuf* -lv2_evbuf_new(uint32_t capacity) +lv2_evbuf_new(uint32_t capacity, LV2_Evbuf_Type type) { LV2_Evbuf* evbuf = (LV2_Evbuf*)malloc(sizeof(LV2_Evbuf)); - evbuf->type = LV2_EVBUF_EVENT_BUFFER; - evbuf->buf.event.capacity = capacity; + evbuf->type = type; + switch (type) { + case LV2_EVBUF_EVENT: + evbuf->buf.event.capacity = capacity; + break; + case LV2_EVBUF_ATOM: + evbuf->buf.atom.capacity = capacity; + } lv2_evbuf_reset(evbuf); return evbuf; } @@ -58,73 +63,127 @@ lv2_evbuf_free(LV2_Evbuf* evbuf) void lv2_evbuf_reset(LV2_Evbuf* evbuf) { - LV2_Event_Buffer* buf = &evbuf->buf.event; - buf->header_size = sizeof(LV2_Event_Buffer); - buf->stamp_type = LV2_EVENT_AUDIO_STAMP; - buf->event_count = 0; - buf->size = 0; + switch (evbuf->type) { + case LV2_EVBUF_EVENT: + evbuf->buf.event.header_size = sizeof(LV2_Event_Buffer); + evbuf->buf.event.stamp_type = LV2_EVENT_AUDIO_STAMP; + evbuf->buf.event.event_count = 0; + evbuf->buf.event.size = 0; + break; + case LV2_EVBUF_ATOM: + evbuf->buf.atom.event_count = 0; + evbuf->buf.atom.size = 0; + } +} + +uint32_t +lv2_evbuf_get_size(LV2_Evbuf* evbuf) +{ + switch (evbuf->type) { + case LV2_EVBUF_EVENT: + return evbuf->buf.event.size; + case LV2_EVBUF_ATOM: + return evbuf->buf.atom.size; + } + return 0; } uint32_t lv2_evbuf_get_event_count(LV2_Evbuf* evbuf) { - return evbuf->buf.event.event_count; + switch (evbuf->type) { + case LV2_EVBUF_EVENT: + return evbuf->buf.event.event_count; + case LV2_EVBUF_ATOM: + return evbuf->buf.atom.event_count; + } + return 0; } void* lv2_evbuf_get_buffer(LV2_Evbuf* evbuf) { - return &evbuf->buf.event; + switch (evbuf->type) { + case LV2_EVBUF_EVENT: + return &evbuf->buf.event; + case LV2_EVBUF_ATOM: + return &evbuf->buf.atom; + } + return NULL; } -bool -lv2_evbuf_begin(LV2_Evbuf_Iterator* iter, - LV2_Evbuf* evbuf) +LV2_Evbuf_Iterator +lv2_evbuf_begin(LV2_Evbuf* evbuf) { - LV2_Event_Buffer* buf = &evbuf->buf.event; - iter->offset = 0; - return buf->size > 0; + LV2_Evbuf_Iterator iter = { evbuf, 0 }; + return iter; } bool -lv2_evbuf_is_valid(LV2_Evbuf_Iterator* iter) +lv2_evbuf_is_valid(LV2_Evbuf_Iterator iter) { - return iter->offset < iter->evbuf->buf.event.size; + return iter.offset < lv2_evbuf_get_size(iter.evbuf); } -bool -lv2_evbuf_increment(LV2_Evbuf_Iterator* iter) +LV2_Evbuf_Iterator +lv2_evbuf_next(LV2_Evbuf_Iterator iter) { - assert(lv2_evbuf_is_valid(iter)); - - LV2_Event* const ev = (LV2_Event*)( - (uint8_t*)iter->evbuf->buf.event.data + iter->offset); + if (!lv2_evbuf_is_valid(iter)) { + return iter; + } - iter->offset += lv2_evbuf_pad_size(sizeof(LV2_Event) + ev->size); + LV2_Evbuf* evbuf = iter.evbuf; + uint32_t size; + uint32_t offset = iter.offset; + switch (evbuf->type) { + case LV2_EVBUF_EVENT: + size = ((LV2_Event*)(evbuf->buf.event.data + offset))->size; + break; + case LV2_EVBUF_ATOM: + size = ((LV2_Atom_Event*)(evbuf->buf.atom.data + offset))->body.size; + break; + } - return true; + offset += lv2_evbuf_pad_size(sizeof(LV2_Atom_Event) + size); + LV2_Evbuf_Iterator next = { evbuf, offset }; + return next; } bool -lv2_evbuf_get(LV2_Evbuf_Iterator* iter, - uint32_t* frames, - uint32_t* subframes, - uint32_t* type, - uint32_t* size, - uint8_t** data) +lv2_evbuf_get(LV2_Evbuf_Iterator iter, + uint32_t* frames, + uint32_t* subframes, + uint32_t* type, + uint32_t* size, + uint8_t** data) { *frames = *subframes = *type = *size = 0; *data = NULL; - assert(lv2_evbuf_is_valid(iter)); - LV2_Event* const ev = (LV2_Event*)( - (uint8_t*)iter->evbuf->buf.event.data + iter->offset); + if (!lv2_evbuf_is_valid(iter)) { + return false; + } - *frames = ev->frames; - *subframes = ev->subframes; - *type = ev->type; - *size = ev->size; - *data = (uint8_t*)ev + sizeof(LV2_Event); + LV2_Event* ev; + LV2_Atom_Event* aev; + switch (iter.evbuf->type) { + case LV2_EVBUF_EVENT: + ev = (LV2_Event*)(iter.evbuf->buf.event.data + iter.offset); + *frames = ev->frames; + *subframes = ev->subframes; + *type = ev->type; + *size = ev->size; + *data = (uint8_t*)ev + sizeof(LV2_Event); + break; + case LV2_EVBUF_ATOM: + aev = (LV2_Atom_Event*)(iter.evbuf->buf.atom.data + iter.offset); + *frames = aev->frames; + *subframes = aev->subframes; + *type = aev->body.type; + *size = aev->body.size; + *data = aev->body.body; + break; + } return true; } @@ -137,23 +196,49 @@ lv2_evbuf_write(LV2_Evbuf_Iterator* iter, uint32_t size, const uint8_t* data) { - LV2_Event_Buffer* buf = &iter->evbuf->buf.event; - if (buf->capacity - buf->size < sizeof(LV2_Event) + size) { - return false; + LV2_Event_Buffer* ebuf; + LV2_Event* ev; + LV2_Atom_Buffer* abuf; + LV2_Atom_Event* aev; + switch (iter->evbuf->type) { + case LV2_EVBUF_EVENT: + ebuf = &iter->evbuf->buf.event; + if (ebuf->capacity - ebuf->size < sizeof(LV2_Event) + size) { + return false; + } + + ev = (LV2_Event*)(ebuf->data + iter->offset); + ev->frames = frames; + ev->subframes = subframes; + ev->type = type; + ev->size = size; + memcpy((uint8_t*)ev + sizeof(LV2_Event), data, size); + + size = lv2_evbuf_pad_size(sizeof(LV2_Event) + size); + ebuf->size += size; + ebuf->event_count += 1; + iter->offset += size; + break; + case LV2_EVBUF_ATOM: + abuf = &iter->evbuf->buf.atom; + if (abuf->capacity - abuf->size < sizeof(LV2_Atom_Event) + size) { + return false; + } + + aev = (LV2_Atom_Event*)(abuf->data + iter->offset); + aev->frames = frames; + aev->subframes = subframes; + aev->body.type = type; + aev->body.size = size; + memcpy(aev->body.body, data, size); + ++abuf->event_count; + + size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + size); + abuf->size += size; + abuf->event_count += 1; + iter->offset += size; + break; } - LV2_Event* const ev = (LV2_Event*)((uint8_t*)buf->data + iter->offset); - - ev->frames = frames; - ev->subframes = subframes; - ev->type = type; - ev->size = size; - memcpy((uint8_t*)ev + sizeof(LV2_Event), data, size); - ++buf->event_count; - - size = lv2_evbuf_pad_size(sizeof(LV2_Event) + size); - buf->size += size; - iter->offset += size; - return true; } diff --git a/src/lv2_evbuf.h b/src/lv2_evbuf.h index 94aa1e0..7af161d 100644 --- a/src/lv2_evbuf.h +++ b/src/lv2_evbuf.h @@ -31,12 +31,12 @@ typedef enum { /** An old ev:EventBuffer (LV2_Event_Buffer). */ - LV2_EVBUF_EVENT_BUFFER, + LV2_EVBUF_EVENT, /** A new atom:EventBuffer (LV2_Atom_Event_Buffer). */ - LV2_EVBUF_ATOM_EVENT_BUFFER + LV2_EVBUF_ATOM } LV2_Evbuf_Type; /** @@ -56,7 +56,7 @@ typedef struct { Allocate a new, empty event buffer. */ LV2_Evbuf* -lv2_evbuf_new(uint32_t capacity); +lv2_evbuf_new(uint32_t capacity, LV2_Evbuf_Type type); /** Free an event buffer allocated with lv2_evbuf_new. @@ -73,6 +73,12 @@ void lv2_evbuf_reset(LV2_Evbuf* evbuf); /** + Return the total padded size of the events stored in the buffer. +*/ +uint32_t +lv2_evbuf_get_size(LV2_Evbuf* evbuf); + +/** Return the number of events stored in the buffer. */ uint32_t @@ -89,24 +95,23 @@ lv2_evbuf_get_buffer(LV2_Evbuf* evbuf); Reset an iterator to point to the start of @a buf. @return True if @a iter is valid, otherwise false (buffer is empty) */ -bool -lv2_evbuf_begin(LV2_Evbuf_Iterator* iter, - LV2_Evbuf* evbuf); +LV2_Evbuf_Iterator +lv2_evbuf_begin(LV2_Evbuf* evbuf); /** Check if @a iter is valid. @return True if @a iter is valid, otherwise false (past end of buffer) */ bool -lv2_evbuf_is_valid(LV2_Evbuf_Iterator* iter); +lv2_evbuf_is_valid(LV2_Evbuf_Iterator iter); /** Advance @a iter forward one event. @a iter must be valid. @return True if @a iter is valid, otherwise false (reached end of buffer) */ -bool -lv2_evbuf_increment(LV2_Evbuf_Iterator* iter); +LV2_Evbuf_Iterator +lv2_evbuf_next(LV2_Evbuf_Iterator iter); /** Dereference an event iterator (i.e. get the event currently pointed to). @@ -117,12 +122,12 @@ lv2_evbuf_increment(LV2_Evbuf_Iterator* iter); @return True on success. */ bool -lv2_evbuf_get(LV2_Evbuf_Iterator* iter, - uint32_t* frames, - uint32_t* subframes, - uint32_t* type, - uint32_t* size, - uint8_t** data); +lv2_evbuf_get(LV2_Evbuf_Iterator iter, + uint32_t* frames, + uint32_t* subframes, + uint32_t* type, + uint32_t* size, + uint8_t** data); /** Write an event at @a iter. |