diff options
Diffstat (limited to 'src/lv2_evbuf.c')
-rw-r--r-- | src/lv2_evbuf.c | 201 |
1 files changed, 102 insertions, 99 deletions
diff --git a/src/lv2_evbuf.c b/src/lv2_evbuf.c index a64d860..f19aac2 100644 --- a/src/lv2_evbuf.c +++ b/src/lv2_evbuf.c @@ -1,125 +1,124 @@ -/* - Copyright 2008-2018 David Robillard <http://drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ +// Copyright 2008-2022 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC #include "lv2_evbuf.h" +#include "jalv_config.h" #include "lv2/atom/atom.h" +#include "lv2/atom/util.h" #include <assert.h> #include <stdlib.h> #include <string.h> struct LV2_Evbuf_Impl { - uint32_t capacity; - uint32_t atom_Chunk; - uint32_t atom_Sequence; - LV2_Atom_Sequence buf; + uint32_t capacity; + uint32_t atom_Chunk; + uint32_t atom_Sequence; + uint32_t pad; // So buf has correct atom alignment + LV2_Atom_Sequence buf; }; -static inline uint32_t -lv2_evbuf_pad_size(uint32_t size) -{ - return (size + 7) & (~7); -} - LV2_Evbuf* lv2_evbuf_new(uint32_t capacity, uint32_t atom_Chunk, uint32_t atom_Sequence) { - // FIXME: memory must be 64-bit aligned - LV2_Evbuf* evbuf = (LV2_Evbuf*)malloc( - sizeof(LV2_Evbuf) + sizeof(LV2_Atom_Sequence) + capacity); - evbuf->capacity = capacity; - evbuf->atom_Chunk = atom_Chunk; - evbuf->atom_Sequence = atom_Sequence; - lv2_evbuf_reset(evbuf, true); - return evbuf; + const size_t buffer_size = + sizeof(LV2_Evbuf) + sizeof(LV2_Atom_Sequence) + capacity; + +#if USE_POSIX_MEMALIGN + LV2_Evbuf* evbuf = NULL; + const int st = posix_memalign((void**)&evbuf, 16, buffer_size); + if (st) { + return NULL; + } + + assert((uintptr_t)evbuf % 8U == 0U); +#else + LV2_Evbuf* evbuf = (LV2_Evbuf*)malloc(buffer_size); +#endif + + if (evbuf) { + memset(evbuf, 0, sizeof(*evbuf)); + evbuf->capacity = capacity; + evbuf->atom_Chunk = atom_Chunk; + evbuf->atom_Sequence = atom_Sequence; + } + + return evbuf; } void lv2_evbuf_free(LV2_Evbuf* evbuf) { - free(evbuf); + free(evbuf); } void lv2_evbuf_reset(LV2_Evbuf* evbuf, bool input) { - if (input) { - evbuf->buf.atom.size = sizeof(LV2_Atom_Sequence_Body); - evbuf->buf.atom.type = evbuf->atom_Sequence; - } else { - evbuf->buf.atom.size = evbuf->capacity; - evbuf->buf.atom.type = evbuf->atom_Chunk; - } + if (input) { + evbuf->buf.atom.size = sizeof(LV2_Atom_Sequence_Body); + evbuf->buf.atom.type = evbuf->atom_Sequence; + } else { + evbuf->buf.atom.size = evbuf->capacity; + evbuf->buf.atom.type = evbuf->atom_Chunk; + } } uint32_t lv2_evbuf_get_size(LV2_Evbuf* evbuf) { - assert(evbuf->buf.atom.type != evbuf->atom_Sequence - || evbuf->buf.atom.size >= sizeof(LV2_Atom_Sequence_Body)); - return evbuf->buf.atom.type == evbuf->atom_Sequence - ? evbuf->buf.atom.size - sizeof(LV2_Atom_Sequence_Body) - : 0; + assert(evbuf->buf.atom.type != evbuf->atom_Sequence || + evbuf->buf.atom.size >= sizeof(LV2_Atom_Sequence_Body)); + return evbuf->buf.atom.type == evbuf->atom_Sequence + ? evbuf->buf.atom.size - sizeof(LV2_Atom_Sequence_Body) + : 0; } void* lv2_evbuf_get_buffer(LV2_Evbuf* evbuf) { - return &evbuf->buf; + return &evbuf->buf; } LV2_Evbuf_Iterator lv2_evbuf_begin(LV2_Evbuf* evbuf) { - LV2_Evbuf_Iterator iter = { evbuf, 0 }; - return iter; + LV2_Evbuf_Iterator iter = {evbuf, 0}; + return iter; } LV2_Evbuf_Iterator lv2_evbuf_end(LV2_Evbuf* evbuf) { - const uint32_t size = lv2_evbuf_get_size(evbuf); - const LV2_Evbuf_Iterator iter = { evbuf, lv2_evbuf_pad_size(size) }; - return iter; + const uint32_t size = lv2_evbuf_get_size(evbuf); + const LV2_Evbuf_Iterator iter = {evbuf, lv2_atom_pad_size(size)}; + return iter; } bool lv2_evbuf_is_valid(LV2_Evbuf_Iterator iter) { - return iter.offset < lv2_evbuf_get_size(iter.evbuf); + return iter.offset < lv2_evbuf_get_size(iter.evbuf); } LV2_Evbuf_Iterator -lv2_evbuf_next(LV2_Evbuf_Iterator iter) +lv2_evbuf_next(const LV2_Evbuf_Iterator iter) { - if (!lv2_evbuf_is_valid(iter)) { - return iter; - } - - LV2_Evbuf* evbuf = iter.evbuf; - uint32_t offset = iter.offset; - uint32_t size; - size = ((LV2_Atom_Event*) - ((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, &evbuf->buf.atom) - + offset))->body.size; - offset += lv2_evbuf_pad_size(sizeof(LV2_Atom_Event) + size); - - LV2_Evbuf_Iterator next = { evbuf, offset }; - return next; + if (!lv2_evbuf_is_valid(iter)) { + return iter; + } + + LV2_Atom_Sequence* aseq = &iter.evbuf->buf; + LV2_Atom_Event* aev = + (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, aseq) + + iter.offset); + + const uint32_t offset = + iter.offset + lv2_atom_pad_size(sizeof(LV2_Atom_Event) + aev->body.size); + + LV2_Evbuf_Iterator next = {iter.evbuf, offset}; + return next; } bool @@ -128,26 +127,27 @@ lv2_evbuf_get(LV2_Evbuf_Iterator iter, uint32_t* subframes, uint32_t* type, uint32_t* size, - uint8_t** data) + void** data) { - *frames = *subframes = *type = *size = 0; - *data = NULL; + *frames = *subframes = *type = *size = 0; + *data = NULL; - if (!lv2_evbuf_is_valid(iter)) { - return false; - } + if (!lv2_evbuf_is_valid(iter)) { + return false; + } - LV2_Atom_Sequence* aseq = &iter.evbuf->buf; - LV2_Atom_Event* aev = (LV2_Atom_Event*)( - (char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, aseq) + iter.offset); + LV2_Atom_Sequence* aseq = &iter.evbuf->buf; + LV2_Atom_Event* aev = + (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, aseq) + + iter.offset); - *frames = aev->time.frames; - *subframes = 0; - *type = aev->body.type; - *size = aev->body.size; - *data = (uint8_t*)LV2_ATOM_BODY(&aev->body); + *frames = aev->time.frames; + *subframes = 0; + *type = aev->body.type; + *size = aev->body.size; + *data = LV2_ATOM_BODY(&aev->body); - return true; + return true; } bool @@ -156,25 +156,28 @@ lv2_evbuf_write(LV2_Evbuf_Iterator* iter, uint32_t subframes, uint32_t type, uint32_t size, - const uint8_t* data) + const void* data) { - LV2_Atom_Sequence* aseq = &iter->evbuf->buf; - if (iter->evbuf->capacity - sizeof(LV2_Atom) - aseq->atom.size < - sizeof(LV2_Atom_Event) + size) { - return false; - } + (void)subframes; + + LV2_Atom_Sequence* aseq = &iter->evbuf->buf; + if (iter->evbuf->capacity - sizeof(LV2_Atom) - aseq->atom.size < + sizeof(LV2_Atom_Event) + size) { + return false; + } - LV2_Atom_Event* aev = (LV2_Atom_Event*)( - (char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, aseq) + iter->offset); + LV2_Atom_Event* aev = + (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, aseq) + + iter->offset); - aev->time.frames = frames; - aev->body.type = type; - aev->body.size = size; - memcpy(LV2_ATOM_BODY(&aev->body), data, size); + aev->time.frames = frames; + aev->body.type = type; + aev->body.size = size; + memcpy(LV2_ATOM_BODY(&aev->body), data, size); - size = lv2_evbuf_pad_size(sizeof(LV2_Atom_Event) + size); - aseq->atom.size += size; - iter->offset += size; + size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + size); + aseq->atom.size += size; + iter->offset += size; - return true; + return true; } |