summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-07-23 20:36:46 +0000
committerDavid Robillard <d@drobilla.net>2007-07-23 20:36:46 +0000
commit54329f21625e52903009a89fc03c8ac966f2724c (patch)
tree592983305e4460f969c70d8fa57ca0d9a9def0af
parent8c417dad8447ea1b45fbe772fd03fd277c4f9ee4 (diff)
downloadingen-54329f21625e52903009a89fc03c8ac966f2724c.tar.gz
ingen-54329f21625e52903009a89fc03c8ac966f2724c.tar.bz2
ingen-54329f21625e52903009a89fc03c8ac966f2724c.zip
Control <-> Audio connections.
git-svn-id: http://svn.drobilla.net/lad/ingen@603 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/engine/AudioBuffer.cpp2
-rw-r--r--src/libs/engine/Connection.cpp32
-rw-r--r--src/libs/engine/events/ConnectionEvent.cpp8
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);