diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/engine/AudioBuffer.cpp | 2 | ||||
-rw-r--r-- | src/libs/engine/Connection.cpp | 32 | ||||
-rw-r--r-- | src/libs/engine/events/ConnectionEvent.cpp | 8 |
3 files changed, 27 insertions, 15 deletions
diff --git a/src/libs/engine/AudioBuffer.cpp b/src/libs/engine/AudioBuffer.cpp index 35987942..1e865dbe 100644 --- a/src/libs/engine/AudioBuffer.cpp +++ b/src/libs/engine/AudioBuffer.cpp @@ -233,7 +233,7 @@ AudioBuffer::join(Buffer* buf) if (!abuf) return false; - assert(abuf->size() == _size); + assert(abuf->size() >= _size); _joined_buf = abuf; _filled_size = abuf->filled_size(); diff --git a/src/libs/engine/Connection.cpp b/src/libs/engine/Connection.cpp index 992496c2..6ae293c4 100644 --- a/src/libs/engine/Connection.cpp +++ b/src/libs/engine/Connection.cpp @@ -15,6 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <algorithm> #include "Connection.h" #include "util.h" #include "Node.h" @@ -35,7 +36,8 @@ Connection::Connection(Port* src_port, Port* dst_port) , _dst_port(dst_port) , _local_buffer(NULL) , _buffer_size(dst_port->buffer_size()) - , _must_mix(src_port->poly() != dst_port->poly()) + , _must_mix( (src_port->poly() != dst_port->poly()) + || (src_port->buffer(0)->size() < dst_port->buffer(0)->size()) ) , _pending_disconnection(false) { assert(src_port); @@ -88,17 +90,35 @@ Connection::process(SampleCount nframes, FrameTime start, FrameTime end) if (_must_mix) { assert(type() == DataType::FLOAT); - AudioBuffer* mix_buf = (AudioBuffer*)_local_buffer; + const AudioBuffer* const src_buffer = (AudioBuffer*)src_port()->buffer(0); + AudioBuffer* mix_buf = (AudioBuffer*)_local_buffer; + + const size_t copy_size = std::min(src_buffer->size(), mix_buf->size()); //cerr << "Mixing " << src_port()->buffer(0)->data() // << " -> " << _local_buffer->data() << endl; - mix_buf->copy((AudioBuffer*)src_port()->buffer(0), 0, _buffer_size-1); + // Copy src buffer to start of mix buffer + mix_buf->copy((AudioBuffer*)src_port()->buffer(0), 0, copy_size-1); + + // Write last value of src buffer to remainder of dst buffer, if necessary + if (copy_size < mix_buf->size()) + mix_buf->set(src_buffer->value_at(copy_size-1), copy_size, mix_buf->size()-1); - // Mix all the source's voices down into local buffer starting at the second + // Accumulate the source's voices into local buffer starting at the second // voice (buffer is already set to first voice above) - for (size_t j=1; j < src_port()->poly(); ++j) - mix_buf->accumulate((AudioBuffer*)src_port()->buffer(j), 0, _buffer_size-1); + for (size_t j=1; j < src_port()->poly(); ++j) { + mix_buf->accumulate((AudioBuffer*)src_port()->buffer(j), 0, copy_size-1); + } + + // Find the summed value and write it to the remainder of dst buffer + if (copy_size < mix_buf->size()) { + float src_value = src_buffer->value_at(copy_size-1); + for (size_t j=1; j < src_port()->poly(); ++j) + src_value += ((AudioBuffer*)src_port()->buffer(j))->value_at(copy_size-1); + + mix_buf->set(src_value, copy_size, mix_buf->size()-1); + } // Scale the buffer down. if (src_port()->poly() > 1) diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp index dc4033cc..8952e281 100644 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ b/src/libs/engine/events/ConnectionEvent.cpp @@ -76,14 +76,6 @@ ConnectionEvent::pre_process() return; } - // FIXME: MIDI buffer size is a kluge all around - if (_src_port->type() == DataType::FLOAT - && _src_port->buffer_size() != _dst_port->buffer_size()) { - _error = TYPE_MISMATCH; - QueuedEvent::pre_process(); - return; - } - _dst_input_port = dynamic_cast<InputPort*>(_dst_port); _src_output_port = dynamic_cast<OutputPort*>(_src_port); |