From 49c05a2653e2f6c8abd8390a5e1f07361cd66f33 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 2 Jun 2009 23:24:28 +0000 Subject: Fix horribly broken LV2 event implementation (ticket #378 among other problems). git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2061 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/AudioBuffer.cpp | 1 + src/engine/EventBuffer.cpp | 5 +++-- src/engine/InputPort.cpp | 19 +++++++------------ src/engine/LV2EventBuffer.cpp | 21 ++++++++++++++++++++- src/engine/LV2EventBuffer.hpp | 2 ++ 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/engine/AudioBuffer.cpp b/src/engine/AudioBuffer.cpp index 0b4a8364..a2ad7e07 100644 --- a/src/engine/AudioBuffer.cpp +++ b/src/engine/AudioBuffer.cpp @@ -244,6 +244,7 @@ AudioBuffer::accumulate(const AudioBuffer* const src, size_t start_sample, size_ bool AudioBuffer::join(Buffer* buf) { + assert(buf != this); AudioBuffer* abuf = dynamic_cast(buf); if (!abuf) return false; diff --git a/src/engine/EventBuffer.cpp b/src/engine/EventBuffer.cpp index 7110ccc2..5e3e8b4a 100644 --- a/src/engine/EventBuffer.cpp +++ b/src/engine/EventBuffer.cpp @@ -50,6 +50,7 @@ EventBuffer::EventBuffer(size_t capacity) bool EventBuffer::join(Buffer* buf) { + assert(buf != this); EventBuffer* ebuf = dynamic_cast(buf); if (!ebuf) return false; @@ -90,12 +91,12 @@ EventBuffer::copy(const Buffer* src_buf, size_t start_sample, size_t end_sample) const EventBuffer* src = dynamic_cast(src_buf); assert(src); assert(_buf->capacity() >= src->_buf->capacity()); + assert(src != this); assert(src->_buf != _buf); - //clear(); src->rewind(); - memcpy(_buf, src->_buf, src->_buf->size()); + _buf->copy(*src->_buf); _this_nframes = end_sample - start_sample; assert(event_count() == src->event_count()); } diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index 9b10580f..c42de5c6 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -210,21 +210,15 @@ InputPort::pre_process(ProcessContext& context) if ( ! _fixed_buffers) { // If only one connection, try to use buffer directly (zero copy) if (can_direct()) { - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->join(_connections.front()->buffer(i)); - _connections.front()->buffer(i)->prepare_read(context.start(), context.nframes()); - _buffers->at(i)->prepare_read(context.start(), context.nframes()); - } do_mixdown = false; + for (uint32_t i=0; i < _poly; ++i) + _buffers->at(i)->join(_connections.front()->buffer(i)); } connect_buffers(); } else { do_mixdown = true; } - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - /*cerr << path() << " poly = " << _poly << ", mixdown: " << do_mixdown << ", fixed buffers: " << _fixed_buffers << ", joined: " << _buffers->at(0)->is_joined() << " to " << _buffers->at(0)->joined_buffer() << endl;*/ @@ -237,10 +231,8 @@ InputPort::pre_process(ProcessContext& context) << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ if (!do_mixdown) { - /*#ifndef NDEBUG for (uint32_t i=0; i < _poly; ++i) - assert(buffer(i) == _connections.front()->buffer(i)); - #endif*/ + buffer(i)->prepare_read(context.start(), context.nframes()); return; } @@ -266,8 +258,11 @@ InputPort::pre_process(ProcessContext& context) cerr << "WARNING: MIDI mixing not implemented, only first connection used." << endl; // Copy first connection - _buffers->at(0)->copy(_connections.front()->buffer(0), 0, _buffer_size-1); + buffer(0)->copy(_connections.front()->buffer(0), 0, _buffer_size-1); } + + for (uint32_t i=0; i < _poly; ++i) + buffer(i)->prepare_read(context.start(), context.nframes()); } diff --git a/src/engine/LV2EventBuffer.cpp b/src/engine/LV2EventBuffer.cpp index cfd285d4..88b7ad22 100644 --- a/src/engine/LV2EventBuffer.cpp +++ b/src/engine/LV2EventBuffer.cpp @@ -52,10 +52,12 @@ LV2EventBuffer::LV2EventBuffer(size_t capacity) exit(EXIT_FAILURE); } + _data->header_size = sizeof(LV2_Event_Buffer); + _data->data = reinterpret_cast(_data + _data->header_size); + _data->stamp_type = 0; _data->event_count = 0; _data->capacity = (uint32_t)capacity; _data->size = 0; - _data->data = reinterpret_cast(_data + 1); reset(); @@ -188,5 +190,22 @@ LV2EventBuffer::append(const LV2_Event_Buffer* buf) } +/** Clear this buffer and copy @a buf into it. + * The capacity of this buffer must be >= the capacity of @a buf. + */ +void +LV2EventBuffer::copy(const LV2EventBuffer& buf) +{ + assert(buf._data->header_size == _data->header_size); + memcpy(_data, buf._data, _data->header_size + buf._data->size); + + _iter = buf._iter; + _iter.buf = _data; + + _latest_frames = buf._latest_frames; + _latest_subframes = buf._latest_subframes; +} + + } // namespace Ingen diff --git a/src/engine/LV2EventBuffer.hpp b/src/engine/LV2EventBuffer.hpp index 68633a8f..755352c6 100644 --- a/src/engine/LV2EventBuffer.hpp +++ b/src/engine/LV2EventBuffer.hpp @@ -66,6 +66,8 @@ public: bool append(const LV2_Event_Buffer* buf); + void copy(const LV2EventBuffer& buf); + private: LV2_Event_Buffer* _data; ///< Contents mutable LV2_Event_Iterator _iter; ///< Iterator into _data -- cgit v1.2.1