diff options
Diffstat (limited to 'src/lv2_evbuf.c')
-rw-r--r-- | src/lv2_evbuf.c | 201 |
1 files changed, 143 insertions, 58 deletions
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; } |