From 6488ffb1a3fedb87b41add3a2a78a953755c949a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 3 Jun 2009 02:30:57 +0000 Subject: Clean up and shave some overhead from port value broadcasting. Clean up duplex port code and document weird semantics. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2075 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/DuplexPort.cpp | 32 ++++++++++++--------------- src/engine/InputPort.cpp | 5 +++-- src/engine/OutputPort.cpp | 3 ++- src/engine/PortImpl.cpp | 31 +++++++++++++------------- src/engine/PortImpl.hpp | 1 - src/engine/events/SetMetadata.cpp | 46 +++++++++++++++++++-------------------- 6 files changed, 57 insertions(+), 61 deletions(-) (limited to 'src/engine') diff --git a/src/engine/DuplexPort.cpp b/src/engine/DuplexPort.cpp index 195d0468..2c4e81b9 100644 --- a/src/engine/DuplexPort.cpp +++ b/src/engine/DuplexPort.cpp @@ -52,30 +52,25 @@ DuplexPort::DuplexPort( } +/** Prepare for the execution of parent patch */ void DuplexPort::pre_process(ProcessContext& context) { - // - /*cerr << endl << "{ duplex pre" << endl; 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 we're a patch output, prepare buffers for write (so plugins can deliver to them) if (_is_output) { - for (uint32_t i=0; i < _poly; ++i) if (!_buffers->at(i)->is_joined()) _buffers->at(i)->prepare_write(context.start(), context.nframes()); + // Otherwise, we're a patch input, do whatever a normal node's input port does + // (mix down inputs from an outside "patch is a node" perspective) } else { - InputPort::pre_process(context); - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_read(context.start(), context.nframes()); - - broadcast(context); } /*if (type() == DataType::EVENT) @@ -84,18 +79,14 @@ DuplexPort::pre_process(ProcessContext& context) << ((EventBuffer*)buffer(i))->event_count() << ", joined: " << _buffers->at(i)->is_joined() << ", is_output: " << _is_output << endl;*/ - //cerr << "} duplex pre " << path() << endl; - - // } +/** Finalize after the execution of parent patch (deliver outputs) */ void DuplexPort::post_process(ProcessContext& context) { - // - /*cerr << endl << "{ duplex post" << endl; cerr << path() << " duplex post: fixed buffers: " << fixed_buffers() << endl; cerr << path() << " duplex post: buffer: " << buffer(0) << endl; @@ -107,14 +98,19 @@ DuplexPort::post_process(ProcessContext& context) << ((EventBuffer*)buffer(i))->event_count() << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ + // If we're a patch output + + if (_is_output) { - InputPort::pre_process(context); // Mix down inputs - broadcast(context); + // Then we've been delivered to as an input (internal perspective) + // Mix down this input so patch output ports (external perspective) are ready + InputPort::pre_process(context); + + if (_broadcast) + broadcast_value(context, false); } //cerr << "} duplex post " << path() << endl; - - // } diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index c42de5c6..09132b6e 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -263,14 +263,15 @@ InputPort::pre_process(ProcessContext& context) for (uint32_t i=0; i < _poly; ++i) buffer(i)->prepare_read(context.start(), context.nframes()); + + if (_broadcast) + broadcast_value(context, false); } void InputPort::post_process(ProcessContext& context) { - broadcast(context); - // Prepare buffers for next cycle if (!can_direct()) for (uint32_t i=0; i < _poly; ++i) diff --git a/src/engine/OutputPort.cpp b/src/engine/OutputPort.cpp index 020ea6bb..023d5a21 100644 --- a/src/engine/OutputPort.cpp +++ b/src/engine/OutputPort.cpp @@ -62,7 +62,8 @@ OutputPort::post_process(ProcessContext& context) //cerr << path() << " output post: buffer: " << buffer(0) << endl; - broadcast(context); + if (_broadcast) + broadcast_value(context, false); } diff --git a/src/engine/PortImpl.cpp b/src/engine/PortImpl.cpp index 6b0bfcad..05fcfe67 100644 --- a/src/engine/PortImpl.cpp +++ b/src/engine/PortImpl.cpp @@ -177,29 +177,28 @@ PortImpl::clear_buffers() void PortImpl::broadcast_value(ProcessContext& context, bool force) { - if (_type == DataType::CONTROL || _type == DataType::AUDIO) { - const Sample value = ((AudioBuffer*)buffer(0))->value_at(0); - if (force || value != _last_broadcasted_value) { - const Events::SendPortValue ev(context.engine(), context.start(), this, false, 0, value); - context.event_sink().write(sizeof(ev), &ev); - _last_broadcasted_value = value; + switch (_type.symbol()) { + case DataType::UNKNOWN: + break; + case DataType::AUDIO: + case DataType::CONTROL: + { + const Sample val = ((AudioBuffer*)buffer(0))->value_at(0); + if (force || val != _last_broadcasted_value) { + _last_broadcasted_value = val; + const Events::SendPortValue ev(context.engine(), context.start(), this, false, 0, val); + context.event_sink().write(sizeof(ev), &ev); + } } - } else if (_type == DataType::EVENT) { + break; + case DataType::EVENT: if (((EventBuffer*)buffer(0))->event_count() > 0) { const Events::SendPortActivity ev(context.engine(), context.start(), this); context.event_sink().write(sizeof(ev), &ev); } + break; } } -void -PortImpl::broadcast(ProcessContext& context) -{ - if (_broadcast) - broadcast_value(context); -} - - - } // namespace Ingen diff --git a/src/engine/PortImpl.hpp b/src/engine/PortImpl.hpp index d58e2b7d..986e8233 100644 --- a/src/engine/PortImpl.hpp +++ b/src/engine/PortImpl.hpp @@ -130,7 +130,6 @@ protected: virtual void allocate_buffers(); virtual void connect_buffers(); - virtual void broadcast(ProcessContext& context); uint32_t _index; uint32_t _poly; diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp index bc73e793..e991bcf5 100644 --- a/src/engine/events/SetMetadata.cpp +++ b/src/engine/events/SetMetadata.cpp @@ -185,30 +185,30 @@ SetMetadata::execute(ProcessContext& context) PortImpl* port = 0; GraphObjectImpl* object = 0; switch (*t) { - case ENABLE_BROADCAST: - if ((port = dynamic_cast(_object))) - port->broadcast(value.get_bool()); - break; - case ENABLE: - if (value.get_bool()) { - if (!_patch->compiled_patch()) - _patch->compiled_patch(_compiled_patch); - _patch->enable(); - } else { - _patch->disable(); - } - break; - case POLYPHONIC: - if ((object = dynamic_cast(_object))) - if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) - _error = INTERNAL; - break; - case POLYPHONY: - if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) + case ENABLE_BROADCAST: + if ((port = dynamic_cast(_object))) + port->broadcast(value.get_bool()); + break; + case ENABLE: + if (value.get_bool()) { + if (!_patch->compiled_patch()) + _patch->compiled_patch(_compiled_patch); + _patch->enable(); + } else { + _patch->disable(); + } + break; + case POLYPHONIC: + if ((object = dynamic_cast(_object))) + if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) _error = INTERNAL; - break; - default: - _success = true; + break; + case POLYPHONY: + if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) + _error = INTERNAL; + break; + default: + _success = true; } } -- cgit v1.2.1