aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jalv.c35
-rw-r--r--src/jalv_internal.h2
-rw-r--r--src/lv2_evbuf.c201
-rw-r--r--src/lv2_evbuf.h35
4 files changed, 185 insertions, 88 deletions
diff --git a/src/jalv.c b/src/jalv.c
index e927ee2..49fd8ba 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -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.