From ebbfd9e3cc38106843962bfd56ed6d7f699a59dc Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 3 Jun 2009 03:05:06 +0000 Subject: Clean up input port mixdown code. Make input port connections private, and ensure only touched from the process thread. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2076 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/AudioBuffer.cpp | 8 +++---- src/engine/InputPort.cpp | 57 ++++++++++++++++++++++------------------------ src/engine/InputPort.hpp | 2 -- 3 files changed, 31 insertions(+), 36 deletions(-) (limited to 'src/engine') diff --git a/src/engine/AudioBuffer.cpp b/src/engine/AudioBuffer.cpp index a2ad7e07..86e3800e 100644 --- a/src/engine/AudioBuffer.cpp +++ b/src/engine/AudioBuffer.cpp @@ -80,7 +80,7 @@ AudioBuffer::resize(size_t size) else _data = old_data; - set_block(0, 0, _size-1); + set_block(0, 0, _size - 1); } @@ -98,7 +98,7 @@ AudioBuffer::allocate() _data = _local_data; - set_block(0, 0, _size-1); + clear(); } @@ -119,7 +119,7 @@ AudioBuffer::deallocate() void AudioBuffer::clear() { - set_block(0, 0, _size-1); + set_block(0, 0, _size - 1); _state = OK; _filled_size = 0; } @@ -281,7 +281,7 @@ AudioBuffer::prepare_read(FrameTime start, SampleCount nframes) _state = HALF_SET_CYCLE_2; break; case HALF_SET_CYCLE_2: - set_block(_set_value, 0, _size-1); + set_block(_set_value, 0, _size - 1); _state = OK; break; default: diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index 09132b6e..8d5238e3 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -26,6 +26,7 @@ #include "NodeImpl.hpp" #include "OutputPort.hpp" #include "ProcessContext.hpp" +#include "ThreadManager.hpp" #include "util.hpp" using namespace std; @@ -113,24 +114,25 @@ InputPort::apply_poly(Raul::Maid& maid, uint32_t poly) void InputPort::add_connection(Connections::Node* const c) { - _connections.push_back(c); + assert(ThreadManager::current_thread_id() == THREAD_PROCESS); + + const bool could_direct = can_direct(); - bool modify_buffers = !_fixed_buffers; + _connections.push_back(c); - if (modify_buffers) { + if (!_fixed_buffers) { if (can_direct()) { // Use buffer directly to avoid copying for (uint32_t i=0; i < _poly; ++i) { _buffers->at(i)->join(c->elem()->buffer(i)); } - } else if (_connections.size() == 2) { - // Used to directly use single connection buffer, now there's two - // so have to use local ones again and mix down + } else if (could_direct) { + // Used to directly use single connection's buffer(s), + // but now there's two so use the local ones again and mix down for (uint32_t i=0; i < _poly; ++i) { _buffers->at(i)->unjoin(); } } - PortImpl::connect_buffers(); } // Automatically broadcast connected control inputs @@ -139,17 +141,16 @@ InputPort::add_connection(Connections::Node* const c) } -/** Remove a connection. Realtime safe. - */ +/** Remove a connection. Realtime safe. */ InputPort::Connections::Node* InputPort::remove_connection(const OutputPort* src_port) { - bool modify_buffers = !_fixed_buffers; + assert(ThreadManager::current_thread_id() == THREAD_PROCESS); bool found = false; Connections::Node* connection = NULL; for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) { - if ((*i)->src_port()->path() == src_port->path()) { + if ((*i)->src_port() == src_port) { connection = _connections.erase(i); found = true; } @@ -162,11 +163,11 @@ InputPort::remove_connection(const OutputPort* src_port) if (_connections.size() == 0) { for (uint32_t i=0; i < _poly; ++i) { // Use a local buffer - if (modify_buffers) + if (!_fixed_buffers) _buffers->at(i)->unjoin(); _buffers->at(i)->clear(); // Write silence } - } else if (modify_buffers && _connections.size() == 1 && can_direct()) { + } else if (_connections.size() == 1 && !_fixed_buffers && can_direct()) { // Share a buffer for (uint32_t i=0; i < _poly; ++i) { _buffers->at(i)->join(_connections.front()->buffer(i)); @@ -174,7 +175,7 @@ InputPort::remove_connection(const OutputPort* src_port) } } - if (modify_buffers) + if (!_fixed_buffers) PortImpl::connect_buffers(); // Turn off broadcasting if we're not connected any more (FIXME: not quite right..) @@ -186,7 +187,6 @@ InputPort::remove_connection(const OutputPort* src_port) /** Prepare buffer for access, mixing if necessary. Realtime safe. - * FIXME: nframes parameter not used, */ void InputPort::pre_process(ProcessContext& context) @@ -196,8 +196,7 @@ InputPort::pre_process(ProcessContext& context) if (_set_by_user) return; - bool do_mixdown = true; - + // No connections, just prepare buffers for reading by our node if (_connections.size() == 0) { for (uint32_t i=0; i < _poly; ++i) buffer(i)->prepare_read(context.start(), context.nframes()); @@ -207,20 +206,22 @@ InputPort::pre_process(ProcessContext& context) for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) (*c)->process(context); - if ( ! _fixed_buffers) { - // If only one connection, try to use buffer directly (zero copy) + if (!_fixed_buffers) { + // Single (matching) connection, use buffer(s) directly (zero copy) if (can_direct()) { - do_mixdown = false; - for (uint32_t i=0; i < _poly; ++i) + for (uint32_t i=0; i < _poly; ++i) { _buffers->at(i)->join(_connections.front()->buffer(i)); + _buffers->at(i)->prepare_read(context.start(), context.nframes()); + } + connect_buffers(); + return; } + connect_buffers(); - } else { - do_mixdown = true; } - /*cerr << path() << " poly = " << _poly << ", mixdown: " << do_mixdown - << ", fixed buffers: " << _fixed_buffers << ", joined: " << _buffers->at(0)->is_joined() + /*cerr << path() << " poly = " << _poly << ", fixed buffers: " << _fixed_buffers + << ", joined: " << _buffers->at(0)->is_joined() << " to " << _buffers->at(0)->joined_buffer() << endl;*/ /*if (type() == DataType::EVENT) @@ -230,11 +231,7 @@ InputPort::pre_process(ProcessContext& context) << ((EventBuffer*)buffer(i))->event_count() << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - if (!do_mixdown) { - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - return; - } + // Mix down all incoming connection to buffers if (_type == DataType::CONTROL || _type == DataType::AUDIO) { for (uint32_t voice=0; voice < _poly; ++voice) { diff --git a/src/engine/InputPort.hpp b/src/engine/InputPort.hpp index 9e8db13e..4f27835a 100644 --- a/src/engine/InputPort.hpp +++ b/src/engine/InputPort.hpp @@ -61,8 +61,6 @@ public: void add_connection(Connections::Node* c); Connections::Node* remove_connection(const OutputPort* src_port); - const Connections& connections() { return _connections; } - bool prepare_poly(uint32_t poly); bool apply_poly(Raul::Maid& maid, uint32_t poly); -- cgit v1.2.1