diff options
author | David Robillard <d@drobilla.net> | 2010-02-26 01:39:16 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-02-26 01:39:16 +0000 |
commit | 52e49500bb78974d43bdfd30b2ec9b2a4522dd25 (patch) | |
tree | 44a5a46e946c6b43b657ca5733a165943dd947ae /src/engine/ConnectionImpl.cpp | |
parent | 3d6b047cd19baf9bf5a81b4fe16e1e9e53ed8fef (diff) | |
download | ingen-52e49500bb78974d43bdfd30b2ec9b2a4522dd25.tar.gz ingen-52e49500bb78974d43bdfd30b2ec9b2a4522dd25.tar.bz2 ingen-52e49500bb78974d43bdfd30b2ec9b2a4522dd25.zip |
Perform all mixing for an audio input in a single mix operation (instead of a two step polyphony mixdown (by connections) and connections mixdown (by ports)).
Speed up and inline AudioBuffer::accumulate, to speed up mix().
Remove local buffer from Connection (always mix into destination InputPort's buffers).
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2494 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/ConnectionImpl.cpp')
-rw-r--r-- | src/engine/ConnectionImpl.cpp | 95 |
1 files changed, 15 insertions, 80 deletions
diff --git a/src/engine/ConnectionImpl.cpp b/src/engine/ConnectionImpl.cpp index d3ec6cc7..c6ccf3ba 100644 --- a/src/engine/ConnectionImpl.cpp +++ b/src/engine/ConnectionImpl.cpp @@ -55,9 +55,6 @@ ConnectionImpl::ConnectionImpl(BufferFactory& bufs, PortImpl* src_port, PortImpl assert(src_port != dst_port); assert(src_port->path() != dst_port->path()); - if (must_mix() || must_queue()) - _local_buffer = bufs.get(dst_port->buffer_type(), dst_port->buffer_size(), true); - if (must_queue()) _queue = new Raul::RingBuffer<LV2_Object>(src_port->buffer_size() * 2); } @@ -74,82 +71,23 @@ ConnectionImpl::dump() const void -ConnectionImpl::update_buffer_size(Context& context, BufferFactory& bufs) -{ - if (must_mix() || must_queue()) - allocate_buffer(bufs); -} - - -void -ConnectionImpl::allocate_buffer(BufferFactory& bufs) -{ - if (!_local_buffer) - _local_buffer = bufs.get(_dst_port->buffer_type(), _dst_port->buffer_size()); -} - - -void -ConnectionImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) -{ - ThreadManager::assert_thread(THREAD_PRE_PROCESS); - - assert(_src_port->prepared_poly() == _dst_port->prepared_poly() - || _src_port->prepared_poly() == 1 - || _dst_port->prepared_poly() == 1); - - const bool mix = _src_port->prepared_poly() > _dst_port->prepared_poly(); - if ((mix || must_queue()) && !_local_buffer) - _local_buffer = bufs.get(_dst_port->buffer_type(), _dst_port->buffer(0)->size()); -} - - -void -ConnectionImpl::apply_poly(Raul::Maid& maid, uint32_t poly) +ConnectionImpl::get_sources(Context& context, uint32_t voice, + Buffer** srcs, uint32_t max_num_srcs, uint32_t& num_srcs) { - ThreadManager::assert_thread(THREAD_PROCESS); - - assert(_src_port->poly() == _dst_port->poly() - || _src_port->poly() == 1 - || _dst_port->poly() == 1); - - // Recycle buffer if it's no longer needed - if (!(must_mix() || must_queue())) - _local_buffer = NULL; -} - - -void -ConnectionImpl::process(Context& context) -{ - if (must_queue()) { - IntrusivePtr<EventBuffer> src_buf = PtrCast<EventBuffer>(_src_port->buffer(0)); - if (!src_buf) { - error << "Queued connection but source is not an EventBuffer" << endl; - return; - } - - IntrusivePtr<ObjectBuffer> local_buf = PtrCast<ObjectBuffer>(_local_buffer); - if (!local_buf) { - error << "Queued connection but local buffer is not an ObjectBuffer" << endl; - return; - } - - local_buf->clear(); + if (must_queue()) + return; - if (_queue->read_space()) { - LV2_Object obj; - _queue->full_peek(sizeof(LV2_Object), &obj); - _queue->full_read(sizeof(LV2_Object) + obj.size, local_buf->object()); + if (must_mix()) { + // Mixing down voices: every src voice mixed into every dst voice + for (uint32_t v = 0; v < _src_port->poly(); ++v) { + assert(num_srcs < max_num_srcs); + srcs[num_srcs++] = _src_port->buffer(v).get(); } - - } else if (must_mix()) { - const uint32_t num_srcs = src_port()->poly(); - Buffer* srcs[num_srcs]; - for (uint32_t v = 0; v < num_srcs; ++v) - srcs[v] = src_port()->buffer(v).get(); - - mix(context, _local_buffer.get(), srcs, num_srcs); + } else { + // Matching polyphony: each src voice mixed into corresponding dst voice + assert(_src_port->poly() == _dst_port->poly()); + assert(num_srcs < max_num_srcs); + srcs[num_srcs++] = _src_port->buffer(voice).get(); } } @@ -166,8 +104,7 @@ ConnectionImpl::queue(Context& context) return; } - src_buf->rewind(); - while (src_buf->is_valid()) { + for (src_buf->rewind(); src_buf->is_valid(); src_buf->increment()) { LV2_Event* ev = src_buf->get_event(); LV2_Object* obj = LV2_OBJECT_FROM_EVENT(ev); /*debug << _src_port->path() << " -> " << _dst_port->path() @@ -177,8 +114,6 @@ ConnectionImpl::queue(Context& context) debug << endl;*/ _queue->write(sizeof(LV2_Object) + obj->size, obj); - src_buf->increment(); - context.engine().message_context()->run(_dst_port, context.start() + ev->frames); } } |