From cf63c971c2a8ee8cc2ddcddb52ce8135cd29619b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 13 Oct 2007 20:35:29 +0000 Subject: Fix sub-patch MIDI I/O. Make buffer 'joining' (zero-copy connections) significantly less retarded. git-svn-id: http://svn.drobilla.net/lad/ingen@882 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/AudioBuffer.cpp | 12 ------------ src/libs/engine/AudioBuffer.hpp | 9 +++------ src/libs/engine/Buffer.hpp | 9 +++++++-- src/libs/engine/ConnectionImpl.cpp | 5 +++++ src/libs/engine/DuplexPort.cpp | 31 ++++++++++++++++++++++++++++--- src/libs/engine/InputPort.cpp | 29 +++++++++++++++++++---------- src/libs/engine/JackAudioDriver.cpp | 2 ++ src/libs/engine/LADSPANode.cpp | 12 ++++++------ src/libs/engine/MidiBuffer.cpp | 27 ++++++++++----------------- src/libs/engine/MidiBuffer.hpp | 26 ++++++++++++-------------- src/libs/engine/MidiNoteNode.cpp | 14 ++++++++------ src/libs/engine/OSCBuffer.cpp | 11 ----------- src/libs/engine/OSCBuffer.hpp | 13 ++++--------- src/libs/engine/OutputPort.cpp | 9 +++++++-- src/libs/engine/PatchImpl.cpp | 7 +++++++ src/libs/engine/PortImpl.cpp | 4 ++-- src/libs/engine/PortImpl.hpp | 11 ++++++++++- 17 files changed, 130 insertions(+), 101 deletions(-) (limited to 'src/libs/engine') diff --git a/src/libs/engine/AudioBuffer.cpp b/src/libs/engine/AudioBuffer.cpp index c302480a..b4038586 100644 --- a/src/libs/engine/AudioBuffer.cpp +++ b/src/libs/engine/AudioBuffer.cpp @@ -32,7 +32,6 @@ AudioBuffer::AudioBuffer(size_t size) : Buffer((size == 1) ? DataType::CONTROL : DataType::AUDIO, size) , _data(NULL) , _local_data(NULL) - , _joined_buf(NULL) , _size(size) , _filled_size(0) , _state(OK) @@ -254,17 +253,6 @@ AudioBuffer::unjoin() } -bool -AudioBuffer::is_joined_to(Buffer* buf) const -{ - AudioBuffer* abuf = dynamic_cast(buf); - if (abuf) - return (data() == abuf->data()); - - return false; -} - - void AudioBuffer::prepare_read(SampleCount nframes) { diff --git a/src/libs/engine/AudioBuffer.hpp b/src/libs/engine/AudioBuffer.hpp index de9fc4a6..44650856 100644 --- a/src/libs/engine/AudioBuffer.hpp +++ b/src/libs/engine/AudioBuffer.hpp @@ -41,16 +41,14 @@ public: bool join(Buffer* buf); void unjoin(); - bool is_joined_to(Buffer* buf) const; /** For driver use only!! */ void set_data(Sample* data); - inline void* raw_data() const - { return ((_joined_buf != NULL) ? _joined_buf->raw_data() : _data); } + inline const void* raw_data() const { return _data; } + inline void* raw_data() { return _data; } - inline Sample* data() const - { return ((_joined_buf != NULL) ? _joined_buf->data() : _data); } + inline Sample* data() const { return _data; } inline Sample& value_at(size_t offset) const { assert(offset < _size); return data()[offset]; } @@ -73,7 +71,6 @@ private: Sample* _data; ///< Used data pointer (probably same as _local_data) Sample* _local_data; ///< Locally allocated buffer (possibly unused if joined or set_data used) - AudioBuffer* _joined_buf; ///< Buffer to mirror, if joined size_t _size; ///< Allocated buffer size size_t _filled_size; ///< Usable buffer size (for MIDI ports etc) State _state; ///< State of buffer for setting values next cycle diff --git a/src/libs/engine/Buffer.hpp b/src/libs/engine/Buffer.hpp index d18270f5..30180064 100644 --- a/src/libs/engine/Buffer.hpp +++ b/src/libs/engine/Buffer.hpp @@ -34,12 +34,14 @@ public: Buffer(Shared::DataType type, size_t size) : _type(type) , _size(size) + , _joined_buf(NULL) {} /** Clear contents and reset state */ virtual void clear() = 0; - virtual void* raw_data() const = 0; + virtual void* raw_data() = 0; + virtual const void* raw_data() const = 0; /** Rewing (ie reset read pointer), but leave contents unchanged */ virtual void rewind() const = 0; @@ -47,7 +49,9 @@ public: virtual void prepare_read(SampleCount nframes) = 0; virtual void prepare_write(SampleCount nframes) = 0; - virtual bool is_joined_to(Buffer* buf) const = 0; + bool is_joined() const { return (_joined_buf != NULL); } + Buffer* joined_buffer() const { return _joined_buf; } + virtual bool join(Buffer* buf) = 0; virtual void unjoin() = 0; @@ -61,6 +65,7 @@ public: protected: Shared::DataType _type; size_t _size; + Buffer* _joined_buf; }; diff --git a/src/libs/engine/ConnectionImpl.cpp b/src/libs/engine/ConnectionImpl.cpp index 57d5e1ad..f2bfeda5 100644 --- a/src/libs/engine/ConnectionImpl.cpp +++ b/src/libs/engine/ConnectionImpl.cpp @@ -62,6 +62,7 @@ ConnectionImpl::ConnectionImpl(PortImpl* src_port, PortImpl* dst_port) if (_must_mix) _local_buffer = BufferFactory::create(dst_port->type(), dst_port->buffer(0)->size()); + /* FIXME: 1->1 connections with a destination with fixed buffers copies unecessarily */ //cerr << src_port->path() << " -> " << dst_port->path() << " must mix: " << _must_mix << endl; } @@ -126,6 +127,10 @@ ConnectionImpl::process(ProcessContext& context) * a buffer (if it hasn't been done already this cycle) and returns that * would avoid having to mix multiple times. Probably not a very common * case, but it would be faster anyway. */ + + /*cerr << src_port()->path() << " * " << src_port()->poly() + << " -> " << dst_port()->path() << " * " << dst_port()->poly() + << "\t\tmust mix: " << _must_mix << endl;*/ if (_must_mix && (type() == DataType::CONTROL || type() == DataType::AUDIO)) { diff --git a/src/libs/engine/DuplexPort.cpp b/src/libs/engine/DuplexPort.cpp index 93b61b8c..0da8d9d4 100644 --- a/src/libs/engine/DuplexPort.cpp +++ b/src/libs/engine/DuplexPort.cpp @@ -23,6 +23,7 @@ #include "ConnectionImpl.hpp" #include "OutputPort.hpp" #include "NodeImpl.hpp" +#include "ProcessContext.hpp" using namespace std; @@ -43,10 +44,26 @@ void DuplexPort::pre_process(ProcessContext& context) { // - InputPort::pre_process(context); + + /*cerr << path() << " duplex pre: fixed buffers: " << fixed_buffers() << endl; + cerr << path() << " duplex pre: buffer: " << buffer(0) << endl; + cerr << path() << " duplex pre: is_output: " << _is_output << " { " << endl;*/ + + if (_is_output) { + + for (uint32_t i=0; i < _poly; ++i) + _buffers->at(i)->prepare_write(context.nframes()); + + } else { + + for (uint32_t i=0; i < _poly; ++i) + _buffers->at(i)->prepare_read(context.nframes()); - if ( ! _is_output) broadcast(context); + } + + //cerr << "} pre " << path() << endl; + // } @@ -54,12 +71,20 @@ DuplexPort::pre_process(ProcessContext& context) void DuplexPort::post_process(ProcessContext& context) { + /*cerr << path() << " duplex post: fixed buffers: " << fixed_buffers() << endl; + cerr << path() << " duplex post: buffer: " << buffer(0) << endl; + cerr << path() << " duplex post: is_output: " << _is_output << " { " << endl;*/ + // - if (_is_output) + if (_is_output) { + InputPort::pre_process(context); // Mix down inputs broadcast(context); + } OutputPort::pre_process(context); // + + //cerr << "} post " << path() << endl; } diff --git a/src/libs/engine/InputPort.cpp b/src/libs/engine/InputPort.cpp index b9723855..f64cf97b 100644 --- a/src/libs/engine/InputPort.cpp +++ b/src/libs/engine/InputPort.cpp @@ -152,7 +152,7 @@ InputPort::pre_process(ProcessContext& context) if (_connections.size() == 0) { for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_read(context.nframes()); + buffer(i)->prepare_read(context.nframes()); return; } @@ -162,8 +162,10 @@ InputPort::pre_process(ProcessContext& context) if ( ! _fixed_buffers) { // If only one connection, try to use buffer directly (zero copy) if (_connections.size() == 1) { - for (uint32_t i=0; i < _poly; ++i) + for (uint32_t i=0; i < _poly; ++i) { + //cerr << path() << " joining to " << (*_connections.begin())->buffer(i) << endl; _buffers->at(i)->join((*_connections.begin())->buffer(i)); + } do_mixdown = false; } connect_buffers(); @@ -172,22 +174,27 @@ InputPort::pre_process(ProcessContext& context) } for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_read(context.nframes()); + buffer(i)->prepare_read(context.nframes()); + + /*cerr << path() << " poly = " << _poly << ", mixdown: " << do_mixdown + << ", fixed buffers: " << _fixed_buffers << endl; - //cerr << path() << " poly = " << _poly << ", mixdown: " << do_mixdown << endl; + if (type() == DataType::MIDI) + for (uint32_t i=0; i < _poly; ++i) + cerr << path() << " (" << buffer(i) << ") # events: " << ((MidiBuffer*)buffer(i))->event_count() << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ if (!do_mixdown) { -#ifndef NDEBUG +/*#ifndef NDEBUG for (uint32_t i=0; i < _poly; ++i) - assert(_buffers->at(i)->is_joined_to((*_connections.begin())->buffer(i))); -#endif + assert(buffer(i) == (*_connections.begin())->buffer(i)); +#endif*/ return; } if (_type == DataType::CONTROL || _type == DataType::AUDIO) { for (uint32_t voice=0; voice < _poly; ++voice) { // Copy first connection - _buffers->at(voice)->copy( + buffer(voice)->copy( (*_connections.begin())->buffer(voice), 0, _buffer_size-1); // Accumulate the rest @@ -196,7 +203,7 @@ InputPort::pre_process(ProcessContext& context) Connections::iterator c = _connections.begin(); for (++c; c != _connections.end(); ++c) - ((AudioBuffer*)_buffers->at(voice))->accumulate( + ((AudioBuffer*)buffer(voice))->accumulate( ((AudioBuffer*)(*c)->buffer(voice)), 0, _buffer_size-1); } } @@ -221,7 +228,9 @@ InputPort::post_process(ProcessContext& context) // Prepare for next cycle for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_write(context.nframes()); + buffer(i)->prepare_write(context.nframes()); + + //cerr << path() << " input post: buffer: " << buffer(0) << endl; } diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp index f90e1075..8d8203ce 100644 --- a/src/libs/engine/JackAudioDriver.cpp +++ b/src/libs/engine/JackAudioDriver.cpp @@ -79,6 +79,8 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes) AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0); + //cerr << "[JACK] " << _patch_port->path() << " buffer: " << patch_buf << endl; + if (jack_buf != _jack_buffer) { patch_buf->set_data(jack_buf); _jack_buffer = jack_buf; diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp index ee5da968..033f3d50 100644 --- a/src/libs/engine/LADSPANode.cpp +++ b/src/libs/engine/LADSPANode.cpp @@ -78,10 +78,6 @@ LADSPANode::instantiate() for (size_t j=0; j < _descriptor->PortCount; ++j) { port_name = Path::nameify(_descriptor->PortNames[j]); - - if (_descriptor->PortNames[j] != port_name) - cerr << "WARNING: Translated LADSPA port name: " << - _descriptor->PortNames[j] << " -> " << port_name << endl; string::size_type slash_index; @@ -90,14 +86,18 @@ LADSPANode::instantiate() assert(_descriptor->PortNames[k] != NULL); if (k != j && port_name == _descriptor->PortNames[k]) { // clash if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) - port_name += "_(CR)"; + port_name += "(CR)"; else - port_name += "_(AR)"; + port_name += "(AR)"; } // Replace all slashes with "-" (so they don't screw up paths) while ((slash_index = port_name.find("/")) != string::npos) port_name[slash_index] = '-'; } + + if (_descriptor->PortNames[j] != port_name) + cerr << "NOTICE: Translated LADSPA port name: " << + _descriptor->PortNames[j] << " -> " << port_name << endl; port_path = path() + "/" + port_name; diff --git a/src/libs/engine/MidiBuffer.cpp b/src/libs/engine/MidiBuffer.cpp index 618c7476..929ac840 100644 --- a/src/libs/engine/MidiBuffer.cpp +++ b/src/libs/engine/MidiBuffer.cpp @@ -31,7 +31,6 @@ namespace Ingen { MidiBuffer::MidiBuffer(size_t capacity) : Buffer(DataType(DataType::MIDI), capacity) , _latest_stamp(0) - , _joined_buf(NULL) { if (capacity > UINT32_MAX) { cerr << "MIDI buffer size " << capacity << " too large, aborting." << endl; @@ -98,20 +97,11 @@ MidiBuffer::unjoin() } -bool -MidiBuffer::is_joined_to(Buffer* buf) const -{ - MidiBuffer* mbuf = dynamic_cast(buf); - if (mbuf) - return (data() == mbuf->data()); - - return false; -} - - void MidiBuffer::prepare_read(SampleCount nframes) { + //cerr << "\t" << this << " prepare_read: " << event_count() << endl; + rewind(); _this_nframes = nframes; } @@ -120,6 +110,7 @@ MidiBuffer::prepare_read(SampleCount nframes) void MidiBuffer::prepare_write(SampleCount nframes) { + //cerr << "\t" << this << " prepare_write: " << event_count() << endl; reset(nframes); } @@ -214,17 +205,19 @@ MidiBuffer::get_event(double* timestamp, uint32_t* size, unsigned char** data) const { - if (_position >= _buf->size) { - _position = _buf->size; + const LV2_MIDI* buf = this->data(); + + if (_position >= buf->size) { + _position = buf->size; *timestamp = _this_nframes; *size = 0; *data = NULL; return _this_nframes; } - *timestamp = *(double*)(_buf->data + _position); - *size = *(uint32_t*)(_buf->data + _position + sizeof(double)); - *data = _buf->data + _position + sizeof(double) + sizeof(uint32_t); + *timestamp = *(double*)(buf->data + _position); + *size = *(uint32_t*)(buf->data + _position + sizeof(double)); + *data = buf->data + _position + sizeof(double) + sizeof(uint32_t); return *timestamp; } diff --git a/src/libs/engine/MidiBuffer.hpp b/src/libs/engine/MidiBuffer.hpp index fe3d36bb..e5ebc290 100644 --- a/src/libs/engine/MidiBuffer.hpp +++ b/src/libs/engine/MidiBuffer.hpp @@ -18,6 +18,7 @@ #ifndef MIDIBUFFER_H #define MIDIBUFFER_H +#include #include #include "Buffer.hpp" #include "interface/DataType.hpp" @@ -34,29 +35,27 @@ public: void prepare_read(SampleCount nframes); void prepare_write(SampleCount nframes); - bool is_joined_to(Buffer* buf) const; bool join(Buffer* buf); void unjoin(); - uint32_t this_nframes() const { return _this_nframes; } - uint32_t event_count() const { return _buf->event_count; } + inline uint32_t this_nframes() const { return _this_nframes; } + inline uint32_t event_count() const { return _buf->event_count; } - inline LV2_MIDI* local_data() { return _local_buf; } - - inline void* raw_data() const - { return ((_joined_buf != NULL) ? _joined_buf->raw_data() : _buf); } + inline void* raw_data() { return _buf; } + inline const void* raw_data() const { return _buf; } - inline LV2_MIDI* data() - { return ((_joined_buf != NULL) ? _joined_buf->data() : _buf); } - - inline const LV2_MIDI* data() const - { return ((_joined_buf != NULL) ? _joined_buf->data() : _buf); } + inline LV2_MIDI* local_data() { return _local_buf; } + inline const LV2_MIDI* local_data() const { return _local_buf; } + + inline LV2_MIDI* data() { return _buf; } + inline const LV2_MIDI* data() const { return _buf; } void copy(const Buffer* src, size_t start_sample, size_t end_sample); inline void rewind() const { _position = 0; } - inline void clear() { if (_joined_buf) reset(_this_nframes); } + inline void clear() { reset(_this_nframes); } inline void reset(SampleCount nframes) { + //std::cerr << this << " reset" << std::endl; _latest_stamp = 0; _position = 0; _buf->event_count = 0; @@ -75,7 +74,6 @@ private: double _latest_stamp; ///< Highest timestamp of all events uint32_t _this_nframes; ///< Current cycle nframes mutable uint32_t _position; ///< Index into _buf - MidiBuffer* _joined_buf; ///< Buffer to mirror, if joined LV2_MIDI* _buf; ///< Contents (maybe belong to _joined_buf) LV2_MIDI* _local_buf; ///< Local contents }; diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp index 7b3c1c9e..c90f44ae 100644 --- a/src/libs/engine/MidiNoteNode.cpp +++ b/src/libs/engine/MidiNoteNode.cpp @@ -130,6 +130,8 @@ MidiNoteNode::process(ProcessContext& context) MidiBuffer* const midi_in = (MidiBuffer*)_midi_in_port->buffer(0); assert(midi_in->this_nframes() == context.nframes()); + //cerr << path() << " # input events: " << midi_in->event_count() << endl; + if (midi_in->event_count() > 0) while (midi_in->get_event(×tamp, &size, &buffer) < context.nframes()) { @@ -167,11 +169,11 @@ MidiNoteNode::process(ProcessContext& context) } break; default: - //fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buffer[0]); + fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buffer[0]); break; } } else { - //fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buffer[0]); + fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buffer[0]); } if (midi_in->increment() == midi_in->this_nframes()) @@ -218,8 +220,8 @@ MidiNoteNode::note_on(uchar note_num, uchar velocity, FrameTime time, ProcessCon assert(voice != NULL); assert(voice == &(*_voices)[voice_num]); - cerr << "[MidiNoteNode] Note " << (int)note_num << " on @ " << time - << ". Voice " << voice_num << " / " << _polyphony << endl; + //cerr << "[MidiNoteNode] Note " << (int)note_num << " on @ " << time + // << ". Voice " << voice_num << " / " << _polyphony << endl; // Update stolen key, if applicable if (voice->state == Voice::Voice::ACTIVE) { @@ -273,7 +275,7 @@ MidiNoteNode::note_off(uchar note_num, FrameTime time, ProcessContext& context) Key* key = &_keys[note_num]; - cerr << "[MidiNoteNode] Note off @ " << time << ". Key " << (int)note_num << endl; + //cerr << "[MidiNoteNode] Note " << (int)note_num << " off @ " << time << endl; if (key->state == Key::ON_ASSIGNED) { // Assigned key, turn off voice and key @@ -345,7 +347,7 @@ MidiNoteNode::all_notes_off(FrameTime time, ProcessContext& context) assert(time >= context.start() && time <= context.end()); assert(time - context.start() < _buffer_size); - //cerr << "Note off starting at sample " << offset << endl; + //cerr << "All notes off @ " << offset << endl; // FIXME: set all keys to Key::OFF? diff --git a/src/libs/engine/OSCBuffer.cpp b/src/libs/engine/OSCBuffer.cpp index 977d4e66..f8454a14 100644 --- a/src/libs/engine/OSCBuffer.cpp +++ b/src/libs/engine/OSCBuffer.cpp @@ -73,17 +73,6 @@ OSCBuffer::unjoin() } -bool -OSCBuffer::is_joined_to(Buffer* buf) const -{ - OSCBuffer* obuf = dynamic_cast(buf); - if (obuf) - return (data() == obuf->data()); - - return false; -} - - void OSCBuffer::prepare_read(SampleCount nframes) { diff --git a/src/libs/engine/OSCBuffer.hpp b/src/libs/engine/OSCBuffer.hpp index 31371641..b939b764 100644 --- a/src/libs/engine/OSCBuffer.hpp +++ b/src/libs/engine/OSCBuffer.hpp @@ -38,7 +38,6 @@ public: void prepare_read(SampleCount nframes); void prepare_write(SampleCount nframes); - bool is_joined_to(Buffer* buf) const; bool join(Buffer* buf); void unjoin(); @@ -47,14 +46,10 @@ public: uint32_t this_nframes() const { return _this_nframes; } uint32_t event_count() const { return _buf->message_count; } - inline void* raw_data() const - { return ((_joined_buf != NULL) ? _joined_buf->raw_data() : _buf); } - - inline LV2OSCBuffer* data() - { return ((_joined_buf != NULL) ? _joined_buf->data() : _buf); } - - inline const LV2OSCBuffer* data() const - { return ((_joined_buf != NULL) ? _joined_buf->data() : _buf); } + inline void* raw_data() { return _buf; } + inline const void* raw_data() const { return _buf; } + inline LV2OSCBuffer* data() { return _buf; } + inline const LV2OSCBuffer* data() const { return _buf; } private: LV2OSCBuffer* const _buf; diff --git a/src/libs/engine/OutputPort.cpp b/src/libs/engine/OutputPort.cpp index 024f6f39..82e23889 100644 --- a/src/libs/engine/OutputPort.cpp +++ b/src/libs/engine/OutputPort.cpp @@ -15,10 +15,13 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "OutputPort.hpp" #include "Buffer.hpp" #include "ProcessContext.hpp" +using namespace std; + namespace Ingen { @@ -26,7 +29,7 @@ void OutputPort::pre_process(ProcessContext& context) { for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_write(context.nframes()); + buffer(i)->prepare_write(context.nframes()); } @@ -34,7 +37,9 @@ void OutputPort::post_process(ProcessContext& context) { for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_read(context.nframes()); + buffer(i)->prepare_read(context.nframes()); + + //cerr << path() << " output post: buffer: " << buffer(0) << endl; broadcast(context); } diff --git a/src/libs/engine/PatchImpl.cpp b/src/libs/engine/PatchImpl.cpp index 9e2becae..7c4e0a65 100644 --- a/src/libs/engine/PatchImpl.cpp +++ b/src/libs/engine/PatchImpl.cpp @@ -142,6 +142,13 @@ PatchImpl::process(ProcessContext& context) return; NodeBase::pre_process(context); + + /*if (_ports) + for (size_t i=0; i < _ports->size(); ++i) + if (_ports->at(i)->is_input() && _ports->at(i)->type() == DataType::MIDI) + cerr << _ports->at(i)->path() << " " + << _ports->at(i)->buffer(0) << " # events: " + << ((MidiBuffer*)_ports->at(i)->buffer(0))->event_count() << endl;*/ /* Run */ if (_engine.process_slaves().size() > 0) diff --git a/src/libs/engine/PortImpl.cpp b/src/libs/engine/PortImpl.cpp index 800ba011..4a17a218 100644 --- a/src/libs/engine/PortImpl.cpp +++ b/src/libs/engine/PortImpl.cpp @@ -157,7 +157,7 @@ void PortImpl::connect_buffers() { for (uint32_t i=0; i < _poly; ++i) - PortImpl::parent_node()->set_port_buffer(i, _index, _buffers->at(i)); + PortImpl::parent_node()->set_port_buffer(i, _index, buffer(i)); } @@ -165,7 +165,7 @@ void PortImpl::clear_buffers() { for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->clear(); + buffer(i)->clear(); } diff --git a/src/libs/engine/PortImpl.hpp b/src/libs/engine/PortImpl.hpp index 93972f58..22e44c05 100644 --- a/src/libs/engine/PortImpl.hpp +++ b/src/libs/engine/PortImpl.hpp @@ -25,6 +25,7 @@ #include "types.hpp" #include "GraphObjectImpl.hpp" #include "interface/DataType.hpp" +#include "Buffer.hpp" namespace Raul { class Maid; } @@ -69,7 +70,15 @@ public: virtual Raul::Atom value() const; - Buffer* buffer(uint32_t voice) const { return _buffers->at(voice); } + inline Buffer* buffer(uint32_t voice) const { + Buffer* const buf = _buffers->at(voice); + if (buf->is_joined()) { + assert(buf->joined_buffer()); + return buf->joined_buffer(); + } else { + return buf; + } + } /** Called once per process cycle */ virtual void pre_process(ProcessContext& context) = 0; -- cgit v1.2.1