From 46e5de590817756b21a7a5d99bd4963df343f455 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Feb 2010 21:52:36 +0000 Subject: Heavy overhaul of buffer management and polyphony. * Working polyphony when nodes are instantiated at desired polyphony level (dynamic still doesn't work) * Use shared silent buffer for disconnected audio inputs (save memory) * Eliminate redundant patch compiling on delete and disconnect-all events that have child events * Fix a ton of crash bugs and other issues I've since forgotten git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2468 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/events/Connect.cpp | 25 ++++++++- src/engine/events/Connect.hpp | 4 +- src/engine/events/CreateNode.cpp | 17 ++++-- src/engine/events/CreateNode.hpp | 1 - src/engine/events/CreatePatch.cpp | 15 +++-- src/engine/events/CreatePort.cpp | 10 +++- src/engine/events/Delete.cpp | 24 ++++---- src/engine/events/Disconnect.cpp | 81 +++++++++++++++++---------- src/engine/events/Disconnect.hpp | 18 +++--- src/engine/events/DisconnectAll.cpp | 23 ++++++-- src/engine/events/DisconnectAll.hpp | 10 ++-- src/engine/events/SetMetadata.cpp | 108 +++++++++++++++++++++--------------- src/engine/events/SetPortValue.cpp | 2 +- 13 files changed, 208 insertions(+), 130 deletions(-) (limited to 'src/engine/events') diff --git a/src/engine/events/Connect.cpp b/src/engine/events/Connect.cpp index 1654645c..cc870c04 100644 --- a/src/engine/events/Connect.cpp +++ b/src/engine/events/Connect.cpp @@ -22,12 +22,14 @@ #include "ClientBroadcaster.hpp" #include "Connect.hpp" #include "ConnectionImpl.hpp" +#include "DuplexPort.hpp" #include "Engine.hpp" -#include "InputPort.hpp" #include "EngineStore.hpp" +#include "InputPort.hpp" #include "OutputPort.hpp" #include "PatchImpl.hpp" #include "PortImpl.hpp" +#include "ProcessContext.hpp" #include "Request.hpp" #include "types.hpp" @@ -50,6 +52,7 @@ Connect::Connect(Engine& engine, SharedPtr request, SampleCount timesta , _compiled_patch(NULL) , _patch_listnode(NULL) , _port_listnode(NULL) + , _buffers(NULL) , _error(NO_ERROR) { } @@ -157,6 +160,18 @@ Connect::pre_process() } _patch->add_connection(_patch_listnode); + _dst_input_port->increment_num_connections(); + + switch (_dst_input_port->num_connections()) { + case 1: + _connection->allocate_buffer(*_engine.buffer_factory()); + break; + case 2: + _buffers = new Raul::Array(_dst_input_port->poly()); + _dst_input_port->get_buffers(*_engine.buffer_factory(), _buffers, _dst_input_port->poly()); + default: + break; + } if (_patch->enabled()) _compiled_patch = _patch->compile(); @@ -173,8 +188,12 @@ Connect::execute(ProcessContext& context) if (_error == NO_ERROR) { // This must be inserted here, since they're actually used by the audio thread _dst_input_port->add_connection(_port_listnode); - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); + if (_buffers) + _engine.maid()->push(_dst_input_port->set_buffers(_buffers)); + else + _dst_input_port->setup_buffers(*_engine.buffer_factory(), _dst_input_port->poly()); + _dst_input_port->connect_buffers(); + _engine.maid()->push(_patch->compiled_patch()); _patch->compiled_patch(_compiled_patch); } } diff --git a/src/engine/events/Connect.hpp b/src/engine/events/Connect.hpp index 7f88d160..116ea892 100644 --- a/src/engine/events/Connect.hpp +++ b/src/engine/events/Connect.hpp @@ -34,7 +34,6 @@ namespace Ingen { class PatchImpl; class NodeImpl; class ConnectionImpl; -class MidiMessage; class PortImpl; class InputPort; class OutputPort; @@ -57,7 +56,6 @@ public: void post_process(); private: - enum ErrorType { NO_ERROR, PARENT_PATCH_DIFFERENT, @@ -83,6 +81,8 @@ private: PatchImpl::Connections::Node* _patch_listnode; InputPort::Connections::Node* _port_listnode; + Raul::Array* _buffers; + ErrorType _error; }; diff --git a/src/engine/events/CreateNode.cpp b/src/engine/events/CreateNode.cpp index 4f5b4877..37adda6b 100644 --- a/src/engine/events/CreateNode.cpp +++ b/src/engine/events/CreateNode.cpp @@ -19,6 +19,7 @@ #include "raul/Path.hpp" #include "raul/Path.hpp" #include "redlandmm/World.hpp" +#include "shared/LV2URIMap.hpp" #include "CreateNode.hpp" #include "Request.hpp" #include "PatchImpl.hpp" @@ -46,12 +47,11 @@ CreateNode::CreateNode( SampleCount timestamp, const Path& path, const URI& plugin_uri, - bool polyphonic, const Resource::Properties& properties) : QueuedEvent(engine, request, timestamp) , _path(path) , _plugin_uri(plugin_uri) - , _polyphonic(polyphonic) + , _polyphonic(false) , _patch(NULL) , _plugin(NULL) , _node(NULL) @@ -69,6 +69,12 @@ CreateNode::CreateNode( _plugin_label = uri.substr(colon + 1); uri = ""; } + + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + const Resource::Properties::const_iterator p = properties.find(uris.ingen_polyphonic); + if (p != properties.end() && p->second.type() == Raul::Atom::BOOL + && p->second.get_bool()) + _polyphonic = true; } @@ -93,7 +99,7 @@ CreateNode::pre_process() if (_node != NULL) { _node->properties().insert(_properties.begin(), _properties.end()); - _node->activate(); + _node->activate(*_engine.buffer_factory()); // This can be done here because the audio thread doesn't touch the // node tree - just the process order array @@ -116,9 +122,8 @@ CreateNode::execute(ProcessContext& context) { QueuedEvent::execute(context); - if (_node != NULL) { - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); + if (_node) { + _engine.maid()->push(_patch->compiled_patch()); _patch->compiled_patch(_compiled_patch); } } diff --git a/src/engine/events/CreateNode.hpp b/src/engine/events/CreateNode.hpp index 4bb7e0b5..4c1b1238 100644 --- a/src/engine/events/CreateNode.hpp +++ b/src/engine/events/CreateNode.hpp @@ -45,7 +45,6 @@ public: SampleCount timestamp, const Raul::Path& node_path, const Raul::URI& plugin_uri, - bool poly, const Shared::Resource::Properties& properties); void pre_process(); diff --git a/src/engine/events/CreatePatch.cpp b/src/engine/events/CreatePatch.cpp index c90e2c17..f832c9fe 100644 --- a/src/engine/events/CreatePatch.cpp +++ b/src/engine/events/CreatePatch.cpp @@ -81,13 +81,13 @@ CreatePatch::pre_process() } uint32_t poly = 1; - if (_parent != NULL && _poly > 1 && _poly == static_cast(_parent->internal_polyphony())) + if (_parent != NULL && _poly > 1 && _poly == static_cast(_parent->internal_poly())) poly = _poly; const LV2URIMap& uris = *_engine.world()->uris.get(); _patch = new PatchImpl(_engine, path.symbol(), poly, _parent, - _engine.driver()->sample_rate(), _engine.driver()->buffer_size(), _poly); + _engine.driver()->sample_rate(), _poly); _patch->meta().properties().insert(_properties.begin(), _properties.end()); _patch->meta().set_property(uris.rdf_type, uris.ingen_Patch); _patch->set_property(uris.rdf_type, uris.ingen_Node); @@ -99,7 +99,7 @@ CreatePatch::pre_process() _compiled_patch = _parent->compile(); } - _patch->activate(); + _patch->activate(*_engine.buffer_factory()); // Insert into EngineStore //_patch->add_to_store(_engine.engine_store()); @@ -114,16 +114,15 @@ CreatePatch::execute(ProcessContext& context) { QueuedEvent::execute(context); - if (_patch != NULL) { - if (_parent == NULL) { + if (_patch) { + if (!_parent) { assert(_path.is_root()); assert(_patch->parent_patch() == NULL); _engine.driver()->set_root_patch(_patch); } else { - assert(_parent != NULL); + assert(_parent); assert(!_path.is_root()); - if (_parent->compiled_patch() != NULL) - _engine.maid()->push(_parent->compiled_patch()); + _engine.maid()->push(_parent->compiled_patch()); _parent->compiled_patch(_compiled_patch); } } diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp index d2953c86..33a7f810 100644 --- a/src/engine/events/CreatePort.cpp +++ b/src/engine/events/CreatePort.cpp @@ -90,7 +90,7 @@ CreatePort::pre_process() if (_patch != NULL) { assert(_patch->path() == _path.parent()); - size_t buffer_size = _engine.driver()->buffer_size(); + size_t buffer_size = _engine.buffer_factory()->default_buffer_size(_data_type); const uint32_t old_num_ports = (_patch->external_ports()) ? _patch->external_ports()->size() @@ -104,7 +104,11 @@ CreatePort::pre_process() return; } - _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(), _data_type, buffer_size, _is_output); + Shared::Resource::Properties::const_iterator poly_i = _properties.find(uris.ingen_polyphonic); + bool polyphonic = (poly_i != _properties.end() && poly_i->second.type() == Atom::BOOL + && poly_i->second.get_bool()); + + _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(), _data_type, buffer_size, _is_output, polyphonic); if (_patch->parent()) _patch_port->set_property(uris.rdf_instanceOf, _patch_port->meta_uri()); @@ -121,7 +125,7 @@ CreatePort::pre_process() _patch->add_input(new Raul::List::Node(_patch_port)); if (_patch->external_ports()) - _ports_array = new Raul::Array(old_num_ports + 1, *_patch->external_ports()); + _ports_array = new Raul::Array(old_num_ports + 1, *_patch->external_ports(), NULL); else _ports_array = new Raul::Array(old_num_ports + 1, NULL); diff --git a/src/engine/events/Delete.cpp b/src/engine/events/Delete.cpp index 27f1b995..31e249f5 100644 --- a/src/engine/events/Delete.cpp +++ b/src/engine/events/Delete.cpp @@ -132,16 +132,15 @@ Delete::execute(ProcessContext& context) { QueuedEvent::execute(context); + PatchImpl* parent_patch = NULL; + if (_patch_node_listnode) { assert(_node); if (_disconnect_event) _disconnect_event->execute(context); - if (_node->parent_patch()->compiled_patch()) - _engine.maid()->push(_node->parent_patch()->compiled_patch()); - - _node->parent_patch()->compiled_patch(_compiled_patch); + parent_patch = _node->parent_patch(); } else if (_patch_port_listnode) { assert(_port); @@ -149,14 +148,9 @@ Delete::execute(ProcessContext& context) if (_disconnect_event) _disconnect_event->execute(context); - if (_port->parent_patch()->compiled_patch()) - _engine.maid()->push(_port->parent_patch()->compiled_patch()); - - _port->parent_patch()->compiled_patch(_compiled_patch); - - if (_port->parent_patch()->external_ports()) - _engine.maid()->push(_port->parent_patch()->external_ports()); + parent_patch = _port->parent_patch(); + _engine.maid()->push(_port->parent_patch()->external_ports()); _port->parent_patch()->external_ports(_ports_array); if ( ! _port->parent_patch()->parent()) { @@ -164,6 +158,11 @@ Delete::execute(ProcessContext& context) } } + if (parent_patch) { + _engine.maid()->push(parent_patch->compiled_patch()); + parent_patch->compiled_patch(_compiled_patch); + } + _request->unblock(); } @@ -174,7 +173,8 @@ Delete::post_process() _removed_bindings.reset(); if (_path.is_root() || _path == "path:/control_in" || _path == "path:/control_out") { - _request->respond_error(_path.chop_scheme() + " can not be deleted"); + // XXX: Just ignore? + //_request->respond_error(_path.chop_scheme() + " can not be deleted"); } else if (!_node && !_port) { string msg = string("Could not find object ") + _path.chop_scheme() + " to delete"; _request->respond_error(msg); diff --git a/src/engine/events/Disconnect.cpp b/src/engine/events/Disconnect.cpp index d1cfefe6..7454959e 100644 --- a/src/engine/events/Disconnect.cpp +++ b/src/engine/events/Disconnect.cpp @@ -19,15 +19,18 @@ #include "raul/Maid.hpp" #include "raul/Path.hpp" #include "events/Disconnect.hpp" -#include "Request.hpp" -#include "Engine.hpp" +#include "AudioBuffer.hpp" +#include "ClientBroadcaster.hpp" #include "ConnectionImpl.hpp" +#include "DuplexPort.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" #include "InputPort.hpp" #include "OutputPort.hpp" #include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" #include "PortImpl.hpp" -#include "EngineStore.hpp" +#include "ProcessContext.hpp" +#include "Request.hpp" using namespace std; using namespace Raul; @@ -48,10 +51,13 @@ Disconnect::Disconnect( , _patch(NULL) , _src_port(NULL) , _dst_port(NULL) - , _lookup(true) , _patch_connection(NULL) , _compiled_patch(NULL) + , _buffers(NULL) , _error(NO_ERROR) + , _internal(false) + , _reconnect_dst_port(true) + , _clear_dst_port(false) { } @@ -61,30 +67,28 @@ Disconnect::Disconnect( SharedPtr request, SampleCount timestamp, PortImpl* const src_port, - PortImpl* const dst_port) + PortImpl* const dst_port, + bool reconnect_dst_port) : QueuedEvent(engine, request, timestamp) , _src_port_path(src_port->path()) , _dst_port_path(dst_port->path()) , _patch(src_port->parent_node()->parent_patch()) , _src_port(src_port) , _dst_port(dst_port) - , _lookup(false) , _compiled_patch(NULL) + , _buffers(NULL) , _error(NO_ERROR) + , _internal(true) + , _reconnect_dst_port(reconnect_dst_port) + , _clear_dst_port(false) { - // FIXME: These break for patch ports.. is that ok? - /*assert(src_port->is_output()); - assert(dst_port->is_input()); - assert(src_port->type() == dst_port->type()); - assert(src_port->parent_node()->parent_patch() - == dst_port->parent_node()->parent_patch()); */ } void Disconnect::pre_process() { - if (_lookup) { + if (!_internal) { if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() && _src_port_path.parent() != _dst_port_path.parent().parent() && _src_port_path.parent().parent() != _dst_port_path.parent()) { @@ -156,8 +160,16 @@ Disconnect::pre_process() } _patch_connection = _patch->remove_connection(_src_port, _dst_port); + _dst_input_port->decrement_num_connections(); - if (_patch->enabled()) + if (_dst_input_port->num_connections() == 0) { + _buffers = new Raul::Array(_dst_input_port->poly()); + _dst_input_port->get_buffers(*_engine.buffer_factory(), _buffers, _dst_input_port->poly()); + _clear_dst_port = true; + } + + + if (!_internal && _patch->enabled()) _compiled_patch = _patch->compile(); QueuedEvent::pre_process(); @@ -171,30 +183,41 @@ Disconnect::execute(ProcessContext& context) if (_error == NO_ERROR) { InputPort::Connections::Node* const port_connection - = _dst_input_port->remove_connection(_src_output_port); + = _dst_input_port->remove_connection(context, _src_output_port); + port_connection->elem()->recycle_buffer(); + if (_reconnect_dst_port) { + if (_buffers) + _engine.maid()->push(_dst_input_port->set_buffers(_buffers)); + else + _dst_input_port->setup_buffers(*_engine.buffer_factory(), _dst_input_port->poly()); + _dst_input_port->connect_buffers(); + if (_clear_dst_port) { + for (uint32_t v = 0; v < _dst_input_port->poly(); ++v) { + if (_dst_input_port->type() == PortType::CONTROL) { + PtrCast(_dst_input_port->buffer(v))->set_value( + _dst_input_port->value().get_float(), + context.start(), context.start()); + } else { + _dst_input_port->buffer(v)->clear(); + } + } + } + } else { + _dst_input_port->recycle_buffers(); + } if (port_connection != NULL) { assert(_patch_connection); - - if (port_connection->elem() != _patch_connection->elem()) { - error << "Corrupt connections:" << endl - << "\t" << port_connection->elem() << ": " - << port_connection->elem()->src_port_path() - << " -> " << port_connection->elem()->dst_port_path() << endl - << "!=" << endl - << "\t" << _patch_connection->elem() << ": " - << _patch_connection->elem()->src_port_path() - << " -> " << _patch_connection->elem()->dst_port_path() << endl; - } assert(port_connection->elem() == _patch_connection->elem()); // Destroy list node, which will drop reference to connection itself _engine.maid()->push(port_connection); _engine.maid()->push(_patch_connection); - if (_patch->compiled_patch() != NULL) + if (!_internal) { _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); + _patch->compiled_patch(_compiled_patch); + } } else { _error = CONNECTION_NOT_FOUND; } diff --git a/src/engine/events/Disconnect.hpp b/src/engine/events/Disconnect.hpp index 0bba8c7b..92f1bbc8 100644 --- a/src/engine/events/Disconnect.hpp +++ b/src/engine/events/Disconnect.hpp @@ -22,6 +22,7 @@ #include "QueuedEvent.hpp" #include "types.hpp" #include "PatchImpl.hpp" +#include "BufferFactory.hpp" namespace Raul { template class ListNode; @@ -30,13 +31,10 @@ namespace Raul { namespace Ingen { -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; +class CompiledPatch; class InputPort; class OutputPort; -class CompiledPatch; +class PortImpl; namespace Events { @@ -60,7 +58,8 @@ public: SharedPtr request, SampleCount timestamp, PortImpl* const src_port, - PortImpl* const dst_port); + PortImpl* const dst_port, + bool reconnect_dst_port); void pre_process(); void execute(ProcessContext& context); @@ -87,12 +86,15 @@ private: OutputPort* _src_output_port; InputPort* _dst_input_port; - bool _lookup; - PatchImpl::Connections::Node* _patch_connection; CompiledPatch* _compiled_patch; ///< New process order for Patch + Raul::Array* _buffers; + ErrorType _error; + bool _internal; + bool _reconnect_dst_port; + bool _clear_dst_port; }; diff --git a/src/engine/events/DisconnectAll.cpp b/src/engine/events/DisconnectAll.cpp index af577199..56bef36a 100644 --- a/src/engine/events/DisconnectAll.cpp +++ b/src/engine/events/DisconnectAll.cpp @@ -48,8 +48,9 @@ DisconnectAll::DisconnectAll(Engine& engine, SharedPtr request, SampleC , _parent(NULL) , _node(NULL) , _port(NULL) - , _lookup(true) + , _compiled_patch(NULL) , _error(NO_ERROR) + , _deleting(false) { } @@ -63,8 +64,9 @@ DisconnectAll::DisconnectAll(Engine& engine, PatchImpl* parent, GraphObjectImpl* , _parent(parent) , _node(dynamic_cast(object)) , _port(dynamic_cast(object)) - , _lookup(false) + , _compiled_patch(NULL) , _error(NO_ERROR) + , _deleting(true) { } @@ -79,7 +81,7 @@ DisconnectAll::~DisconnectAll() void DisconnectAll::pre_process() { - if (_lookup) { + if (!_deleting) { _parent = _engine.engine_store()->find_patch(_parent_path); if (_parent == NULL) { @@ -113,10 +115,11 @@ DisconnectAll::pre_process() for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); i != _parent->connections().end(); ++i) { ConnectionImpl* c = (ConnectionImpl*)i->get(); + const bool reconnect_input = !_deleting || (c->dst_port()->parent_node() != _node); if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) && !c->pending_disconnection()) { Disconnect* ev = new Disconnect(_engine, - SharedPtr(), _time, c->src_port(), c->dst_port()); + SharedPtr(), _time, c->src_port(), c->dst_port(), reconnect_input); ev->pre_process(); _disconnect_events.push_back(new Raul::List::Node(ev)); c->pending_disconnection(true); @@ -126,9 +129,10 @@ DisconnectAll::pre_process() for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); i != _parent->connections().end(); ++i) { ConnectionImpl* c = (ConnectionImpl*)i->get(); + const bool reconnect_input = !_deleting || (c->dst_port()->parent_node() != _node); if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { Disconnect* ev = new Disconnect(_engine, - SharedPtr(), _time, c->src_port(), c->dst_port()); + SharedPtr(), _time, c->src_port(), c->dst_port(), reconnect_input); ev->pre_process(); _disconnect_events.push_back(new Raul::List::Node(ev)); c->pending_disconnection(true); @@ -136,6 +140,9 @@ DisconnectAll::pre_process() } } + if (!_deleting && _parent->enabled()) + _compiled_patch = _parent->compile(); + QueuedEvent::pre_process(); } @@ -146,9 +153,13 @@ DisconnectAll::execute(ProcessContext& context) QueuedEvent::execute(context); if (_error == NO_ERROR) { - for (Raul::List::iterator i = _disconnect_events.begin(); i != _disconnect_events.end(); ++i) + for (Raul::List::iterator i = _disconnect_events.begin(); + i != _disconnect_events.end(); ++i) (*i)->execute(context); } + + _engine.maid()->push(_parent->compiled_patch()); + _parent->compiled_patch(_compiled_patch); } diff --git a/src/engine/events/DisconnectAll.hpp b/src/engine/events/DisconnectAll.hpp index 300f3213..47f5576a 100644 --- a/src/engine/events/DisconnectAll.hpp +++ b/src/engine/events/DisconnectAll.hpp @@ -24,12 +24,10 @@ namespace Ingen { -class PatchImpl; +class CompiledPatch; class NodeImpl; -class Connection; +class PatchImpl; class PortImpl; -class InputPort; -class OutputPort; namespace Events { @@ -76,10 +74,10 @@ private: PortImpl* _port; Raul::List _disconnect_events; - bool _lookup; - bool _disconnect_parent; + CompiledPatch* _compiled_patch; ///< New process order for Patch ErrorType _error; + bool _deleting; }; diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp index cc3eb61f..70463aa6 100644 --- a/src/engine/events/SetMetadata.cpp +++ b/src/engine/events/SetMetadata.cpp @@ -18,6 +18,7 @@ #include #include #include "raul/log.hpp" +#include "raul/Maid.hpp" #include "interface/PortType.hpp" #include "shared/LV2URIMap.hpp" #include "ClientBroadcaster.hpp" @@ -68,19 +69,19 @@ SetMetadata::SetMetadata( , _create(create) , _is_meta(meta) { -#if 0 - LOG(debug) << "Set " << subject << " {" << endl; + /* + LOG(info) << "Set " << subject << " {" << endl; typedef Resource::Properties::const_iterator iterator; for (iterator i = properties.begin(); i != properties.end(); ++i) - LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; - LOG(debug) << "}" << endl; + LOG(info) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; + LOG(info) << "}" << endl; - LOG(debug) << "Unset " << subject << " {" << endl; + LOG(info) << "Unset " << subject << " {" << endl; typedef Resource::Properties::const_iterator iterator; for (iterator i = remove.begin(); i != remove.end(); ++i) - LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; - LOG(debug) << "}" << endl; -#endif + LOG(info) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; + LOG(info) << "}" << endl; + */ } @@ -131,7 +132,7 @@ SetMetadata::pre_process() } else if (is_node) { const iterator p = _properties.find(uris.rdf_instanceOf); _create_event = new CreateNode(_engine, sub_request, _time, - path, p->second.get_uri(), true, _properties); + path, p->second.get_uri(), _properties); } else if (is_port) { _blocking = bool(_request); _create_event = new CreatePort(_engine, sub_request, _time, @@ -159,6 +160,18 @@ SetMetadata::pre_process() obj->properties().erase(p->first); #endif + for (Properties::const_iterator p = _remove.begin(); p != _remove.end(); ++p) { + const Raul::URI& key = p->first; + const Raul::Atom& value = p->second; + if (key == uris.ingen_controlBinding && value == uris.wildcard) { + PortImpl* port = dynamic_cast(_object); + if (port) + _old_bindings = _engine.control_bindings()->remove(port); + } + _object->remove_property(key, value); + } + + for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) { const Raul::URI& key = p->first; const Raul::Atom& value = p->second; @@ -176,17 +189,11 @@ SetMetadata::pre_process() _error = BAD_VALUE_TYPE; } } else if (key == uris.ingen_value) { - PortImpl* port = dynamic_cast(_object); - if (port) { - SetPortValue* ev = new SetPortValue(_engine, _request, _time, port, value); - ev->pre_process(); - _set_events.push_back(ev); - } else { - _error = BAD_OBJECT_TYPE; - } + SetPortValue* ev = new SetPortValue(_engine, _request, _time, port, value); + ev->pre_process(); + _set_events.push_back(ev); } else if (key == uris.ingen_controlBinding) { - PortImpl* port = dynamic_cast(_object); - if (port && port->type() == Shared::PortType::CONTROL) { + if (port->type() == Shared::PortType::CONTROL) { if (value == uris.wildcard) { _engine.control_bindings()->learn(port); } else if (value.type() == Atom::DICT) { @@ -202,17 +209,12 @@ SetMetadata::pre_process() if (key == uris.ingen_enabled) { if (value.type() == Atom::BOOL) { op = ENABLE; - if (value.get_bool() && !_patch->compiled_patch()) + // FIXME: defer this until all other metadata has been processed + if (value.get_bool() && !_patch->enabled()) _compiled_patch = _patch->compile(); } else { _error = BAD_VALUE_TYPE; } - } else if (key == uris.ingen_polyphonic) { - if (value.type() == Atom::BOOL) { - op = POLYPHONIC; - } else { - _error = BAD_VALUE_TYPE; - } } else if (key == uris.ingen_polyphony) { if (value.type() == Atom::INT) { op = POLYPHONY; @@ -222,6 +224,27 @@ SetMetadata::pre_process() _error = BAD_VALUE_TYPE; } } + } else if (key == uris.ingen_polyphonic) { + PatchImpl* parent = dynamic_cast(obj->parent()); + if (parent) { + if (value.type() == Atom::BOOL) { + op = POLYPHONIC; + _blocking = true; + obj->set_property(key, value.get_bool()); + NodeBase* node = dynamic_cast(obj); + if (node) + node->set_polyphonic(value.get_bool()); + if (value.get_bool()) { + obj->prepare_poly(*_engine.buffer_factory(), parent->internal_poly()); + } else { + obj->prepare_poly(*_engine.buffer_factory(), 1); + } + } else { + _error = BAD_VALUE_TYPE; + } + } else { + _error = BAD_OBJECT_TYPE; + } } } @@ -233,17 +256,6 @@ SetMetadata::pre_process() _types.push_back(op); } - for (Properties::iterator p = _remove.begin(); p != _remove.end(); ++p) { - const Raul::URI& key = p->first; - const Raul::Atom& value = p->second; - if (key == uris.ingen_controlBinding && value == uris.wildcard) { - PortImpl* port = dynamic_cast(_object); - if (port) - _old_bindings = _engine.control_bindings()->remove(port); - } - _object->remove_property(key, value); - } - QueuedEvent::pre_process(); } @@ -281,21 +293,30 @@ SetMetadata::execute(ProcessContext& context) break; case ENABLE: if (value.get_bool()) { - if (!_patch->compiled_patch()) + if (_compiled_patch) { + _engine.maid()->push(_patch->compiled_patch()); _patch->compiled_patch(_compiled_patch); + } _patch->enable(); } else { _patch->disable(); } break; case POLYPHONIC: - if (object) - if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) - _error = INTERNAL; + { + PatchImpl* parent = reinterpret_cast(object->parent()); + if (value.get_bool()) + object->apply_poly(*_engine.maid(), parent->internal_poly()); + else + object->apply_poly(*_engine.maid(), 1); + } break; case POLYPHONY: - if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) + if (_patch->internal_poly() != static_cast(value.get_int32()) && + !_patch->apply_internal_poly(*_engine.buffer_factory(), + *_engine.maid(), value.get_int32())) { _error = INTERNAL; + } break; case CONTROL_BINDING: if (port) { @@ -311,9 +332,6 @@ SetMetadata::execute(ProcessContext& context) } } - for (Properties::const_iterator p = _remove.begin(); p != _remove.end(); ++p, ++t) - _object->remove_property(p->first, p->second); - QueuedEvent::execute(context); if (_blocking) diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp index a43a37aa..d919814e 100644 --- a/src/engine/events/SetPortValue.cpp +++ b/src/engine/events/SetPortValue.cpp @@ -99,7 +99,7 @@ SetPortValue::pre_process() apply(*_engine.message_context()); _port->parent_node()->set_port_valid(_port->index()); _engine.message_context()->run(_port, - _engine.driver()->frame_time() + _engine.driver()->buffer_size()); + _engine.driver()->frame_time() + _engine.driver()->block_length()); } if (_port) { -- cgit v1.2.1