From 317627ef40f7654c298aa1ac707851c852259e3a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 18 Aug 2012 23:05:06 +0000 Subject: Node => Block git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4720 a436a847-0d15-0410-975c-d299462d15a1 --- src/Resource.cpp | 16 +- src/URIs.cpp | 8 +- src/client/BlockModel.cpp | 270 +++++++++++++++++++++ src/client/ClientStore.cpp | 16 +- src/client/NodeModel.cpp | 270 --------------------- src/client/PatchModel.cpp | 18 +- src/client/PluginModel.cpp | 10 +- src/client/PluginUI.cpp | 26 +- src/client/PortModel.cpp | 2 +- src/client/wscript | 2 +- src/gui/App.cpp | 2 +- src/gui/LoadPatchWindow.cpp | 2 +- src/gui/LoadPluginWindow.cpp | 36 +-- src/gui/LoadPluginWindow.hpp | 2 +- src/gui/NewSubpatchWindow.cpp | 2 +- src/gui/NodeMenu.cpp | 26 +- src/gui/NodeMenu.hpp | 4 +- src/gui/NodeModule.cpp | 99 ++++---- src/gui/NodeModule.hpp | 22 +- src/gui/PatchBox.cpp | 14 +- src/gui/PatchCanvas.cpp | 42 ++-- src/gui/PatchCanvas.hpp | 4 +- src/gui/PatchPortModule.cpp | 2 +- src/gui/PatchPortModule.hpp | 1 - src/gui/PatchView.cpp | 4 +- src/gui/Port.cpp | 18 +- src/gui/PortMenu.cpp | 28 +-- src/gui/PortPropertiesWindow.cpp | 4 +- src/gui/PropertiesWindow.cpp | 2 +- src/gui/PropertiesWindow.hpp | 2 +- src/gui/SubpatchModule.cpp | 6 +- src/gui/SubpatchModule.hpp | 3 +- src/gui/WindowFactory.cpp | 6 +- src/gui/WindowFactory.hpp | 6 +- src/serialisation/Parser.cpp | 71 +++--- src/serialisation/Serialiser.cpp | 118 ++++----- src/server/BlockFactory.cpp | 134 +++++++++++ src/server/BlockFactory.hpp | 63 +++++ src/server/BlockImpl.cpp | 187 ++++++++++++++ src/server/BlockImpl.hpp | 175 ++++++++++++++ src/server/Broadcaster.cpp | 10 +- src/server/Broadcaster.hpp | 6 +- src/server/CompiledPatch.hpp | 30 +-- src/server/Driver.hpp | 7 +- src/server/DuplexPort.cpp | 6 +- src/server/DuplexPort.hpp | 6 +- src/server/EdgeImpl.cpp | 8 +- src/server/EdgeImpl.hpp | 2 +- src/server/Engine.cpp | 8 +- src/server/Engine.hpp | 6 +- src/server/GraphObjectImpl.cpp | 2 +- src/server/GraphObjectImpl.hpp | 2 +- src/server/InputPort.cpp | 6 +- src/server/InputPort.hpp | 6 +- src/server/InternalPlugin.cpp | 2 +- src/server/InternalPlugin.hpp | 12 +- src/server/LV2Block.cpp | 469 ++++++++++++++++++++++++++++++++++++ src/server/LV2Block.hpp | 116 +++++++++ src/server/LV2Node.cpp | 469 ------------------------------------ src/server/LV2Node.hpp | 116 --------- src/server/LV2Plugin.cpp | 12 +- src/server/LV2Plugin.hpp | 12 +- src/server/LV2ResizeFeature.hpp | 16 +- src/server/NodeFactory.cpp | 134 ----------- src/server/NodeFactory.hpp | 65 ----- src/server/NodeImpl.cpp | 187 -------------- src/server/NodeImpl.hpp | 175 -------------- src/server/OutputPort.cpp | 4 +- src/server/OutputPort.hpp | 2 +- src/server/PatchImpl.cpp | 68 +++--- src/server/PatchImpl.hpp | 24 +- src/server/PatchPlugin.hpp | 12 +- src/server/PluginImpl.hpp | 18 +- src/server/PortImpl.cpp | 12 +- src/server/PortImpl.hpp | 14 +- src/server/Worker.cpp | 28 +-- src/server/Worker.hpp | 4 +- src/server/events.hpp | 2 +- src/server/events/Connect.cpp | 38 +-- src/server/events/CreateBlock.cpp | 144 +++++++++++ src/server/events/CreateBlock.hpp | 70 ++++++ src/server/events/CreateNode.cpp | 144 ----------- src/server/events/CreateNode.hpp | 70 ------ src/server/events/CreatePatch.cpp | 4 +- src/server/events/Delete.cpp | 22 +- src/server/events/Delete.hpp | 8 +- src/server/events/Delta.cpp | 26 +- src/server/events/Disconnect.cpp | 44 ++-- src/server/events/DisconnectAll.cpp | 20 +- src/server/events/DisconnectAll.hpp | 6 +- src/server/events/Get.cpp | 32 +-- src/server/events/Get.hpp | 4 +- src/server/events/Move.cpp | 2 +- src/server/events/SetPortValue.cpp | 4 +- src/server/ingen_lv2.cpp | 2 +- src/server/internals/Controller.cpp | 6 +- src/server/internals/Controller.hpp | 6 +- src/server/internals/Delay.cpp | 8 +- src/server/internals/Delay.hpp | 4 +- src/server/internals/Note.cpp | 10 +- src/server/internals/Note.hpp | 6 +- src/server/internals/Trigger.cpp | 6 +- src/server/internals/Trigger.hpp | 10 +- src/server/wscript | 8 +- 104 files changed, 2252 insertions(+), 2253 deletions(-) create mode 100644 src/client/BlockModel.cpp delete mode 100644 src/client/NodeModel.cpp create mode 100644 src/server/BlockFactory.cpp create mode 100644 src/server/BlockFactory.hpp create mode 100644 src/server/BlockImpl.cpp create mode 100644 src/server/BlockImpl.hpp create mode 100644 src/server/LV2Block.cpp create mode 100644 src/server/LV2Block.hpp delete mode 100644 src/server/LV2Node.cpp delete mode 100644 src/server/LV2Node.hpp delete mode 100644 src/server/NodeFactory.cpp delete mode 100644 src/server/NodeFactory.hpp delete mode 100644 src/server/NodeImpl.cpp delete mode 100644 src/server/NodeImpl.hpp create mode 100644 src/server/events/CreateBlock.cpp create mode 100644 src/server/events/CreateBlock.hpp delete mode 100644 src/server/events/CreateNode.cpp delete mode 100644 src/server/events/CreateNode.hpp (limited to 'src') diff --git a/src/Resource.cpp b/src/Resource.cpp index 60e79642..a317ff67 100644 --- a/src/Resource.cpp +++ b/src/Resource.cpp @@ -111,14 +111,14 @@ bool Resource::type(const URIs& uris, const Properties& properties, bool& patch, - bool& node, + bool& block, bool& port, bool& is_output) { typedef Resource::Properties::const_iterator iterator; const std::pair types_range = properties.equal_range(uris.rdf_type); - patch = node = port = is_output = false; + patch = block = port = is_output = false; for (iterator i = types_range.first; i != types_range.second; ++i) { const Raul::Atom& atom = i->second; if (atom.type() != uris.forge.URI && atom.type() != uris.forge.URID) { @@ -127,8 +127,8 @@ Resource::type(const URIs& uris, if (atom == uris.ingen_Patch) { patch = true; - } else if (atom == uris.ingen_Node) { - node = true; + } else if (atom == uris.ingen_Block) { + block = true; } else if (atom == uris.lv2_InputPort) { port = true; is_output = false; @@ -138,13 +138,13 @@ Resource::type(const URIs& uris, } } - if (patch && node && !port) { // => patch - node = false; + if (patch && block && !port) { // => patch + block = false; return true; - } else if (port && (patch || node)) { // nonsense + } else if (port && (patch || block)) { // nonsense port = false; return false; - } else if (patch || node || port) { // recognized type + } else if (patch || block || port) { // recognized type return true; } else { // unknown return false; diff --git a/src/URIs.cpp b/src/URIs.cpp index c5564aa7..227b6162 100644 --- a/src/URIs.cpp +++ b/src/URIs.cpp @@ -55,22 +55,23 @@ URIs::URIs(Forge& f, URIMap* map) , atom_eventTransfer (forge, map, LV2_ATOM__eventTransfer) , atom_supports (forge, map, LV2_ATOM__supports) , doap_name (forge, map, "http://usefulinc.com/ns/doap#name") + , ingen_Block (forge, map, NS_INGEN "Block") , ingen_Edge (forge, map, NS_INGEN "Edge") , ingen_Internal (forge, map, NS_INGEN "Internal") - , ingen_Node (forge, map, NS_INGEN "Node") , ingen_Patch (forge, map, NS_INGEN "Patch") , ingen_activity (forge, map, NS_INGEN "activity") + , ingen_block (forge, map, NS_INGEN "block") , ingen_broadcast (forge, map, NS_INGEN "broadcast") , ingen_canvasX (forge, map, NS_INGEN "canvasX") , ingen_canvasY (forge, map, NS_INGEN "canvasY") , ingen_controlBinding (forge, map, NS_INGEN "controlBinding") , ingen_document (forge, map, NS_INGEN "document") + , ingen_edge (forge, map, NS_INGEN "edge") , ingen_enabled (forge, map, NS_INGEN "enabled") , ingen_engine (forge, map, NS_INGEN "engine") , ingen_head (forge, map, NS_INGEN "head") , ingen_incidentTo (forge, map, NS_INGEN "incidentTo") , ingen_nil (forge, map, NS_INGEN "nil") - , ingen_node (forge, map, NS_INGEN "node") , ingen_polyphonic (forge, map, NS_INGEN "polyphonic") , ingen_polyphony (forge, map, NS_INGEN "polyphony") , ingen_prototype (forge, map, NS_INGEN "prototype") @@ -88,13 +89,16 @@ URIs::URIs(Forge& f, URIMap* map) , lv2_InputPort (forge, map, LV2_CORE__InputPort) , lv2_OutputPort (forge, map, LV2_CORE__OutputPort) , lv2_Plugin (forge, map, LV2_CORE__Plugin) + , lv2_binary (forge, map, LV2_CORE__binary) , lv2_connectionOptional(forge, map, LV2_CORE__connectionOptional) , lv2_default (forge, map, LV2_CORE__default) + , lv2_extensionData (forge, map, LV2_CORE__extensionData) , lv2_index (forge, map, LV2_CORE__index) , lv2_integer (forge, map, LV2_CORE__integer) , lv2_maximum (forge, map, LV2_CORE__maximum) , lv2_minimum (forge, map, LV2_CORE__minimum) , lv2_name (forge, map, LV2_CORE__name) + , lv2_port (forge, map, LV2_CORE__port) , lv2_portProperty (forge, map, LV2_CORE__portProperty) , lv2_sampleRate (forge, map, LV2_CORE__sampleRate) , lv2_scalePoint (forge, map, LV2_CORE__scalePoint) diff --git a/src/client/BlockModel.cpp b/src/client/BlockModel.cpp new file mode 100644 index 00000000..865f081c --- /dev/null +++ b/src/client/BlockModel.cpp @@ -0,0 +1,270 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include +#include +#include + +#include "ingen/client/BlockModel.hpp" +#include "ingen/URIs.hpp" +#include "ingen/World.hpp" + +namespace Ingen { +namespace Client { + +BlockModel::BlockModel(URIs& uris, + SharedPtr plugin, + const Raul::Path& path) + : ObjectModel(uris, path) + , _plugin_uri(plugin->uri()) + , _plugin(plugin) + , _num_values(0) + , _min_values(0) + , _max_values(0) +{ +} + +BlockModel::BlockModel(URIs& uris, + const Raul::URI& plugin_uri, + const Raul::Path& path) + : ObjectModel(uris, path) + , _plugin_uri(plugin_uri) + , _num_values(0) + , _min_values(0) + , _max_values(0) +{ +} + +BlockModel::BlockModel(const BlockModel& copy) + : ObjectModel(copy) + , _plugin_uri(copy._plugin_uri) + , _num_values(copy._num_values) + , _min_values((float*)malloc(sizeof(float) * _num_values)) + , _max_values((float*)malloc(sizeof(float) * _num_values)) +{ + memcpy(_min_values, copy._min_values, sizeof(float) * _num_values); + memcpy(_max_values, copy._max_values, sizeof(float) * _num_values); +} + +BlockModel::~BlockModel() +{ + clear(); +} + +void +BlockModel::remove_port(SharedPtr port) +{ + for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { + if ((*i) == port) { + _ports.erase(i); + break; + } + } + _signal_removed_port.emit(port); +} + +void +BlockModel::remove_port(const Raul::Path& port_path) +{ + for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { + if ((*i)->path() == port_path) { + _ports.erase(i); + break; + } + } +} + +void +BlockModel::clear() +{ + _ports.clear(); + assert(_ports.empty()); + delete[] _min_values; + delete[] _max_values; + _min_values = 0; + _max_values = 0; +} + +void +BlockModel::add_child(SharedPtr c) +{ + assert(c->parent().get() == this); + + //ObjectModel::add_child(c); + + SharedPtr pm = PtrCast(c); + assert(pm); + add_port(pm); +} + +bool +BlockModel::remove_child(SharedPtr c) +{ + assert(c->path().is_child_of(path())); + assert(c->parent().get() == this); + + //bool ret = ObjectModel::remove_child(c); + + SharedPtr pm = PtrCast(c); + assert(pm); + remove_port(pm); + + //return ret; + return true; +} + +void +BlockModel::add_port(SharedPtr pm) +{ + assert(pm); + assert(pm->path().is_child_of(path())); + assert(pm->parent().get() == this); + + // Store should have handled this by merging the two + assert(find(_ports.begin(), _ports.end(), pm) == _ports.end()); + + _ports.push_back(pm); + _signal_new_port.emit(pm); +} + +SharedPtr +BlockModel::get_port(const Raul::Symbol& symbol) const +{ + for (Ports::const_iterator i = _ports.begin(); i != _ports.end(); ++i) + if ((*i)->symbol() == symbol) + return (*i); + return SharedPtr(); +} + +Ingen::GraphObject* +BlockModel::port(uint32_t index) const +{ + assert(index < num_ports()); + return const_cast( + dynamic_cast(_ports[index].get())); +} + +void +BlockModel::default_port_value_range(SharedPtr port, + float& min, + float& max, + uint32_t srate) const +{ + // Default control values + min = 0.0; + max = 1.0; + + // Get range from client-side LV2 data + if (_plugin && _plugin->type() == PluginModel::LV2) { + if (!_min_values) { + _num_values = lilv_plugin_get_num_ports(_plugin->lilv_plugin()); + _min_values = new float[_num_values]; + _max_values = new float[_num_values]; + lilv_plugin_get_port_ranges_float(_plugin->lilv_plugin(), + _min_values, _max_values, 0); + } + + if (!std::isnan(_min_values[port->index()])) + min = _min_values[port->index()]; + if (!std::isnan(_max_values[port->index()])) + max = _max_values[port->index()]; + } + + if (port->port_property(_uris.lv2_sampleRate)) { + min *= srate; + max *= srate; + } +} + +void +BlockModel::port_value_range(SharedPtr port, + float& min, float& max, uint32_t srate) const +{ + assert(port->parent().get() == this); + + default_port_value_range(port, min, max); + + // Possibly overriden + const Raul::Atom& min_atom = port->get_property(_uris.lv2_minimum); + const Raul::Atom& max_atom = port->get_property(_uris.lv2_maximum); + if (min_atom.type() == _uris.forge.Float) + min = min_atom.get_float(); + if (max_atom.type() == _uris.forge.Float) + max = max_atom.get_float(); + + if (max <= min) + max = min + 1.0; + + if (port->port_property(_uris.lv2_sampleRate)) { + min *= srate; + max *= srate; + } +} + +std::string +BlockModel::label() const +{ + const Raul::Atom& name_property = get_property(_uris.lv2_name); + if (name_property.type() == _uris.forge.String) { + return name_property.get_string(); + } else if (plugin_model()) { + return plugin_model()->human_name(); + } else { + return symbol().c_str(); + } +} + +std::string +BlockModel::port_label(SharedPtr port) const +{ + const Raul::Atom& name = port->get_property(Raul::URI(LV2_CORE__name)); + if (name.is_valid()) { + return name.get_string(); + } + + if (_plugin && _plugin->type() == PluginModel::LV2) { + LilvWorld* w = _plugin->lilv_world(); + const LilvPlugin* plug = _plugin->lilv_plugin(); + LilvNode* sym = lilv_new_string(w, port->symbol().c_str()); + const LilvPort* lport = lilv_plugin_get_port_by_symbol(plug, sym); + if (lport) { + LilvNode* lname = lilv_port_get_name(plug, lport); + if (lname && lilv_node_is_string(lname)) { + std::string ret(lilv_node_as_string(lname)); + lilv_node_free(lname); + return ret; + } + lilv_node_free(lname); + } + } + + return port->symbol().c_str(); +} + +void +BlockModel::set(SharedPtr model) +{ + SharedPtr block = PtrCast(model); + if (block) { + _plugin_uri = block->_plugin_uri; + _plugin = block->_plugin; + } + + ObjectModel::set(model); +} + +} // namespace Client +} // namespace Ingen diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 7a6f69c1..07b44b84 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -17,7 +17,7 @@ #include "ingen/Log.hpp" #include "ingen/client/ClientStore.hpp" #include "ingen/client/EdgeModel.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/ObjectModel.hpp" #include "ingen/client/PatchModel.hpp" #include "ingen/client/PluginModel.hpp" @@ -223,9 +223,9 @@ ClientStore::put(const Raul::URI& uri, std::cerr << "}" << endl; #endif - bool is_patch, is_node, is_port, is_output; + bool is_patch, is_block, is_port, is_output; Resource::type(uris(), properties, - is_patch, is_node, is_port, is_output); + is_patch, is_block, is_port, is_output); // Check if uri is a plugin Iterator t = properties.find(_uris.rdf_type); @@ -265,7 +265,7 @@ ClientStore::put(const Raul::URI& uri, SharedPtr model(new PatchModel(uris(), path)); model->set_properties(properties); add_object(model); - } else if (is_node) { + } else if (is_block) { const Iterator p = properties.find(_uris.ingen_prototype); SharedPtr plug; if (p->second.is_valid() && p->second.type() == _uris.forge.URI) { @@ -280,11 +280,11 @@ ClientStore::put(const Raul::URI& uri, add_plugin(plug); } - SharedPtr n(new NodeModel(uris(), plug, path)); - n->set_properties(properties); - add_object(n); + SharedPtr bm(new BlockModel(uris(), plug, path)); + bm->set_properties(properties); + add_object(bm); } else { - _log.warn(Raul::fmt("Node %1% has no plugin\n") + _log.warn(Raul::fmt("Block %1% has no plugin\n") % path.c_str()); } } else if (is_port) { diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp deleted file mode 100644 index 06a3320d..00000000 --- a/src/client/NodeModel.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#include -#include -#include - -#include "ingen/client/NodeModel.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" - -namespace Ingen { -namespace Client { - -NodeModel::NodeModel(URIs& uris, - SharedPtr plugin, - const Raul::Path& path) - : ObjectModel(uris, path) - , _plugin_uri(plugin->uri()) - , _plugin(plugin) - , _num_values(0) - , _min_values(0) - , _max_values(0) -{ -} - -NodeModel::NodeModel(URIs& uris, - const Raul::URI& plugin_uri, - const Raul::Path& path) - : ObjectModel(uris, path) - , _plugin_uri(plugin_uri) - , _num_values(0) - , _min_values(0) - , _max_values(0) -{ -} - -NodeModel::NodeModel(const NodeModel& copy) - : ObjectModel(copy) - , _plugin_uri(copy._plugin_uri) - , _num_values(copy._num_values) - , _min_values((float*)malloc(sizeof(float) * _num_values)) - , _max_values((float*)malloc(sizeof(float) * _num_values)) -{ - memcpy(_min_values, copy._min_values, sizeof(float) * _num_values); - memcpy(_max_values, copy._max_values, sizeof(float) * _num_values); -} - -NodeModel::~NodeModel() -{ - clear(); -} - -void -NodeModel::remove_port(SharedPtr port) -{ - for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i) == port) { - _ports.erase(i); - break; - } - } - _signal_removed_port.emit(port); -} - -void -NodeModel::remove_port(const Raul::Path& port_path) -{ - for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i)->path() == port_path) { - _ports.erase(i); - break; - } - } -} - -void -NodeModel::clear() -{ - _ports.clear(); - assert(_ports.empty()); - delete[] _min_values; - delete[] _max_values; - _min_values = 0; - _max_values = 0; -} - -void -NodeModel::add_child(SharedPtr c) -{ - assert(c->parent().get() == this); - - //ObjectModel::add_child(c); - - SharedPtr pm = PtrCast(c); - assert(pm); - add_port(pm); -} - -bool -NodeModel::remove_child(SharedPtr c) -{ - assert(c->path().is_child_of(path())); - assert(c->parent().get() == this); - - //bool ret = ObjectModel::remove_child(c); - - SharedPtr pm = PtrCast(c); - assert(pm); - remove_port(pm); - - //return ret; - return true; -} - -void -NodeModel::add_port(SharedPtr pm) -{ - assert(pm); - assert(pm->path().is_child_of(path())); - assert(pm->parent().get() == this); - - // Store should have handled this by merging the two - assert(find(_ports.begin(), _ports.end(), pm) == _ports.end()); - - _ports.push_back(pm); - _signal_new_port.emit(pm); -} - -SharedPtr -NodeModel::get_port(const Raul::Symbol& symbol) const -{ - for (Ports::const_iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->symbol() == symbol) - return (*i); - return SharedPtr(); -} - -Ingen::GraphObject* -NodeModel::port(uint32_t index) const -{ - assert(index < num_ports()); - return const_cast( - dynamic_cast(_ports[index].get())); -} - -void -NodeModel::default_port_value_range(SharedPtr port, - float& min, - float& max, - uint32_t srate) const -{ - // Default control values - min = 0.0; - max = 1.0; - - // Get range from client-side LV2 data - if (_plugin && _plugin->type() == PluginModel::LV2) { - if (!_min_values) { - _num_values = lilv_plugin_get_num_ports(_plugin->lilv_plugin()); - _min_values = new float[_num_values]; - _max_values = new float[_num_values]; - lilv_plugin_get_port_ranges_float(_plugin->lilv_plugin(), - _min_values, _max_values, 0); - } - - if (!std::isnan(_min_values[port->index()])) - min = _min_values[port->index()]; - if (!std::isnan(_max_values[port->index()])) - max = _max_values[port->index()]; - } - - if (port->port_property(_uris.lv2_sampleRate)) { - min *= srate; - max *= srate; - } -} - -void -NodeModel::port_value_range(SharedPtr port, - float& min, float& max, uint32_t srate) const -{ - assert(port->parent().get() == this); - - default_port_value_range(port, min, max); - - // Possibly overriden - const Raul::Atom& min_atom = port->get_property(_uris.lv2_minimum); - const Raul::Atom& max_atom = port->get_property(_uris.lv2_maximum); - if (min_atom.type() == _uris.forge.Float) - min = min_atom.get_float(); - if (max_atom.type() == _uris.forge.Float) - max = max_atom.get_float(); - - if (max <= min) - max = min + 1.0; - - if (port->port_property(_uris.lv2_sampleRate)) { - min *= srate; - max *= srate; - } -} - -std::string -NodeModel::label() const -{ - const Raul::Atom& name_property = get_property(_uris.lv2_name); - if (name_property.type() == _uris.forge.String) { - return name_property.get_string(); - } else if (plugin_model()) { - return plugin_model()->human_name(); - } else { - return symbol().c_str(); - } -} - -std::string -NodeModel::port_label(SharedPtr port) const -{ - const Raul::Atom& name = port->get_property(Raul::URI(LV2_CORE__name)); - if (name.is_valid()) { - return name.get_string(); - } - - if (_plugin && _plugin->type() == PluginModel::LV2) { - LilvWorld* w = _plugin->lilv_world(); - const LilvPlugin* plug = _plugin->lilv_plugin(); - LilvNode* sym = lilv_new_string(w, port->symbol().c_str()); - const LilvPort* lport = lilv_plugin_get_port_by_symbol(plug, sym); - if (lport) { - LilvNode* lname = lilv_port_get_name(plug, lport); - if (lname && lilv_node_is_string(lname)) { - std::string ret(lilv_node_as_string(lname)); - lilv_node_free(lname); - return ret; - } - lilv_node_free(lname); - } - } - - return port->symbol().c_str(); -} - -void -NodeModel::set(SharedPtr model) -{ - SharedPtr node = PtrCast(model); - if (node) { - _plugin_uri = node->_plugin_uri; - _plugin = node->_plugin; - } - - ObjectModel::set(model); -} - -} // namespace Client -} // namespace Ingen diff --git a/src/client/PatchModel.cpp b/src/client/PatchModel.cpp index 72c17009..9b622cda 100644 --- a/src/client/PatchModel.cpp +++ b/src/client/PatchModel.cpp @@ -18,7 +18,7 @@ #include "ingen/client/ClientStore.hpp" #include "ingen/client/EdgeModel.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PatchModel.hpp" #include "ingen/URIs.hpp" @@ -38,9 +38,10 @@ PatchModel::add_child(SharedPtr c) return; } - SharedPtr nm = PtrCast(c); - if (nm) - _signal_new_node.emit(nm); + SharedPtr bm = PtrCast(c); + if (bm) { + _signal_new_block.emit(bm); + } } bool @@ -72,9 +73,10 @@ PatchModel::remove_child(SharedPtr o) if (pm) remove_port(pm); - SharedPtr nm = PtrCast(o); - if (nm) - _signal_removed_node.emit(nm); + SharedPtr bm = PtrCast(o); + if (bm) { + _signal_removed_block.emit(bm); + } return true; } @@ -84,7 +86,7 @@ PatchModel::clear() { _edges.clear(); - NodeModel::clear(); + BlockModel::clear(); assert(_edges.empty()); assert(_ports.empty()); diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp index 0f422a89..53736a3e 100644 --- a/src/client/PluginModel.cpp +++ b/src/client/PluginModel.cpp @@ -153,7 +153,7 @@ PluginModel::set(SharedPtr p) } Raul::Symbol -PluginModel::default_node_symbol() const +PluginModel::default_block_symbol() const { const Raul::Atom& name_atom = get_property(_uris.lv2_symbol); if (name_atom.is_valid() && name_atom.type() == _uris.forge.String) @@ -169,7 +169,7 @@ PluginModel::human_name() const if (name_atom.type() == _uris.forge.String) return name_atom.get_string(); else - return default_node_symbol().c_str(); + return default_block_symbol().c_str(); } string @@ -215,14 +215,14 @@ PluginModel::has_ui() const } SharedPtr -PluginModel::ui(Ingen::World* world, - SharedPtr node) const +PluginModel::ui(Ingen::World* world, + SharedPtr block) const { if (!_lilv_plugin) { return SharedPtr(); } - return PluginUI::create(world, node, _lilv_plugin); + return PluginUI::create(world, block, _lilv_plugin); } const string& diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp index 2a63296a..7a4c88e8 100644 --- a/src/client/PluginUI.cpp +++ b/src/client/PluginUI.cpp @@ -17,7 +17,7 @@ #include "ingen/Interface.hpp" #include "ingen/Log.hpp" #include "ingen/URIs.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PluginUI.hpp" #include "ingen/client/PortModel.hpp" #include "lv2/lv2plug.in/ns/ext/atom/atom.h" @@ -39,11 +39,11 @@ lv2_ui_write(SuilController controller, { PluginUI* const ui = (PluginUI*)controller; - const NodeModel::Ports& ports = ui->node()->ports(); + const BlockModel::Ports& ports = ui->block()->ports(); if (port_index >= ports.size()) { ui->world()->log().error( Raul::fmt("%1% UI tried to write to invalid port %2%\n") - % ui->node()->plugin()->uri().c_str() % port_index); + % ui->block()->plugin()->uri().c_str() % port_index); return; } @@ -73,15 +73,15 @@ lv2_ui_write(SuilController controller, } else { ui->world()->log().warn( Raul::fmt("Unknown value format %1% from LV2 UI\n") - % format % ui->node()->plugin()->uri().c_str()); + % format % ui->block()->plugin()->uri().c_str()); } } -PluginUI::PluginUI(Ingen::World* world, - SharedPtr node, - const LilvNode* ui_node) +PluginUI::PluginUI(Ingen::World* world, + SharedPtr block, + const LilvNode* ui_node) : _world(world) - , _node(node) + , _block(block) , _instance(NULL) , _ui_node(lilv_node_duplicate(ui_node)) { @@ -94,9 +94,9 @@ PluginUI::~PluginUI() } SharedPtr -PluginUI::create(Ingen::World* world, - SharedPtr node, - const LilvPlugin* plugin) +PluginUI::create(Ingen::World* world, + SharedPtr block, + const LilvPlugin* plugin) { if (!PluginUI::ui_host) { PluginUI::ui_host = suil_host_new(lv2_ui_write, NULL, NULL, NULL); @@ -126,9 +126,9 @@ PluginUI::create(Ingen::World* world, return SharedPtr(); } - SharedPtr ret(new PluginUI(world, node, lilv_ui_get_uri(ui))); + SharedPtr ret(new PluginUI(world, block, lilv_ui_get_uri(ui))); ret->_features = world->lv2_features().lv2_features( - world, const_cast(node.get())); + world, const_cast(block.get())); SuilInstance* instance = suil_instance_new( PluginUI::ui_host, diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp index c2493563..54db0ca1 100644 --- a/src/client/PortModel.cpp +++ b/src/client/PortModel.cpp @@ -14,7 +14,7 @@ along with Ingen. If not, see . */ -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PortModel.hpp" namespace Ingen { diff --git a/src/client/wscript b/src/client/wscript index b0b0620e..c85ee5ab 100644 --- a/src/client/wscript +++ b/src/client/wscript @@ -12,8 +12,8 @@ def build(bld): autowaf.use_lib(bld, obj, 'GLIBMM LV2 LILV SUIL RAUL SORD SIGCPP') obj.source = ''' + BlockModel.cpp ClientStore.cpp - NodeModel.cpp ObjectModel.cpp PatchModel.cpp PluginModel.cpp diff --git a/src/gui/App.cpp b/src/gui/App.cpp index cfba10c7..de35de54 100644 --- a/src/gui/App.cpp +++ b/src/gui/App.cpp @@ -112,7 +112,7 @@ App::create(Ingen::World* world) app->_about_dialog->property_logo_icon_name() = "ingen"; gtk_window_set_default_icon_name("ingen"); - // Set style for embedded node GUIs + // Set style for embedded block GUIs const string rc_style = "style \"ingen_embedded_node_gui_style\" {\n" "bg[NORMAL] = \"#212222\"\n" diff --git a/src/gui/LoadPatchWindow.cpp b/src/gui/LoadPatchWindow.cpp index 57c932af..7ba348a6 100644 --- a/src/gui/LoadPatchWindow.cpp +++ b/src/gui/LoadPatchWindow.cpp @@ -22,8 +22,8 @@ #include #include "ingen/Interface.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/ClientStore.hpp" -#include "ingen/client/NodeModel.hpp" #include "ingen/client/PatchModel.hpp" #include "ingen/runtime_paths.hpp" diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index 69a4f53c..f5f7a7d7 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -50,7 +50,7 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, { xml->get_widget("load_plugin_plugins_treeview", _plugins_treeview); xml->get_widget("load_plugin_polyphonic_checkbutton", _polyphonic_checkbutton); - xml->get_widget("load_plugin_name_entry", _node_name_entry); + xml->get_widget("load_plugin_name_entry", _name_entry); xml->get_widget("load_plugin_add_button", _add_button); xml->get_widget("load_plugin_close_button", _close_button); @@ -98,7 +98,7 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); _search_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::filter_changed)); - _node_name_entry->signal_changed().connect( + _name_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::name_changed)); #ifdef HAVE_NEW_GTKMM @@ -131,7 +131,7 @@ LoadPluginWindow::name_changed() { // Toggle add button sensitivity according name legality if (_selection->get_selected_rows().size() == 1) { - const string sym = _node_name_entry->get_text(); + const string sym = _name_entry->get_text(); if (!Raul::Symbol::is_valid(sym)) { _add_button->property_sensitive() = false; } else if (_app->store()->find(_patch->path().child(Raul::Symbol(sym))) @@ -282,8 +282,8 @@ LoadPluginWindow::plugin_selection_changed() size_t n_selected = _selection->get_selected_rows().size(); if (n_selected == 0) { _name_offset = 0; - _node_name_entry->set_text(""); - _node_name_entry->set_sensitive(false); + _name_entry->set_text(""); + _name_entry->set_sensitive(false); } else if (n_selected == 1) { Gtk::TreeModel::iterator iter = _plugins_liststore->get_iter( *_selection->get_selected_rows().begin()); @@ -292,17 +292,17 @@ LoadPluginWindow::plugin_selection_changed() boost::shared_ptr p = row.get_value( _plugins_columns._col_plugin); _name_offset = _app->store()->child_name_offset( - _patch->path(), p->default_node_symbol()); - _node_name_entry->set_text(generate_module_name(p, _name_offset)); - _node_name_entry->set_sensitive(true); + _patch->path(), p->default_block_symbol()); + _name_entry->set_text(generate_module_name(p, _name_offset)); + _name_entry->set_sensitive(true); } else { _name_offset = 0; - _node_name_entry->set_text(""); - _node_name_entry->set_sensitive(false); + _name_entry->set_text(""); + _name_entry->set_sensitive(false); } } else { - _node_name_entry->set_text(""); - _node_name_entry->set_sensitive(false); + _name_entry->set_text(""); + _name_entry->set_sensitive(false); } } @@ -317,7 +317,7 @@ LoadPluginWindow::generate_module_name(SharedPtr plugin, int offset) { std::stringstream ss; - ss << plugin->default_node_symbol(); + ss << plugin->default_block_symbol(); if (offset != 0) ss << "_" << offset; return ss.str(); @@ -330,14 +330,14 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) Gtk::TreeModel::Row row = *iter; SharedPtr plugin = row.get_value(_plugins_columns._col_plugin); bool polyphonic = _polyphonic_checkbutton->get_active(); - string name = _node_name_entry->get_text(); + string name = _name_entry->get_text(); if (name.empty()) name = generate_module_name(plugin, _name_offset); if (name.empty() || !Raul::Symbol::is_valid(name)) { Gtk::MessageDialog dialog(*this, - "Unable to chose a default name for this node. Please enter a name.", + "Unable to choose a default name, please provide one", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); dialog.run(); @@ -345,7 +345,7 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) Raul::Path path = _patch->path().child(Raul::Symbol::symbolify(name)); Resource::Properties props = _initial_data; props.insert(make_pair(uris.rdf_type, - uris.ingen_Node)); + uris.ingen_Block)); props.insert(make_pair(uris.ingen_prototype, _app->forge().alloc_uri(plugin->uri()))); props.insert(make_pair(uris.ingen_polyphonic, @@ -354,10 +354,10 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) if (_selection->get_selected_rows().size() == 1) { _name_offset = (_name_offset == 0) ? 2 : _name_offset + 1; - _node_name_entry->set_text(generate_module_name(plugin, _name_offset)); + _name_entry->set_text(generate_module_name(plugin, _name_offset)); } - // Cascade next node + // Cascade next block Raul::Atom& x = _initial_data.find(uris.ingen_canvasX)->second; x = _app->forge().make(x.get_float() + 20.0f); Raul::Atom& y = _initial_data.find(uris.ingen_canvasY)->second; diff --git a/src/gui/LoadPluginWindow.hpp b/src/gui/LoadPluginWindow.hpp index 081bc6cc..e9b874a2 100644 --- a/src/gui/LoadPluginWindow.hpp +++ b/src/gui/LoadPluginWindow.hpp @@ -147,7 +147,7 @@ private: bool _refresh_list; Gtk::TreeView* _plugins_treeview; Gtk::CheckButton* _polyphonic_checkbutton; - Gtk::Entry* _node_name_entry; + Gtk::Entry* _name_entry; Gtk::Button* _close_button; Gtk::Button* _add_button; Gtk::ComboBox* _filter_combo; diff --git a/src/gui/NewSubpatchWindow.cpp b/src/gui/NewSubpatchWindow.cpp index fbdc5f0d..1124afb3 100644 --- a/src/gui/NewSubpatchWindow.cpp +++ b/src/gui/NewSubpatchWindow.cpp @@ -101,7 +101,7 @@ NewSubpatchWindow::ok_clicked() props.insert(make_pair(_app->uris().ingen_enabled, _app->forge().make(bool(true)))); _app->interface()->put(GraphObject::path_to_uri(path), props, Resource::INTERNAL); - // Set external (node perspective) properties + // Set external (block perspective) properties props = _initial_data; props.insert(make_pair(_app->uris().rdf_type, _app->uris().ingen_Patch)); _app->interface()->put(GraphObject::path_to_uri(path), _initial_data, Resource::EXTERNAL); diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp index 35a35c39..fe01c713 100644 --- a/src/gui/NodeMenu.cpp +++ b/src/gui/NodeMenu.cpp @@ -21,7 +21,7 @@ #include "ingen/Interface.hpp" #include "ingen/Log.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PluginModel.hpp" #include "lv2/lv2plug.in/ns/ext/presets/presets.h" @@ -49,9 +49,9 @@ NodeMenu::NodeMenu(BaseObjectType* cobject, } void -NodeMenu::init(App& app, SharedPtr node) +NodeMenu::init(App& app, SharedPtr block) { - ObjectMenu::init(app, node); + ObjectMenu::init(app, block); _learn_menuitem->signal_activate().connect(sigc::mem_fun(this, &NodeMenu::on_menu_learn)); @@ -62,11 +62,11 @@ NodeMenu::init(App& app, SharedPtr node) _randomize_menuitem->signal_activate().connect( sigc::mem_fun(this, &NodeMenu::on_menu_randomize)); - const PluginModel* plugin = dynamic_cast(node->plugin()); + const PluginModel* plugin = dynamic_cast(block->plugin()); if (plugin && plugin->type() == PluginModel::LV2 && plugin->has_ui()) { _popup_gui_menuitem->show(); _embed_gui_menuitem->show(); - const Raul::Atom& ui_embedded = node->get_property( + const Raul::Atom& ui_embedded = block->get_property( _app->uris().ingen_uiEmbedded); _embed_gui_menuitem->set_active( ui_embedded.is_valid() && ui_embedded.get_bool()); @@ -150,11 +150,11 @@ NodeMenu::on_menu_randomize() { _app->interface()->bundle_begin(); - const NodeModel* const nm = (const NodeModel*)_object.get(); - for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) { + const BlockModel* const bm = (const BlockModel*)_object.get(); + for (BlockModel::Ports::const_iterator i = bm->ports().begin(); i != bm->ports().end(); ++i) { if ((*i)->is_input() && _app->can_control(i->get())) { float min = 0.0f, max = 1.0f; - nm->port_value_range(*i, min, max, _app->sample_rate()); + bm->port_value_range(*i, min, max, _app->sample_rate()); const float val = g_random_double_range(0.0, 1.0) * (max - min) + min; _app->interface()->set_property( (*i)->uri(), @@ -175,8 +175,8 @@ NodeMenu::on_menu_disconnect() void NodeMenu::on_preset_activated(const std::string& uri) { - const NodeModel* const node = (const NodeModel*)_object.get(); - const PluginModel* const plugin = dynamic_cast(node->plugin()); + const BlockModel* const block = (const BlockModel*)_object.get(); + const PluginModel* const plugin = dynamic_cast(block->plugin()); LilvNode* port_pred = lilv_new_uri(plugin->lilv_world(), LV2_CORE__port); @@ -202,7 +202,7 @@ NodeMenu::on_preset_activated(const std::string& uri) const LilvNode* sym = lilv_nodes_get_first(symbols); _app->interface()->set_property( GraphObject::path_to_uri( - node->path().child(Raul::Symbol(lilv_node_as_string(sym)))), + block->path().child(Raul::Symbol(lilv_node_as_string(sym)))), _app->uris().ingen_value, _app->forge().make(lilv_node_as_float(val))); } @@ -224,8 +224,8 @@ NodeMenu::on_preset_clicked(const std::string& uri, GdkEventButton* ev) bool NodeMenu::has_control_inputs() { - const NodeModel* const nm = (const NodeModel*)_object.get(); - for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) + const BlockModel* const bm = (const BlockModel*)_object.get(); + for (BlockModel::Ports::const_iterator i = bm->ports().begin(); i != bm->ports().end(); ++i) if ((*i)->is_input() && (*i)->is_numeric()) return true; diff --git a/src/gui/NodeMenu.hpp b/src/gui/NodeMenu.hpp index 07a25367..b307b9a4 100644 --- a/src/gui/NodeMenu.hpp +++ b/src/gui/NodeMenu.hpp @@ -24,7 +24,7 @@ #include #include "ObjectMenu.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "raul/SharedPtr.hpp" namespace Ingen { @@ -40,7 +40,7 @@ public: NodeMenu(BaseObjectType* cobject, const Glib::RefPtr& xml); - void init(App& app, SharedPtr node); + void init(App& app, SharedPtr block); bool has_control_inputs(); diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 89ecc4a1..bbd569fc 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -23,7 +23,7 @@ #include "ingen/Interface.hpp" #include "ingen/Log.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PatchModel.hpp" #include "ingen/client/PluginModel.hpp" #include "ingen/client/PluginUI.hpp" @@ -49,22 +49,20 @@ using namespace Client; namespace GUI { -NodeModule::NodeModule(PatchCanvas& canvas, - SharedPtr node) - : Ganv::Module(canvas, node->path().symbol(), 0, 0, true) - , _node(node) +NodeModule::NodeModule(PatchCanvas& canvas, + SharedPtr block) + : Ganv::Module(canvas, block->path().symbol(), 0, 0, true) + , _block(block) , _gui_widget(NULL) , _gui_window(NULL) { - assert(_node); - - node->signal_new_port().connect( + block->signal_new_port().connect( sigc::mem_fun(this, &NodeModule::new_port_view)); - node->signal_removed_port().connect( + block->signal_removed_port().connect( sigc::hide_return(sigc::mem_fun(this, &NodeModule::delete_port_view))); - node->signal_property().connect( + block->signal_property().connect( sigc::mem_fun(this, &NodeModule::property_changed)); - node->signal_moved().connect( + block->signal_moved().connect( sigc::mem_fun(this, &NodeModule::rename)); signal_event().connect( @@ -73,7 +71,7 @@ NodeModule::NodeModule(PatchCanvas& canvas, signal_moved().connect( sigc::mem_fun(this, &NodeModule::store_location)); - const PluginModel* plugin = dynamic_cast(node->plugin()); + const PluginModel* plugin = dynamic_cast(block->plugin()); if (plugin) { plugin->signal_changed().connect( sigc::mem_fun(this, &NodeModule::plugin_changed)); @@ -90,7 +88,7 @@ bool NodeModule::show_menu(GdkEventButton* ev) { WidgetFactory::get_widget_derived("object_menu", _menu); - _menu->init(app(), _node); + _menu->init(app(), _block); _menu->signal_embed_gui.connect( sigc::mem_fun(this, &NodeModule::on_embed_gui_toggled)); _menu->signal_popup_gui.connect( @@ -100,27 +98,25 @@ NodeModule::show_menu(GdkEventButton* ev) } NodeModule* -NodeModule::create(PatchCanvas& canvas, - SharedPtr node, - bool human) +NodeModule::create(PatchCanvas& canvas, + SharedPtr block, + bool human) { - NodeModule* ret; - - SharedPtr patch = PtrCast(node); - if (patch) - ret = new SubpatchModule(canvas, patch); - else - ret = new NodeModule(canvas, node); - - for (GraphObject::Properties::const_iterator m = node->properties().begin(); - m != node->properties().end(); ++m) + SharedPtr patch = PtrCast(block); + + NodeModule* ret = (patch) + ? new SubpatchModule(canvas, patch) + : new NodeModule(canvas, block); + + for (GraphObject::Properties::const_iterator m = block->properties().begin(); + m != block->properties().end(); ++m) ret->property_changed(m->first, m->second); - for (NodeModel::Ports::const_iterator p = node->ports().begin(); - p != node->ports().end(); ++p) + for (BlockModel::Ports::const_iterator p = block->ports().begin(); + p != block->ports().end(); ++p) ret->new_port_view(*p); - ret->set_stacked(node->polyphonic()); + ret->set_stacked(block->polyphonic()); if (human) ret->show_human_names(human); // FIXME: double port iteration @@ -140,9 +136,9 @@ NodeModule::show_human_names(bool b) const URIs& uris = app().uris(); if (b) { - set_label(node()->label().c_str()); + set_label(block()->label().c_str()); } else { - set_label(node()->symbol().c_str()); + set_label(block()->symbol().c_str()); } for (iterator i = begin(); i != end(); ++i) { @@ -153,7 +149,7 @@ NodeModule::show_human_names(bool b) if (name_property.type() == uris.forge.String) { label = name_property.get_string(); } else { - Glib::ustring hn = node()->plugin_model()->port_human_name( + Glib::ustring hn = block()->plugin_model()->port_human_name( port->model()->index()); if (!hn.empty()) label = hn; @@ -210,7 +206,7 @@ void NodeModule::on_embed_gui_toggled(bool embed) { embed_gui(embed); - app().interface()->set_property(_node->uri(), + app().interface()->set_property(_block->uri(), app().uris().ingen_uiEmbedded, app().forge().make(embed)); } @@ -225,8 +221,8 @@ NodeModule::embed_gui(bool embed) } if (!_plugin_ui) { - const PluginModel* const pm = dynamic_cast(_node->plugin()); - _plugin_ui = pm->ui(app().world(), _node); + const PluginModel* const pm = dynamic_cast(_block->plugin()); + _plugin_ui = pm->ui(app().world(), _block); } if (_plugin_ui) { @@ -257,7 +253,7 @@ void NodeModule::rename() { if (app().configuration()->name_style() == Configuration::PATH) { - set_label(_node->path().symbol()); + set_label(_block->path().symbol()); } } @@ -295,23 +291,23 @@ NodeModule::delete_port_view(SharedPtr model) delete p; } else { app().log().warn(Raul::fmt("Failed to find port %1% on module %2%\n") - % model->path() % _node->path()); + % model->path() % _block->path()); } } bool NodeModule::popup_gui() { - if (_node->plugin() && _node->plugin()->type() == PluginModel::LV2) { + if (_block->plugin() && _block->plugin()->type() == PluginModel::LV2) { if (_plugin_ui) { app().log().warn("LV2 GUI already embedded, cannot pop up\n"); return false; } - const PluginModel* const plugin = dynamic_cast(_node->plugin()); + const PluginModel* const plugin = dynamic_cast(_block->plugin()); assert(plugin); - _plugin_ui = plugin->ui(app().world(), _node); + _plugin_ui = plugin->ui(app().world(), _block); if (_plugin_ui) { GtkWidget* c_widget = (GtkWidget*)_plugin_ui->get_widget(); @@ -321,7 +317,7 @@ NodeModule::popup_gui() if (!_plugin_ui->is_resizable()) { _gui_window->set_resizable(false); } - _gui_window->set_title(_node->path() + " UI - Ingen"); + _gui_window->set_title(_block->path() + " UI - Ingen"); _gui_window->set_role("plugin_ui"); _gui_window->add(*_gui_widget); _gui_widget->show_all(); @@ -333,7 +329,7 @@ NodeModule::popup_gui() return true; } else { - app().log().warn(Raul::fmt("No LV2 GUI for %1%\n") % _node->path()); + app().log().warn(Raul::fmt("No LV2 GUI for %1%\n") % _block->path()); } } @@ -353,10 +349,11 @@ void NodeModule::set_control_values() { uint32_t index = 0; - for (NodeModel::Ports::const_iterator p = _node->ports().begin(); - p != _node->ports().end(); ++p) { - if (app().can_control(p->get())) + for (BlockModel::Ports::const_iterator p = _block->ports().begin(); + p != _block->ports().end(); ++p) { + if (app().can_control(p->get())) { value_changed(index, (*p)->value()); + } ++index; } } @@ -387,8 +384,8 @@ NodeModule::store_location(double ax, double ay) const Raul::Atom x(app().forge().make(static_cast(ax))); const Raul::Atom y(app().forge().make(static_cast(ay))); - if (x != _node->get_property(uris.ingen_canvasX) || - y != _node->get_property(uris.ingen_canvasY)) + if (x != _block->get_property(uris.ingen_canvasX) || + y != _block->get_property(uris.ingen_canvasY)) { Resource::Properties remove; remove.insert(make_pair(uris.ingen_canvasX, uris.wildcard)); @@ -396,7 +393,7 @@ NodeModule::store_location(double ax, double ay) Resource::Properties add; add.insert(make_pair(uris.ingen_canvasX, x)); add.insert(make_pair(uris.ingen_canvasY, y)); - app().interface()->delta(_node->uri(), remove, add); + app().interface()->delta(_block->uri(), remove, add); } } @@ -435,12 +432,12 @@ NodeModule::set_selected(gboolean b) Ganv::Module::set_selected(b); #if 0 if (b) { - PatchWindow* win = app().window_factory()->parent_patch_window(node()); + PatchWindow* win = app().window_factory()->parent_patch_window(block()); if (win) { std::string doc; bool html = false; - if (node()->plugin_model()) { - doc = node()->plugin_model()->documentation(&html); + if (block()->plugin_model()) { + doc = block()->plugin_model()->documentation(&html); } if (!doc.empty()) { win->show_documentation(doc, html); diff --git a/src/gui/NodeModule.hpp b/src/gui/NodeModule.hpp index 42ad0fc4..73295d1a 100644 --- a/src/gui/NodeModule.hpp +++ b/src/gui/NodeModule.hpp @@ -25,7 +25,7 @@ namespace Raul { class Atom; } namespace Ingen { namespace Client { - class NodeModel; + class BlockModel; class PluginUI; class PortModel; } } @@ -47,9 +47,9 @@ class NodeModule : public Ganv::Module { public: static NodeModule* create( - PatchCanvas& canvas, - SharedPtr node, - bool human_names); + PatchCanvas& canvas, + SharedPtr block, + bool human_names); virtual ~NodeModule(); @@ -63,10 +63,10 @@ public: void show_human_names(bool b); void set_selected(gboolean b); - SharedPtr node() const { return _node; } + SharedPtr block() const { return _block; } protected: - NodeModule(PatchCanvas& canvas, SharedPtr node); + NodeModule(PatchCanvas& canvas, SharedPtr block); virtual bool on_double_click(GdkEventButton* ev); @@ -89,11 +89,11 @@ protected: bool show_menu(GdkEventButton* ev); - SharedPtr _node; - NodeMenu* _menu; - SharedPtr _plugin_ui; - Gtk::Widget* _gui_widget; - Gtk::Window* _gui_window; ///< iff popped up + SharedPtr _block; + NodeMenu* _menu; + SharedPtr _plugin_ui; + Gtk::Widget* _gui_widget; + Gtk::Window* _gui_window; ///< iff popped up }; } // namespace GUI diff --git a/src/gui/PatchBox.cpp b/src/gui/PatchBox.cpp index 9150585a..ea3de513 100644 --- a/src/gui/PatchBox.cpp +++ b/src/gui/PatchBox.cpp @@ -257,7 +257,7 @@ PatchBox::set_patch(SharedPtr patch, _menu_view_control_window->property_sensitive() = false; - for (NodeModel::Ports::const_iterator p = patch->ports().begin(); + for (BlockModel::Ports::const_iterator p = patch->ports().begin(); p != patch->ports().end(); ++p) { if (_app->can_control(p->get())) { _menu_view_control_window->property_sensitive() = true; @@ -296,7 +296,7 @@ PatchBox::patch_port_removed(SharedPtr port) if (!(port->is_input() && _app->can_control(port.get()))) return; - for (NodeModel::Ports::const_iterator i = _patch->ports().begin(); + for (BlockModel::Ports::const_iterator i = _patch->ports().begin(); i != _patch->ports().end(); ++i) { if ((*i)->is_input() && _app->can_control(i->get())) { _menu_view_control_window->property_sensitive() = true; @@ -342,14 +342,14 @@ PatchBox::show_status(const ObjectModel* model) std::stringstream msg; msg << model->path(); - const PortModel* port = 0; - const NodeModel* node = 0; + const PortModel* port = 0; + const BlockModel* block = 0; if ((port = dynamic_cast(model))) { show_port_status(port, port->value()); - } else if ((node = dynamic_cast(model))) { - const PluginModel* plugin = dynamic_cast(node->plugin()); + } else if ((block = dynamic_cast(model))) { + const PluginModel* plugin = dynamic_cast(block->plugin()); if (plugin) msg << ((boost::format(" (%1%)") % plugin->human_name()).str()); _status_bar->push(msg.str(), STATUS_CONTEXT_HOVER); @@ -362,7 +362,7 @@ PatchBox::show_port_status(const PortModel* port, const Raul::Atom& value) std::stringstream msg; msg << port->path(); - const NodeModel* parent = dynamic_cast(port->parent().get()); + const BlockModel* parent = dynamic_cast(port->parent().get()); if (parent) { const PluginModel* plugin = dynamic_cast(parent->plugin()); if (plugin) { diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index bc103d50..d680a9b8 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -30,7 +30,7 @@ #include "ingen/Log.hpp" #include "ingen/World.hpp" #include "ingen/client/ClientStore.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PatchModel.hpp" #include "ingen/client/PluginModel.hpp" #include "ingen/serialisation/Serialiser.hpp" @@ -123,10 +123,10 @@ PatchCanvas::PatchCanvas(App& app, sigc::mem_fun(this, &PatchCanvas::disconnect)); // Connect to model signals to track state - _patch->signal_new_node().connect( - sigc::mem_fun(this, &PatchCanvas::add_node)); - _patch->signal_removed_node().connect( - sigc::mem_fun(this, &PatchCanvas::remove_node)); + _patch->signal_new_block().connect( + sigc::mem_fun(this, &PatchCanvas::add_block)); + _patch->signal_removed_block().connect( + sigc::mem_fun(this, &PatchCanvas::remove_block)); _patch->signal_new_port().connect( sigc::mem_fun(this, &PatchCanvas::add_port)); _patch->signal_removed_port().connect( @@ -289,15 +289,15 @@ PatchCanvas::build() { const Store::const_range kids = _app.store()->children_range(_patch); - // Create modules for nodes + // Create modules for blocks for (Store::const_iterator i = kids.first; i != kids.second; ++i) { - SharedPtr node = PtrCast(i->second); - if (node && node->parent() == _patch) - add_node(node); + SharedPtr block = PtrCast(i->second); + if (block && block->parent() == _patch) + add_block(block); } // Create pseudo modules for ports (ports on this canvas, not on our module) - for (NodeModel::Ports::const_iterator i = _patch->ports().begin(); + for (BlockModel::Ports::const_iterator i = _patch->ports().begin(); i != _patch->ports().end(); ++i) { add_port(*i); } @@ -392,30 +392,30 @@ PatchCanvas::add_plugin(SharedPtr p) } void -PatchCanvas::add_node(SharedPtr nm) +PatchCanvas::add_block(SharedPtr bm) { - SharedPtr pm = PtrCast(nm); + SharedPtr pm = PtrCast(bm); NodeModule* module; if (pm) { module = SubpatchModule::create(*this, pm, _human_names); } else { - module = NodeModule::create(*this, nm, _human_names); + module = NodeModule::create(*this, bm, _human_names); //const PluginModel* plugm = dynamic_cast(nm->plugin()); //if (plugm && !plugm->icon_path().empty()) // module->set_icon(_app.icon_from_path(plugm->icon_path(), 100).operator->()); } module->show(); - _views.insert(std::make_pair(nm, module)); - if (_pastees.find(nm->path()) != _pastees.end()) { + _views.insert(std::make_pair(bm, module)); + if (_pastees.find(bm->path()) != _pastees.end()) { module->set_selected(true); } } void -PatchCanvas::remove_node(SharedPtr nm) +PatchCanvas::remove_block(SharedPtr bm) { - Views::iterator i = _views.find(nm); + Views::iterator i = _views.find(bm); if (i != _views.end()) { const guint n_ports = i->second->num_ports(); @@ -617,7 +617,7 @@ destroy_node(GanvNode* node, void* data) NodeModule* node_module = dynamic_cast(module); if (node_module) { - app->interface()->del(node_module->node()->uri()); + app->interface()->del(node_module->block()->uri()); } else { PatchPortModule* port_module = dynamic_cast(module); if (port_module) { @@ -656,7 +656,7 @@ serialise_node(GanvNode* node, void* data) NodeModule* node_module = dynamic_cast(module); if (node_module) { - serialiser->serialise(node_module->node()); + serialiser->serialise(node_module->block()); } else { PatchPortModule* port_module = dynamic_cast(module); if (port_module) { @@ -828,7 +828,7 @@ PatchCanvas::load_plugin(WeakPtr weak_plugin) if (!plugin) return; - Raul::Symbol symbol = plugin->default_node_symbol(); + Raul::Symbol symbol = plugin->default_block_symbol(); unsigned offset = _app.store()->child_name_offset(_patch->path(), symbol); if (offset != 0) { std::stringstream ss; @@ -841,7 +841,7 @@ PatchCanvas::load_plugin(WeakPtr weak_plugin) // FIXME: polyphony? GraphObject::Properties props = get_initial_data(); - props.insert(make_pair(uris.rdf_type, uris.ingen_Node)); + props.insert(make_pair(uris.rdf_type, uris.ingen_Block)); props.insert(make_pair(uris.ingen_prototype, uris.forge.alloc_uri(plugin->uri()))); _app.interface()->put(GraphObject::path_to_uri(path), props); diff --git a/src/gui/PatchCanvas.hpp b/src/gui/PatchCanvas.hpp index 47b645d6..04c30ed3 100644 --- a/src/gui/PatchCanvas.hpp +++ b/src/gui/PatchCanvas.hpp @@ -64,8 +64,8 @@ public: bool show_port_names() const { return _show_port_names; } void add_plugin(SharedPtr pm); - void add_node(SharedPtr nm); - void remove_node(SharedPtr nm); + void add_block(SharedPtr bm); + void remove_block(SharedPtr bm); void add_port(SharedPtr pm); void remove_port(SharedPtr pm); void connection(SharedPtr cm); diff --git a/src/gui/PatchPortModule.cpp b/src/gui/PatchPortModule.cpp index a260c35e..ec0e6a04 100644 --- a/src/gui/PatchPortModule.cpp +++ b/src/gui/PatchPortModule.cpp @@ -19,7 +19,7 @@ #include #include "ingen/Interface.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PatchModel.hpp" #include "App.hpp" diff --git a/src/gui/PatchPortModule.hpp b/src/gui/PatchPortModule.hpp index 90f9cd6d..b48bbfc4 100644 --- a/src/gui/PatchPortModule.hpp +++ b/src/gui/PatchPortModule.hpp @@ -30,7 +30,6 @@ namespace Raul { class Atom; } namespace Ingen { namespace Client { class PortModel; - class NodeModel; } } namespace Ingen { diff --git a/src/gui/PatchView.cpp b/src/gui/PatchView.cpp index e81d16f7..efb37d11 100644 --- a/src/gui/PatchView.cpp +++ b/src/gui/PatchView.cpp @@ -134,7 +134,7 @@ PatchView::canvas_item_entered(Gnome::Canvas::Item* item) { NodeModule* m = dynamic_cast(item); if (m) - signal_object_entered.emit(m->node().get()); + signal_object_entered.emit(m->block().get()); const Port* p = dynamic_cast(item); if (p) @@ -146,7 +146,7 @@ PatchView::canvas_item_left(Gnome::Canvas::Item* item) { NodeModule* m = dynamic_cast(item); if (m) { - signal_object_left.emit(m->node().get()); + signal_object_left.emit(m->block().get()); return; } diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index 265b4caf..88d81fcd 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -50,7 +50,7 @@ Port::create(App& app, if (name.type() == app.forge().String) { label = name.get_string(); } else { - const SharedPtr parent(PtrCast(pm->parent())); + const SharedPtr parent(PtrCast(pm->parent())); if (parent && parent->plugin_model()) label = parent->plugin_model()->port_human_name(pm->index()); } @@ -111,7 +111,7 @@ Port::update_metadata() { SharedPtr pm = _port_model.lock(); if (_app.can_control(pm.get()) && pm->is_numeric()) { - boost::shared_ptr parent = PtrCast(pm->parent()); + boost::shared_ptr parent = PtrCast(pm->parent()); if (parent) { float min = 0.0f; float max = 1.0f; @@ -182,10 +182,10 @@ Port::on_scale_point_activated(float f) Gtk::Menu* Port::build_enum_menu() { - SharedPtr node = PtrCast(model()->parent()); - Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); + SharedPtr block = PtrCast(model()->parent()); + Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); - PluginModel::ScalePoints points = node->plugin_model()->port_scale_points( + PluginModel::ScalePoints points = block->plugin_model()->port_scale_points( model()->index()); for (PluginModel::ScalePoints::iterator i = points.begin(); i != points.end(); ++i) { @@ -354,10 +354,10 @@ Port::set_selected(gboolean b) Ganv::Port::set_selected(b); SharedPtr pm = _port_model.lock(); if (pm && b) { - SharedPtr node = PtrCast(pm->parent()); - PatchWindow* win = _app.window_factory()->parent_patch_window(node); - if (win && node->plugin_model()) { - const std::string& doc = node->plugin_model()->port_documentation( + SharedPtr block = PtrCast(pm->parent()); + PatchWindow* win = _app.window_factory()->parent_patch_window(block); + if (win && block->plugin_model()) { + const std::string& doc = block->plugin_model()->port_documentation( pm->index()); if (!doc.empty()) { win->show_documentation(doc, false); diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp index a5b907c3..a23e3b84 100644 --- a/src/gui/PortMenu.cpp +++ b/src/gui/PortMenu.cpp @@ -121,9 +121,9 @@ PortMenu::on_menu_set_max() void PortMenu::on_menu_reset_range() { - const URIs& uris = _app->uris(); - SharedPtr model = PtrCast(_object); - SharedPtr parent = PtrCast(_object->parent()); + const URIs& uris = _app->uris(); + SharedPtr model = PtrCast(_object); + SharedPtr parent = PtrCast(_object->parent()); float min, max; parent->default_port_value_range(model, min, max); @@ -142,12 +142,12 @@ PortMenu::on_menu_reset_range() void PortMenu::on_menu_expose() { - const URIs& uris = _app->uris(); - SharedPtr port = PtrCast(_object); - SharedPtr node = PtrCast(port->parent()); + const URIs& uris = _app->uris(); + SharedPtr port = PtrCast(_object); + SharedPtr block = PtrCast(port->parent()); - const std::string label = node->label() + " " + node->port_label(port); - const Raul::Path path = Raul::Path(node->path() + Raul::Symbol("_" + port->symbol())); + const std::string label = block->label() + " " + block->port_label(port); + const Raul::Path path = Raul::Path(block->path() + Raul::Symbol("_" + port->symbol())); Ingen::Resource r(*_object.get()); r.remove_property(uris.lv2_index, uris.wildcard); @@ -155,12 +155,12 @@ PortMenu::on_menu_expose() r.set_property(uris.lv2_name, _app->forge().alloc(label.c_str())); // TODO: Pretty kludgey coordinates - const float node_x = node->get_property(uris.ingen_canvasX).get_float(); - const float node_y = node->get_property(uris.ingen_canvasY).get_float(); - const float x_off = (label.length() * 16.0f) * (port->is_input() ? -1 : 1); - const float y_off = port->index() * 32.0f; - r.set_property(uris.ingen_canvasX, _app->forge().make(node_x + x_off)); - r.set_property(uris.ingen_canvasY, _app->forge().make(node_y + y_off)); + const float block_x = block->get_property(uris.ingen_canvasX).get_float(); + const float block_y = block->get_property(uris.ingen_canvasY).get_float(); + const float x_off = (label.length() * 16.0f) * (port->is_input() ? -1 : 1); + const float y_off = port->index() * 32.0f; + r.set_property(uris.ingen_canvasX, _app->forge().make(block_x + x_off)); + r.set_property(uris.ingen_canvasY, _app->forge().make(block_y + y_off)); _app->interface()->put(GraphObject::path_to_uri(path), r.properties()); diff --git a/src/gui/PortPropertiesWindow.cpp b/src/gui/PortPropertiesWindow.cpp index f6af2563..a4b2d5fc 100644 --- a/src/gui/PortPropertiesWindow.cpp +++ b/src/gui/PortPropertiesWindow.cpp @@ -18,7 +18,7 @@ #include #include "ingen/Interface.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PluginModel.hpp" #include "App.hpp" @@ -66,7 +66,7 @@ PortPropertiesWindow::present(SharedPtr pm) set_title(pm->path() + " Properties - Ingen"); float min = 0.0f, max = 1.0f; - boost::shared_ptr parent = PtrCast(_port_model->parent()); + boost::shared_ptr parent = PtrCast(_port_model->parent()); if (parent) parent->port_value_range(_port_model, min, max, _app->sample_rate()); diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index 2acb7ffe..e49e2021 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -24,7 +24,7 @@ #include "ingen/Interface.hpp" #include "ingen/Log.hpp" #include "ingen/World.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "ingen/client/PluginModel.hpp" #include "App.hpp" diff --git a/src/gui/PropertiesWindow.hpp b/src/gui/PropertiesWindow.hpp index e62fb07f..7ba5e5b6 100644 --- a/src/gui/PropertiesWindow.hpp +++ b/src/gui/PropertiesWindow.hpp @@ -30,7 +30,7 @@ #include "raul/SharedPtr.hpp" -#include "ingen/client/NodeModel.hpp" +#include "ingen/client/BlockModel.hpp" #include "Window.hpp" diff --git a/src/gui/SubpatchModule.cpp b/src/gui/SubpatchModule.cpp index 5425677c..efd29805 100644 --- a/src/gui/SubpatchModule.cpp +++ b/src/gui/SubpatchModule.cpp @@ -67,8 +67,8 @@ SubpatchModule::store_location(double ax, double ay) const Raul::Atom x(app().forge().make(static_cast(ax))); const Raul::Atom y(app().forge().make(static_cast(ay))); - if (x != _node->get_property(uris.ingen_canvasX) || - y != _node->get_property(uris.ingen_canvasY)) + if (x != _block->get_property(uris.ingen_canvasX) || + y != _block->get_property(uris.ingen_canvasY)) { Resource::Properties remove; remove.insert(make_pair(uris.ingen_canvasX, uris.wildcard)); @@ -78,7 +78,7 @@ SubpatchModule::store_location(double ax, double ay) Resource::Property(x, Resource::EXTERNAL))); add.insert(make_pair(uris.ingen_canvasY, Resource::Property(y, Resource::EXTERNAL))); - app().interface()->delta(_node->uri(), remove, add); + app().interface()->delta(_block->uri(), remove, add); } } diff --git a/src/gui/SubpatchModule.hpp b/src/gui/SubpatchModule.hpp index 727f681d..8d7dbecc 100644 --- a/src/gui/SubpatchModule.hpp +++ b/src/gui/SubpatchModule.hpp @@ -24,9 +24,8 @@ namespace Ingen { namespace Client { class PatchModel; - class NodeModel; - class PortModel; class PatchWindow; + class PortModel; } } namespace Ingen { diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp index 98af4c19..1f0e0310 100644 --- a/src/gui/WindowFactory.cpp +++ b/src/gui/WindowFactory.cpp @@ -112,12 +112,12 @@ WindowFactory::patch_window(SharedPtr patch) } PatchWindow* -WindowFactory::parent_patch_window(SharedPtr node) +WindowFactory::parent_patch_window(SharedPtr block) { - if (!node) + if (!block) return NULL; - return patch_window(PtrCast(node->parent())); + return patch_window(PtrCast(block->parent())); } /** Present a PatchWindow for a Patch. diff --git a/src/gui/WindowFactory.hpp b/src/gui/WindowFactory.hpp index 0712c656..465bfa80 100644 --- a/src/gui/WindowFactory.hpp +++ b/src/gui/WindowFactory.hpp @@ -25,9 +25,9 @@ namespace Ingen { namespace Client { -class PatchModel; -class NodeModel; +class BlockModel; class ObjectModel; +class PatchModel; } namespace GUI { @@ -57,7 +57,7 @@ public: PatchBox* patch_box(SharedPtr patch); PatchWindow* patch_window(SharedPtr patch); - PatchWindow* parent_patch_window(SharedPtr node); + PatchWindow* parent_patch_window(SharedPtr block); void present_patch( SharedPtr model, diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index bac5e06f..900aba02 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -36,9 +36,6 @@ #include "sord/sordmm.hpp" #include "sratom/sratom.h" -#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" - using namespace std; typedef set RDFNodes; @@ -192,7 +189,7 @@ parse_patch( boost::optional data = boost::optional()); static boost::optional -parse_node( +parse_block( World* world, Interface* target, Sord::Model& model, @@ -218,21 +215,21 @@ parse_edges( const Raul::Path& patch); static boost::optional -parse_node(Ingen::World* world, - Ingen::Interface* target, - Sord::Model& model, - const Sord::Node& subject, - const Raul::Path& path, - boost::optional data) +parse_block(Ingen::World* world, + Ingen::Interface* target, + Sord::Model& model, + const Sord::Node& subject, + const Raul::Path& path, + boost::optional data) { const URIs& uris = world->uris(); - const Sord::URI ingen_prototype(*world->rdf_world(), NS_INGEN "prototype"); + const Sord::URI ingen_prototype(*world->rdf_world(), uris.ingen_prototype); const Sord::Node nil; Sord::Iter i = model.find(subject, ingen_prototype, nil); if (i.end() || i.get_object().type() != Sord::Node::URI) { - world->log().error("Node missing mandatory ingen:prototype\n"); + world->log().error("BLock missing mandatory ingen:prototype\n"); return boost::optional(); } @@ -274,7 +271,7 @@ parse_node(Ingen::World* world, } else { Resource::Properties props = get_properties(world, model, subject); props.insert(make_pair(uris.rdf_type, - uris.forge.alloc_uri(uris.ingen_Node))); + uris.forge.alloc_uri(uris.ingen_Block))); target->put(GraphObject::path_to_uri(path), props); } return path; @@ -289,8 +286,10 @@ parse_patch(Ingen::World* world, boost::optional a_symbol, boost::optional data) { - const Sord::URI ingen_node(*world->rdf_world(), NS_INGEN "node"); - const Sord::URI ingen_polyphony(*world->rdf_world(), NS_INGEN "polyphony"); + URIs& uris = world->uris(); + + const Sord::URI ingen_block(*world->rdf_world(), uris.ingen_block); + const Sord::URI ingen_polyphony(*world->rdf_world(), uris.ingen_polyphony); const Sord::URI lv2_port(*world->rdf_world(), LV2_CORE__port); const Sord::Node& patch = subject_node; @@ -320,24 +319,24 @@ parse_patch(Ingen::World* world, Resource::Properties props = get_properties(world, model, subject_node); target->put(GraphObject::path_to_uri(patch_path), props); - // For each node in this patch - for (Sord::Iter n = model.find(subject_node, ingen_node, nil); !n.end(); ++n) { - Sord::Node node = n.get_object(); - const Raul::Path node_path = patch_path.child( + // For each block in this patch + for (Sord::Iter n = model.find(subject_node, ingen_block, nil); !n.end(); ++n) { + Sord::Node node = n.get_object(); + const Raul::Path block_path = patch_path.child( Raul::Symbol(get_basename(node.to_string()))); - // Parse and create node - parse_node(world, target, model, node, node_path, - boost::optional()); + // Parse and create block + parse_block(world, target, model, node, block_path, + boost::optional()); - // For each port on this node + // For each port on this block for (Sord::Iter p = model.find(node, lv2_port, nil); !p.end(); ++p) { Sord::Node port = p.get_object(); // Get all properties uint32_t index = 0; boost::optional port_record = get_port( - world, model, port, node_path, index); + world, model, port, block_path, index); if (!port_record) { world->log().error(Raul::fmt("Invalid port %1%\n") % port); return boost::optional(); @@ -386,8 +385,10 @@ parse_edge(Ingen::World* world, const Sord::Node& subject, const Raul::Path& parent) { - const Sord::URI ingen_tail(*world->rdf_world(), NS_INGEN "tail"); - const Sord::URI ingen_head(*world->rdf_world(), NS_INGEN "head"); + URIs& uris = world->uris(); + + const Sord::URI ingen_tail(*world->rdf_world(), uris.ingen_tail); + const Sord::URI ingen_head(*world->rdf_world(), uris.ingen_head); const Sord::Node nil; Sord::Iter t = model.find(subject, ingen_tail, nil); @@ -437,7 +438,7 @@ parse_edges(Ingen::World* world, const Sord::Node& subject, const Raul::Path& parent) { - const Sord::URI ingen_edge(*world->rdf_world(), NS_INGEN "edge"); + const Sord::URI ingen_edge(*world->rdf_world(), world->uris().ingen_edge); const Sord::Node nil; for (Sord::Iter i = model.find(subject, ingen_edge, nil); !i.end(); ++i) { @@ -476,14 +477,16 @@ parse(Ingen::World* world, boost::optional symbol, boost::optional data) { - const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch"); - const Sord::URI node_class (*world->rdf_world(), NS_INGEN "Node"); - const Sord::URI edge_class (*world->rdf_world(), NS_INGEN "Edge"); - const Sord::URI internal_class(*world->rdf_world(), NS_INGEN "Internal"); + URIs& uris = world->uris(); + + const Sord::URI patch_class (*world->rdf_world(), uris.ingen_Patch); + const Sord::URI block_class (*world->rdf_world(), uris.ingen_Block); + const Sord::URI edge_class (*world->rdf_world(), uris.ingen_Edge); + const Sord::URI internal_class(*world->rdf_world(), uris.ingen_Internal); const Sord::URI in_port_class (*world->rdf_world(), LV2_CORE__InputPort); const Sord::URI out_port_class(*world->rdf_world(), LV2_CORE__OutputPort); const Sord::URI lv2_class (*world->rdf_world(), LV2_CORE__Plugin); - const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type"); + const Sord::URI rdf_type (*world->rdf_world(), uris.rdf_type); const Sord::Node nil; // Parse explicit subject patch @@ -518,8 +521,8 @@ parse(Ingen::World* world, relative_uri( model.base_uri().to_string(), s.to_string(), true)); if (types.find(patch_class) != types.end()) { ret = parse_patch(world, target, model, s, parent, symbol, data); - } else if (types.find(node_class) != types.end()) { - ret = parse_node(world, target, model, s, path, data); + } else if (types.find(block_class) != types.end()) { + ret = parse_block(world, target, model, s, path, data); } else if (types.find(in_port_class) != types.end() || types.find(out_port_class) != types.end()) { parse_properties( diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index b480d531..a9d49fe3 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -69,9 +69,9 @@ struct Serialiser::Impl { void serialise_patch(SharedPtr p, const Sord::Node& id); - void serialise_node(SharedPtr n, - const Sord::Node& class_id, - const Sord::Node& id); + void serialise_block(SharedPtr n, + const Sord::Node& class_id, + const Sord::Node& id); void serialise_port(const GraphObject* p, Resource::Graph context, @@ -133,21 +133,22 @@ Serialiser::Impl::write_manifest(const std::string& bundle_path, start_to_filename(manifest_path); Sord::World& world = _model->world(); + const URIs& uris = _world.uris(); const string filename(patch_symbol + ".ttl"); const Sord::URI subject(world, filename, _base_uri); _model->add_statement(subject, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "ingen:Patch")); + Sord::URI(world, uris.rdf_type), + Sord::URI(world, uris.ingen_Patch)); _model->add_statement(subject, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "lv2:Plugin")); + Sord::URI(world, uris.rdf_type), + Sord::URI(world, uris.lv2_Plugin)); _model->add_statement(subject, - Sord::Curie(world, "rdfs:seeAlso"), + Sord::URI(world, uris.rdfs_seeAlso), Sord::URI(world, filename, _base_uri)); _model->add_statement(subject, - Sord::Curie(world, "lv2:binary"), + Sord::URI(world, uris.lv2_binary), Sord::URI(world, binary_path, _base_uri)); symlink(Glib::Module::build_path(INGEN_BUNDLE_DIR, "ingen_lv2").c_str(), @@ -285,9 +286,9 @@ Serialiser::serialise(SharedPtr object) throw (std::logic_err if (object->graph_type() == GraphObject::PATCH) { me->serialise_patch(object, me->path_rdf_node(object->path())); - } else if (object->graph_type() == GraphObject::NODE) { + } else if (object->graph_type() == GraphObject::BLOCK) { const Sord::URI plugin_id(me->_model->world(), object->plugin()->uri()); - me->serialise_node(object, plugin_id, me->path_rdf_node(object->path())); + me->serialise_block(object, plugin_id, me->path_rdf_node(object->path())); } else if (object->graph_type() == GraphObject::PORT) { me->serialise_port(object.get(), Resource::DEFAULT, @@ -302,27 +303,25 @@ void Serialiser::Impl::serialise_patch(SharedPtr patch, const Sord::Node& patch_id) { - assert(_model); Sord::World& world = _model->world(); + const URIs& uris = _world.uris(); _model->add_statement(patch_id, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "ingen:Patch")); + Sord::URI(world, uris.rdf_type), + Sord::URI(world, uris.ingen_Patch)); _model->add_statement(patch_id, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "lv2:Plugin")); + Sord::URI(world, uris.rdf_type), + Sord::URI(world, uris.lv2_Plugin)); _model->add_statement(patch_id, - Sord::Curie(world, "lv2:extensionData"), + Sord::URI(world, uris.lv2_extensionData), Sord::URI(world, LV2_STATE__interface)); _model->add_statement(patch_id, Sord::URI(world, LV2_UI__ui), Sord::URI(world, "http://drobilla.net/ns/ingen#PatchUIGtk2")); - const URIs& uris = _world.uris(); - // Always write a symbol (required by Ingen) Raul::Symbol symbol("_"); GraphObject::Properties::const_iterator s = patch->properties().find(uris.lv2_symbol); @@ -334,7 +333,7 @@ Serialiser::Impl::serialise_patch(SharedPtr patch, symbol = Raul::Symbol::symbolify(base.substr(0, base.find('.'))); _model->add_statement( patch_id, - Sord::Curie(world, "lv2:symbol"), + Sord::URI(world, uris.lv2_symbol), Sord::Literal(world, symbol.c_str())); } else { symbol = Raul::Symbol::symbolify(s->second.get_string()); @@ -381,21 +380,21 @@ Serialiser::Impl::serialise_patch(SharedPtr patch, _base_uri = my_base_uri; _model = my_model; - // Serialise reference to patch node - const Sord::Node node_id(path_rdf_node(subpatch->path())); + // Serialise reference to patch block + const Sord::Node block_id(path_rdf_node(subpatch->path())); _model->add_statement(patch_id, - Sord::Curie(world, "ingen:node"), - node_id); - serialise_node(subpatch, subpatch_id, node_id); - } else if (n->second->graph_type() == GraphObject::NODE) { - SharedPtr node = n->second; - - const Sord::URI class_id(world, node->plugin()->uri()); - const Sord::Node node_id(path_rdf_node(n->second->path())); + Sord::URI(world, uris.ingen_block), + block_id); + serialise_block(subpatch, subpatch_id, block_id); + } else if (n->second->graph_type() == GraphObject::BLOCK) { + SharedPtr block = n->second; + + const Sord::URI class_id(world, block->plugin()->uri()); + const Sord::Node block_id(path_rdf_node(n->second->path())); _model->add_statement(patch_id, - Sord::Curie(world, "ingen:node"), - node_id); - serialise_node(node, class_id, node_id); + Sord::URI(world, uris.ingen_block), + block_id); + serialise_block(block, class_id, block_id); } } @@ -421,29 +420,31 @@ Serialiser::Impl::serialise_patch(SharedPtr patch, } void -Serialiser::Impl::serialise_node(SharedPtr node, - const Sord::Node& class_id, - const Sord::Node& node_id) +Serialiser::Impl::serialise_block(SharedPtr block, + const Sord::Node& class_id, + const Sord::Node& block_id) { - _model->add_statement(node_id, - Sord::Curie(_model->world(), "rdf:type"), - Sord::Curie(_model->world(), "ingen:Node")); - _model->add_statement(node_id, - Sord::Curie(_model->world(), "ingen:prototype"), + const URIs& uris = _world.uris(); + + _model->add_statement(block_id, + Sord::URI(_model->world(), uris.rdf_type), + Sord::URI(_model->world(), uris.ingen_Block)); + _model->add_statement(block_id, + Sord::URI(_model->world(), uris.ingen_prototype), class_id); - _model->add_statement(node_id, - Sord::Curie(_model->world(), "lv2:symbol"), - Sord::Literal(_model->world(), node->path().symbol())); + _model->add_statement(block_id, + Sord::URI(_model->world(), uris.lv2_symbol), + Sord::Literal(_model->world(), block->path().symbol())); - const GraphObject::Properties props = node->properties(Resource::EXTERNAL); - serialise_properties(node_id, props); + const GraphObject::Properties props = block->properties(Resource::EXTERNAL); + serialise_properties(block_id, props); - for (uint32_t i = 0; i < node->num_ports(); ++i) { - GraphObject* const p = node->port(i); + for (uint32_t i = 0; i < block->num_ports(); ++i) { + GraphObject* const p = block->port(i); const Sord::Node port_id = path_rdf_node(p->path()); serialise_port(p, Resource::EXTERNAL, port_id); - _model->add_statement(node_id, - Sord::Curie(_model->world(), "lv2:port"), + _model->add_statement(block_id, + Sord::URI(_model->world(), uris.lv2_port), port_id); } } @@ -457,7 +458,7 @@ Serialiser::Impl::serialise_port(const GraphObject* port, Sord::World& world = _model->world(); _model->add_statement(port_id, - Sord::Curie(world, "lv2:symbol"), + Sord::URI(world, uris.lv2_symbol), Sord::Literal(world, port->path().symbol())); GraphObject::Properties props = port->properties(context); @@ -494,25 +495,26 @@ Serialiser::Impl::serialise_edge(const Sord::Node& parent, "serialise_edge called without serialisation in progress"); Sord::World& world = _model->world(); + const URIs& uris = _world.uris(); - const Sord::Node src = path_rdf_node(edge->tail_path()); - const Sord::Node dst = path_rdf_node(edge->head_path()); + const Sord::Node src = path_rdf_node(edge->tail_path()); + const Sord::Node dst = path_rdf_node(edge->head_path()); const Sord::Node edge_id = Sord::Node::blank_id(*_world.rdf_world()); _model->add_statement(edge_id, - Sord::Curie(world, "ingen:tail"), + Sord::URI(world, uris.ingen_tail), src); _model->add_statement(edge_id, - Sord::Curie(world, "ingen:head"), + Sord::URI(world, uris.ingen_head), dst); if (parent.is_valid()) { _model->add_statement(parent, - Sord::Curie(world, "ingen:edge"), + Sord::URI(world, uris.ingen_edge), edge_id); } else { _model->add_statement(edge_id, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "ingen:Edge")); + Sord::URI(world, uris.rdf_type), + Sord::URI(world, uris.ingen_Edge)); } } diff --git a/src/server/BlockFactory.cpp b/src/server/BlockFactory.cpp new file mode 100644 index 00000000..3e08aa7f --- /dev/null +++ b/src/server/BlockFactory.cpp @@ -0,0 +1,134 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include + +#include "lilv/lilv.h" + +#include "ingen/World.hpp" +#include "internals/Controller.hpp" +#include "internals/Delay.hpp" +#include "internals/Note.hpp" +#include "internals/Trigger.hpp" + +#include "InternalPlugin.hpp" +#include "LV2Plugin.hpp" +#include "BlockFactory.hpp" +#include "ThreadManager.hpp" + +using namespace std; + +namespace Ingen { +namespace Server { + +using namespace Internals; + +BlockFactory::BlockFactory(Ingen::World* world) + : _world(world) + , _lv2_info(new LV2Info(world)) + , _has_loaded(false) +{ + load_internal_plugins(); +} + +BlockFactory::~BlockFactory() +{ + for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) + delete i->second; + + _plugins.clear(); +} + +const BlockFactory::Plugins& +BlockFactory::plugins() +{ + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + if (!_has_loaded) { + _has_loaded = true; + // TODO: Plugin list refreshing + load_lv2_plugins(); + _has_loaded = true; + } + return _plugins; +} + +PluginImpl* +BlockFactory::plugin(const Raul::URI& uri) +{ + load_plugin(uri); + const Plugins::const_iterator i = _plugins.find(uri); + return ((i != _plugins.end()) ? i->second : NULL); +} + +void +BlockFactory::load_internal_plugins() +{ + Ingen::URIs& uris = _world->uris(); + InternalPlugin* controller_plug = ControllerNode::internal_plugin(uris); + _plugins.insert(make_pair(controller_plug->uri(), controller_plug)); + + InternalPlugin* delay_plug = DelayNode::internal_plugin(uris); + _plugins.insert(make_pair(delay_plug->uri(), delay_plug)); + + InternalPlugin* note_plug = NoteNode::internal_plugin(uris); + _plugins.insert(make_pair(note_plug->uri(), note_plug)); + + InternalPlugin* trigger_plug = TriggerNode::internal_plugin(uris); + _plugins.insert(make_pair(trigger_plug->uri(), trigger_plug)); +} + +void +BlockFactory::load_plugin(const Raul::URI& uri) +{ + if (_has_loaded || _plugins.find(uri) != _plugins.end()) { + return; + } + + LilvNode* node = lilv_new_uri(_world->lilv_world(), uri.c_str()); + const LilvPlugins* plugs = lilv_world_get_all_plugins(_world->lilv_world()); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugs, node); + if (plug) { + LV2Plugin* const ingen_plugin = new LV2Plugin(_lv2_info, uri); + ingen_plugin->lilv_plugin(plug); + _plugins.insert(make_pair(uri, ingen_plugin)); + } + lilv_node_free(node); +} + +/** Loads information about all LV2 plugins into internal plugin database. + */ +void +BlockFactory::load_lv2_plugins() +{ + const LilvPlugins* plugins = lilv_world_get_all_plugins(_world->lilv_world()); + LILV_FOREACH(plugins, i, plugins) { + const LilvPlugin* lv2_plug = lilv_plugins_get(plugins, i); + + const Raul::URI uri(lilv_node_as_uri(lilv_plugin_get_uri(lv2_plug))); + + if (_plugins.find(uri) != _plugins.end()) { + continue; + } + + LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri); + + plugin->lilv_plugin(lv2_plug); + _plugins.insert(make_pair(uri, plugin)); + } +} + +} // namespace Server +} // namespace Ingen diff --git a/src/server/BlockFactory.hpp b/src/server/BlockFactory.hpp new file mode 100644 index 00000000..a66b7913 --- /dev/null +++ b/src/server/BlockFactory.hpp @@ -0,0 +1,63 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_ENGINE_BLOCKFACTORY_HPP +#define INGEN_ENGINE_BLOCKFACTORY_HPP + +#include + +#include "ingen/World.hpp" +#include "raul/Noncopyable.hpp" +#include "raul/SharedPtr.hpp" +#include "raul/URI.hpp" + +namespace Ingen { +namespace Server { + +class PluginImpl; +class LV2Info; + +/** Discovers and loads plugin libraries. + * + * \ingroup engine + */ +class BlockFactory : public Raul::Noncopyable +{ +public: + explicit BlockFactory(Ingen::World* world); + ~BlockFactory(); + + void load_plugin(const Raul::URI& uri); + + typedef std::map Plugins; + const Plugins& plugins(); + + PluginImpl* plugin(const Raul::URI& uri); + +private: + void load_lv2_plugins(); + void load_internal_plugins(); + + Plugins _plugins; + Ingen::World* _world; + SharedPtr _lv2_info; + bool _has_loaded; +}; + +} // namespace Server +} // namespace Ingen + +#endif // INGEN_ENGINE_BLOCKFACTORY_HPP diff --git a/src/server/BlockImpl.cpp b/src/server/BlockImpl.cpp new file mode 100644 index 00000000..7d99ca28 --- /dev/null +++ b/src/server/BlockImpl.cpp @@ -0,0 +1,187 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include +#include + +#include "raul/Array.hpp" + +#include "Buffer.hpp" +#include "Engine.hpp" +#include "BlockImpl.hpp" +#include "PatchImpl.hpp" +#include "PluginImpl.hpp" +#include "PortImpl.hpp" +#include "ProcessContext.hpp" +#include "ThreadManager.hpp" + +using namespace std; + +namespace Ingen { +namespace Server { + +BlockImpl::BlockImpl(PluginImpl* plugin, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + SampleRate srate) + : GraphObjectImpl(plugin->uris(), parent, symbol) + , _plugin(plugin) + , _ports(NULL) + , _context(Context::AUDIO) + , _polyphony((polyphonic && parent) ? parent->internal_poly() : 1) + , _polyphonic(polyphonic) + , _activated(false) + , _traversed(false) +{ + assert(_plugin); + assert(_polyphony > 0); +} + +BlockImpl::~BlockImpl() +{ + if (_activated) { + deactivate(); + } + + if (is_linked()) { + parent_patch()->remove_block(*this); + } + + delete _ports; +} + +GraphObject* +BlockImpl::port(uint32_t index) const +{ + return (*_ports)[index]; +} + +const Plugin* +BlockImpl::plugin() const +{ + return _plugin; +} + +void +BlockImpl::activate(BufferFactory& bufs) +{ + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + + _activated = true; + for (uint32_t p = 0; p < num_ports(); ++p) { + PortImpl* const port = _ports->at(p); + port->setup_buffers(bufs, port->poly(), false); + port->connect_buffers(); + port->clear_buffers(); + } +} + +void +BlockImpl::deactivate() +{ + _activated = false; + for (uint32_t i = 0; i < _polyphony; ++i) { + for (uint32_t j = 0; j < num_ports(); ++j) { + PortImpl* const port = _ports->at(j); + if (port->is_output() && port->buffer(i)) + port->buffer(i)->clear(); + } + } +} + +bool +BlockImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) +{ + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + + if (!_polyphonic) + poly = 1; + + if (_ports) + for (uint32_t i = 0; i < _ports->size(); ++i) + _ports->at(i)->prepare_poly(bufs, poly); + + return true; +} + +bool +BlockImpl::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) +{ + if (!_polyphonic) + poly = 1; + + _polyphony = poly; + + if (_ports) + for (uint32_t i = 0; i < num_ports(); ++i) + _ports->at(i)->apply_poly(context, maid, poly); + + return true; +} + +void +BlockImpl::set_buffer_size(Context& context, + BufferFactory& bufs, + LV2_URID type, + uint32_t size) +{ + if (_ports) { + for (uint32_t i = 0; i < _ports->size(); ++i) { + PortImpl* const p = _ports->at(i); + if (p->buffer_type() == type) { + p->set_buffer_size(context, bufs, size); + } + } + } +} + +/** Prepare to run a cycle (in the audio thread) + */ +void +BlockImpl::pre_process(ProcessContext& context) +{ + // Mix down input ports + for (uint32_t i = 0; i < num_ports(); ++i) { + PortImpl* const port = _ports->at(i); + port->pre_process(context); + port->connect_buffers(); + } +} + +/** Prepare to run a cycle (in the audio thread) + */ +void +BlockImpl::post_process(ProcessContext& context) +{ + // Write output ports + for (uint32_t i = 0; _ports && i < _ports->size(); ++i) { + _ports->at(i)->post_process(context); + } +} + +void +BlockImpl::set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf) +{ + /*std::cout << path() << " set port " << port_num << " voice " << voice + << " buffer " << buf << " offset " << offset << std::endl;*/ +} + +} // namespace Server +} // namespace Ingen + diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp new file mode 100644 index 00000000..fd2af927 --- /dev/null +++ b/src/server/BlockImpl.hpp @@ -0,0 +1,175 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_ENGINE_NODEIMPL_HPP +#define INGEN_ENGINE_NODEIMPL_HPP + +#include + +#include + +#include "raul/Array.hpp" +#include "raul/AtomicInt.hpp" + +#include "BufferRef.hpp" +#include "Context.hpp" +#include "GraphObjectImpl.hpp" +#include "PortType.hpp" +#include "types.hpp" + +namespace Raul { +class Maid; +} + +namespace Ingen { + +class Plugin; + +namespace Server { + +class Buffer; +class BufferFactory; +class Context; +class PatchImpl; +class PluginImpl; +class PortImpl; +class ProcessContext; + +/** A Block in a Patch (which is also a Block). + * + * This is what is often called a "Module" in modular synthesizers. A Block is + * a unit with input/output ports, a process() method, and some other things. + * + * \ingroup engine + */ +class BlockImpl : public GraphObjectImpl + , public boost::intrusive::slist_base_hook<> // In PatchImpl +{ +public: + BlockImpl(PluginImpl* plugin, + const Raul::Symbol& symbol, + bool poly, + PatchImpl* parent, + SampleRate rate); + + virtual ~BlockImpl(); + + virtual GraphType graph_type() const { return BLOCK; } + + /** Activate this Block. + * + * This function must be called in a non-realtime thread before it is + * inserted in to a patch. Any non-realtime actions that need to be + * done before the Block is ready for use should be done here. + */ + virtual void activate(BufferFactory& bufs); + + /** Deactivate this Block. + * + * This function must be called in a non-realtime thread after the + * block has been removed from its patch (i.e. processing is finished). + */ + virtual void deactivate(); + + /** Return true iff this block is activated */ + bool activated() { return _activated; } + + /** Learn the next incoming MIDI event (for internals) */ + virtual void learn() {} + + /** Do whatever needs doing in the process thread before process() is called */ + virtual void pre_process(ProcessContext& context); + + /** Run the block for @a nframes input/output. + * + * @a start and @a end are transport times: end is not redundant in the case + * of varispeed, where end-start != nframes. + */ + virtual void process(ProcessContext& context) = 0; + + /** Do whatever needs doing in the process thread after process() is called */ + virtual void post_process(ProcessContext& context); + + /** Set the buffer of a port to a given buffer (e.g. connect plugin to buffer) */ + virtual void set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf); + + virtual GraphObject* port(uint32_t index) const; + virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; } + + /** Blocks that are connected to this Block's inputs. */ + std::list& providers() { return _providers; } + + /** Blocks are are connected to this Block's outputs. */ + std::list& dependants() { return _dependants; } + + /** Flag block as polyphonic. + * + * Note this will not actually allocate voices etc., prepare_poly + * and apply_poly must be called after this function to truly make + * a block polyphonic. + */ + virtual void set_polyphonic(bool p) { _polyphonic = p; } + + virtual bool prepare_poly(BufferFactory& bufs, uint32_t poly); + virtual bool apply_poly( + ProcessContext& context, Raul::Maid& maid, uint32_t poly); + + /** Information about the Plugin this Block is an instance of. + * Not the best name - not all blocks come from plugins (e.g. Patch) + */ + virtual PluginImpl* plugin_impl() const { return _plugin; } + + /** Information about the Plugin this Block is an instance of. + * Not the best name - not all blocks come from plugins (ie Patch) + */ + virtual const Plugin* plugin() const; + + virtual void plugin(PluginImpl* pi) { _plugin = pi; } + + virtual void set_buffer_size(Context& context, + BufferFactory& bufs, + LV2_URID type, + uint32_t size); + + /** The Patch this Block belongs to. */ + inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; } + + Context::ID context() const { return _context; } + uint32_t num_ports() const { return _ports ? _ports->size() : 0; } + virtual uint32_t polyphony() const { return _polyphony; } + + /** Used by the process order finding algorithm (ie during connections) */ + bool traversed() const { return _traversed; } + void traversed(bool b) { _traversed = b; } + +protected: + PluginImpl* _plugin; + Raul::Array* _ports; ///< Access in audio thread only + Context::ID _context; ///< Context this block runs in + uint32_t _polyphony; + std::list _providers; ///< Blocks connected to this one's input ports + std::list _dependants; ///< Blocks this one's output ports are connected to + bool _polyphonic; + bool _activated; + bool _traversed; ///< Flag for process order algorithm +}; + +} // namespace Server +} // namespace Ingen + +#endif // INGEN_ENGINE_BLOCKIMPL_HPP diff --git a/src/server/Broadcaster.cpp b/src/server/Broadcaster.cpp index 33ee5369..ab6b16fb 100644 --- a/src/server/Broadcaster.cpp +++ b/src/server/Broadcaster.cpp @@ -21,7 +21,7 @@ #include "Broadcaster.hpp" #include "PluginImpl.hpp" -#include "NodeFactory.hpp" +#include "BlockFactory.hpp" namespace Ingen { namespace Server { @@ -64,7 +64,7 @@ Broadcaster::client(const Raul::URI& uri) } void -Broadcaster::send_plugins(const NodeFactory::Plugins& plugins) +Broadcaster::send_plugins(const BlockFactory::Plugins& plugins) { Glib::Mutex::Lock lock(_clients_mutex); for (Clients::const_iterator c = _clients.begin(); c != _clients.end(); ++c) { @@ -73,12 +73,12 @@ Broadcaster::send_plugins(const NodeFactory::Plugins& plugins) } void -Broadcaster::send_plugins_to(Interface* client, - const NodeFactory::Plugins& plugins) +Broadcaster::send_plugins_to(Interface* client, + const BlockFactory::Plugins& plugins) { client->bundle_begin(); - for (NodeFactory::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { + for (BlockFactory::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { const PluginImpl* const plugin = i->second; client->put(plugin->uri(), plugin->properties()); } diff --git a/src/server/Broadcaster.hpp b/src/server/Broadcaster.hpp index 507e8eec..0bc7576a 100644 --- a/src/server/Broadcaster.hpp +++ b/src/server/Broadcaster.hpp @@ -27,7 +27,7 @@ #include "ingen/Interface.hpp" -#include "NodeFactory.hpp" +#include "BlockFactory.hpp" namespace Ingen { namespace Server { @@ -47,8 +47,8 @@ public: SharedPtr client(const Raul::URI& uri); - void send_plugins(const NodeFactory::Plugins& plugin_list); - void send_plugins_to(Interface*, const NodeFactory::Plugins& plugin_list); + void send_plugins(const BlockFactory::Plugins& plugin_list); + void send_plugins_to(Interface*, const BlockFactory::Plugins& plugin_list); #define BROADCAST(msg, ...) \ Glib::Mutex::Lock lock(_clients_mutex); \ diff --git a/src/server/CompiledPatch.hpp b/src/server/CompiledPatch.hpp index 7f973792..15d1137a 100644 --- a/src/server/CompiledPatch.hpp +++ b/src/server/CompiledPatch.hpp @@ -27,42 +27,42 @@ namespace Ingen { namespace Server { class EdgeImpl; -class NodeImpl; +class BlockImpl; -/** All information required about a node to execute it in an audio thread. +/** All information required about a block to execute it in an audio thread. */ -class CompiledNode { +class CompiledBlock { public: - CompiledNode(NodeImpl* n, size_t np, const std::list& d) - : _node(n), _n_providers(np) + CompiledBlock(BlockImpl* b, size_t np, const std::list& d) + : _block(b), _n_providers(np) { // Copy to a vector for maximum iteration speed and cache optimization // (Need to take a copy anyway) _dependants.reserve(d.size()); - for (std::list::const_iterator i = d.begin(); i != d.end(); ++i) + for (std::list::const_iterator i = d.begin(); i != d.end(); ++i) _dependants.push_back(*i); } - NodeImpl* node() const { return _node; } - size_t n_providers() const { return _n_providers; } - const std::vector& dependants() const { return _dependants; } + BlockImpl* block() const { return _block; } + size_t n_providers() const { return _n_providers; } + const std::vector& dependants() const { return _dependants; } private: - NodeImpl* _node; - size_t _n_providers; ///< Number of input ready signals to trigger run - std::vector _dependants; ///< Nodes this one's output ports are connected to + BlockImpl* _block; + size_t _n_providers; ///< Number of input ready signals to trigger run + std::vector _dependants; ///< Blocks this one's output ports are connected to }; /** A patch ``compiled'' into a flat structure with the correct order so * the audio thread(s) can execute it without threading problems (since * the preprocessor thread modifies the graph). * - * The nodes contained here are sorted in the order they must be executed. - * The parallel processing algorithm guarantees no node will be executed + * The blocks contained here are sorted in the order they must be executed. + * The parallel processing algorithm guarantees no block will be executed * before its providers, using this order as well as semaphores. */ -class CompiledPatch : public std::vector +class CompiledPatch : public std::vector , public Raul::Disposable , public Raul::Noncopyable { diff --git a/src/server/Driver.hpp b/src/server/Driver.hpp index 1d6e7ef0..e038b2bc 100644 --- a/src/server/Driver.hpp +++ b/src/server/Driver.hpp @@ -34,9 +34,10 @@ class EnginePort; /** Engine driver base class. * - * A Driver is, from the perspective of GraphObjects (nodes, patches, ports) an - * interface for managing system ports. An implementation of Driver basically - * needs to manage EnginePorts, and handle writing/reading data to/from them. + * A Driver is, from the perspective of GraphObjects (blocks, patches, ports) + * an interface for managing system ports. An implementation of Driver + * basically needs to manage EnginePorts, and handle writing/reading data + * to/from them. * * \ingroup engine */ diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp index f28831ff..43197844 100644 --- a/src/server/DuplexPort.cpp +++ b/src/server/DuplexPort.cpp @@ -27,7 +27,7 @@ namespace Ingen { namespace Server { DuplexPort::DuplexPort(BufferFactory& bufs, - NodeImpl* parent, + BlockImpl* parent, const Raul::Symbol& symbol, uint32_t index, bool polyphonic, @@ -85,8 +85,8 @@ DuplexPort::pre_process(Context& context) } } else { /* This is a a patch input, which is an output from the internal - perspective. Do whatever a normal node's input port does to prepare - input for reading. */ + perspective. Do whatever a normal block's input port does to + prepare input for reading. */ InputPort::pre_process(context); } } diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp index 90146e40..25d389c5 100644 --- a/src/server/DuplexPort.hpp +++ b/src/server/DuplexPort.hpp @@ -26,14 +26,14 @@ namespace Ingen { namespace Server { -class NodeImpl; +class BlockImpl; /** A duplex Port (both an InputPort and an OutputPort on a Patch) * * This is used for Patch ports, since they need to appear as both an input and * an output port based on context. There are no actual duplex ports in Ingen, * a Port is either an Input or Output. This class only exists to allow Patch - * outputs to appear as inputs to Nodes inside that patch, and vice versa. + * outputs to appear as inputs from within that Patch, and vice versa. * * \ingroup engine */ @@ -43,7 +43,7 @@ class DuplexPort : public InputPort { public: DuplexPort(BufferFactory& bufs, - NodeImpl* parent, + BlockImpl* parent, const Raul::Symbol& symbol, uint32_t index, bool polyphonic, diff --git a/src/server/EdgeImpl.cpp b/src/server/EdgeImpl.cpp index 23b840d4..08096d45 100644 --- a/src/server/EdgeImpl.cpp +++ b/src/server/EdgeImpl.cpp @@ -17,29 +17,27 @@ #include "ingen/URIs.hpp" #include "lv2/lv2plug.in/ns/ext/atom/util.h" +#include "BlockImpl.hpp" #include "Buffer.hpp" #include "BufferFactory.hpp" #include "EdgeImpl.hpp" #include "Engine.hpp" #include "InputPort.hpp" -#include "NodeImpl.hpp" #include "OutputPort.hpp" #include "PortImpl.hpp" namespace Ingen { namespace Server { -/** Constructor for a edge from a node's output port. +/** Constructor for a edge from a block's output port. * - * This handles both polyphonic and monophonic nodes, transparently to the + * This handles both polyphonic and monophonic blocks, transparently to the * user (InputPort). */ EdgeImpl::EdgeImpl(PortImpl* tail, PortImpl* head) : _tail(tail) , _head(head) { - assert(tail); - assert(head); assert(tail != head); assert(tail->path() != head->path()); } diff --git a/src/server/EdgeImpl.hpp b/src/server/EdgeImpl.hpp index 4a4553b1..0627a7ba 100644 --- a/src/server/EdgeImpl.hpp +++ b/src/server/EdgeImpl.hpp @@ -38,7 +38,7 @@ class InputPort; /** Represents a single inbound connection for an InputPort. * - * This can be a group of ports (ie coming from a polyphonic Node) or + * This can be a group of ports (coming from a polyphonic Block) or * a single Port. This class exists basically as an abstraction of mixing * down polyphonic inputs, so InputPort can just deal with mixing down * multiple connections (oblivious to the polyphonic situation of the diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp index 4efb9f5e..eada608a 100644 --- a/src/server/Engine.cpp +++ b/src/server/Engine.cpp @@ -25,15 +25,15 @@ #include "raul/Maid.hpp" #include "raul/SharedPtr.hpp" +#include "BlockFactory.hpp" #include "Broadcaster.hpp" #include "BufferFactory.hpp" -#include "DirectDriver.hpp" #include "ControlBindings.hpp" +#include "DirectDriver.hpp" #include "Driver.hpp" #include "Engine.hpp" #include "Event.hpp" #include "EventWriter.hpp" -#include "NodeFactory.hpp" #include "PatchImpl.hpp" #include "PostProcessor.hpp" #include "PreProcessor.hpp" @@ -51,11 +51,11 @@ bool ThreadManager::single_threaded(true); Engine::Engine(Ingen::World* world) : _world(world) + , _block_factory(new BlockFactory(world)) , _broadcaster(new Broadcaster()) , _buffer_factory(new BufferFactory(*this, world->uris())) , _control_bindings(NULL) , _maid(new Raul::Maid()) - , _node_factory(new NodeFactory(world)) , _pre_processor(new PreProcessor()) , _post_processor(new PostProcessor(*this)) , _event_writer(new EventWriter(*this)) @@ -92,7 +92,7 @@ Engine::~Engine() delete _maid; delete _pre_processor; delete _post_processor; - delete _node_factory; + delete _block_factory; delete _control_bindings; delete _broadcaster; delete _event_writer; diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp index ca844261..66930938 100644 --- a/src/server/Engine.hpp +++ b/src/server/Engine.hpp @@ -40,7 +40,7 @@ class ControlBindings; class Driver; class Event; class EventWriter; -class NodeFactory; +class BlockFactory; class PostProcessor; class PreProcessor; class ProcessContext; @@ -92,12 +92,12 @@ public: Ingen::World* world() const { return _world; } EventWriter* interface() const { return _event_writer; } + BlockFactory* block_factory() const { return _block_factory; } Broadcaster* broadcaster() const { return _broadcaster; } BufferFactory* buffer_factory() const { return _buffer_factory; } ControlBindings* control_bindings() const { return _control_bindings; } Driver* driver() const { return _driver.get(); } Log& log() const { return _world->log(); } - NodeFactory* node_factory() const { return _node_factory; } PatchImpl* root_patch() const { return _root_patch; } PostProcessor* post_processor() const { return _post_processor; } Raul::Maid* maid() const { return _maid; } @@ -112,12 +112,12 @@ public: private: Ingen::World* _world; + BlockFactory* _block_factory; Broadcaster* _broadcaster; BufferFactory* _buffer_factory; ControlBindings* _control_bindings; SharedPtr _driver; Raul::Maid* _maid; - NodeFactory* _node_factory; PreProcessor* _pre_processor; PostProcessor* _post_processor; EventWriter* _event_writer; diff --git a/src/server/GraphObjectImpl.cpp b/src/server/GraphObjectImpl.cpp index 212e5196..d5608b0f 100644 --- a/src/server/GraphObjectImpl.cpp +++ b/src/server/GraphObjectImpl.cpp @@ -45,7 +45,7 @@ GraphObjectImpl::get_property(const Raul::URI& key) const PatchImpl* GraphObjectImpl::parent_patch() const { - return dynamic_cast((NodeImpl*)_parent); + return dynamic_cast((BlockImpl*)_parent); } } // namespace Server diff --git a/src/server/GraphObjectImpl.hpp b/src/server/GraphObjectImpl.hpp index bfc97fb1..5388981f 100644 --- a/src/server/GraphObjectImpl.hpp +++ b/src/server/GraphObjectImpl.hpp @@ -40,7 +40,7 @@ class Context; class ProcessContext; class BufferFactory; -/** An object on the audio graph - Patch, Node, Port, etc. +/** An object on the audio graph (a Patch, Block, or Port). * * Each of these is a Raul::Deletable and so can be deleted in a realtime safe * way from anywhere, and they all have a map of variable for clients to store diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp index 0bce5b93..fff29f30 100644 --- a/src/server/InputPort.cpp +++ b/src/server/InputPort.cpp @@ -20,12 +20,12 @@ #include "ingen/Log.hpp" #include "ingen/URIs.hpp" +#include "BlockImpl.hpp" #include "Buffer.hpp" #include "BufferFactory.hpp" #include "EdgeImpl.hpp" #include "Engine.hpp" #include "InputPort.hpp" -#include "NodeImpl.hpp" #include "OutputPort.hpp" #include "PatchImpl.hpp" #include "ProcessContext.hpp" @@ -37,7 +37,7 @@ namespace Ingen { namespace Server { InputPort::InputPort(BufferFactory& bufs, - NodeImpl* parent, + BlockImpl* parent, const Raul::Symbol& symbol, uint32_t index, uint32_t poly, @@ -159,7 +159,7 @@ InputPort::remove_edge(ProcessContext& context, const OutputPort* tail) uint32_t InputPort::max_tail_poly(Context& context) const { - return parent_node()->parent_patch()->internal_poly_process(); + return parent_block()->parent_patch()->internal_poly_process(); } static void diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp index d4d565af..40650415 100644 --- a/src/server/InputPort.hpp +++ b/src/server/InputPort.hpp @@ -32,11 +32,11 @@ namespace Server { class EdgeImpl; class Context; -class NodeImpl; +class BlockImpl; class OutputPort; class ProcessContext; -/** An input port on a Node or Patch. +/** An input port on a Block or Patch. * * All ports have a Buffer, but the actual contents (data) of that buffer may be * set directly to the incoming edge's buffer if there's only one inbound @@ -51,7 +51,7 @@ class InputPort : virtual public PortImpl { public: InputPort(BufferFactory& bufs, - NodeImpl* parent, + BlockImpl* parent, const Raul::Symbol& symbol, uint32_t index, uint32_t poly, diff --git a/src/server/InternalPlugin.cpp b/src/server/InternalPlugin.cpp index 60a5699c..0e15fd9d 100644 --- a/src/server/InternalPlugin.cpp +++ b/src/server/InternalPlugin.cpp @@ -42,7 +42,7 @@ InternalPlugin::InternalPlugin(URIs& uris, set_property(uris.rdf_type, uris.ingen_Internal); } -NodeImpl* +BlockImpl* InternalPlugin::instantiate(BufferFactory& bufs, const Raul::Symbol& symbol, bool polyphonic, diff --git a/src/server/InternalPlugin.hpp b/src/server/InternalPlugin.hpp index bb90f5e6..29753c69 100644 --- a/src/server/InternalPlugin.hpp +++ b/src/server/InternalPlugin.hpp @@ -29,7 +29,7 @@ namespace Ingen { namespace Server { -class NodeImpl; +class BlockImpl; class BufferFactory; /** Implementation of an Internal plugin. @@ -41,11 +41,11 @@ public: const Raul::URI& uri, const Raul::Symbol& symbol); - NodeImpl* instantiate(BufferFactory& bufs, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - Engine& engine); + BlockImpl* instantiate(BufferFactory& bufs, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + Engine& engine); const Raul::Symbol symbol() const { return _symbol; } diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp new file mode 100644 index 00000000..d26f7417 --- /dev/null +++ b/src/server/LV2Block.cpp @@ -0,0 +1,469 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include + +#include +#include + +#include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" +#include "lv2/lv2plug.in/ns/ext/morph/morph.h" + +#include "raul/Maid.hpp" +#include "raul/Array.hpp" + +#include "ingen/Log.hpp" +#include "ingen/URIMap.hpp" +#include "ingen/URIs.hpp" + +#include "Buffer.hpp" +#include "Driver.hpp" +#include "Engine.hpp" +#include "InputPort.hpp" +#include "LV2Block.hpp" +#include "LV2Plugin.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "ProcessContext.hpp" + +using namespace std; + +namespace Ingen { +namespace Server { + +/** Partially construct a LV2Block. + * + * Object is not usable until instantiate() is called with success. + * (It _will_ crash!) + */ +LV2Block::LV2Block(LV2Plugin* plugin, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + SampleRate srate) +: BlockImpl(plugin, symbol, polyphonic, parent, srate) + , _lv2_plugin(plugin) + , _instances(NULL) + , _prepared_instances(NULL) + , _worker_iface(NULL) +{ + assert(_lv2_plugin); +} + +LV2Block::~LV2Block() +{ + delete _instances; +} + +SharedPtr +LV2Block::make_instance(URIs& uris, + SampleRate rate, + uint32_t voice, + bool preparing) +{ + LilvInstance* inst = lilv_plugin_instantiate( + _lv2_plugin->lilv_plugin(), rate, _features->array()); + + if (!inst) { + parent_patch()->engine().log().error( + Raul::fmt("Failed to instantiate <%1%>\n") + % _lv2_plugin->uri().c_str()); + return SharedPtr(); + } + + const LV2_Morph_Interface* morph_iface = (const LV2_Morph_Interface*) + lilv_instance_get_extension_data(inst, LV2_MORPH__interface); + + for (uint32_t p = 0; p < num_ports(); ++p) { + PortImpl* const port = _ports->at(p); + Buffer* const buffer = (preparing) + ? port->prepared_buffer(voice).get() + : port->buffer(voice).get(); + if (port->is_morph() && port->is_a(PortType::CV)) { + if (morph_iface) { + morph_iface->morph_port( + inst->lv2_handle, p, uris.lv2_CVPort, NULL); + } + } + + if (buffer) { + if (port->is_a(PortType::CV) || port->is_a(PortType::CONTROL)) { + buffer->set_block(port->value().get_float(), 0, buffer->nframes()); + } else { + buffer->clear(); + } + } + } + + if (morph_iface) { + for (uint32_t p = 0; p < num_ports(); ++p) { + PortImpl* const port = _ports->at(p); + if (port->is_auto_morph()) { + LV2_URID type = morph_iface->port_type( + inst->lv2_handle, p, NULL); + if (type == _uris.lv2_ControlPort) { + port->set_type(PortType::CONTROL, 0); + } else if (type == _uris.lv2_CVPort) { + port->set_type(PortType::CV, 0); + } else { + parent_patch()->engine().log().error( + Raul::fmt("%1% auto-morphed to unknown type %2%\n") + % port->path().c_str() % type); + return SharedPtr(); + } + } + } + } + + return SharedPtr(inst, lilv_instance_free); +} + +bool +LV2Block::prepare_poly(BufferFactory& bufs, uint32_t poly) +{ + if (!_polyphonic) + poly = 1; + + BlockImpl::prepare_poly(bufs, poly); + + if (_polyphony == poly) + return true; + + const SampleRate rate = bufs.engine().driver()->sample_rate(); + assert(!_prepared_instances); + _prepared_instances = new Instances(poly, *_instances, SharedPtr()); + for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { + SharedPtr inst = make_instance(bufs.uris(), rate, i, true); + if (!inst) { + return false; + } + + _prepared_instances->at(i) = inst; + + if (_activated) { + lilv_instance_activate(inst.get()); + } + } + + return true; +} + +bool +LV2Block::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) +{ + if (!_polyphonic) + poly = 1; + + if (_prepared_instances) { + maid.dispose(_instances); + _instances = _prepared_instances; + _prepared_instances = NULL; + } + assert(poly <= _instances->size()); + + return BlockImpl::apply_poly(context, maid, poly); +} + +/** Instantiate self from LV2 plugin descriptor. + * + * Implemented as a seperate function (rather than in the constructor) to + * allow graceful error-catching of broken plugins. + * + * Returns whether or not plugin was successfully instantiated. If return + * value is false, this object may not be used. + */ +bool +LV2Block::instantiate(BufferFactory& bufs) +{ + const Ingen::URIs& uris = bufs.uris(); + SharedPtr info = _lv2_plugin->lv2_info(); + const LilvPlugin* plug = _lv2_plugin->lilv_plugin(); + Ingen::Forge& forge = bufs.forge(); + const uint32_t num_ports = lilv_plugin_get_num_ports(plug); + + _ports = new Raul::Array(num_ports, NULL); + + bool ret = true; + + float* min_values = new float[num_ports]; + float* max_values = new float[num_ports]; + float* def_values = new float[num_ports]; + lilv_plugin_get_port_ranges_float(plug, min_values, max_values, def_values); + + // Get all the necessary information about ports + for (uint32_t j = 0; j < num_ports; ++j) { + const LilvPort* id = lilv_plugin_get_port_by_index(plug, j); + + /* LV2 port symbols are guaranteed to be unique, valid C identifiers, + and Lilv guarantees that lilv_port_get_symbol() is valid. */ + const Raul::Symbol port_sym( + lilv_node_as_string(lilv_port_get_symbol(plug, id))); + + // Get port type + Raul::Atom val; + PortType port_type = PortType::UNKNOWN; + LV2_URID buffer_type = 0; + bool is_morph = false; + bool is_auto_morph = false; + if (lilv_port_is_a(plug, id, info->lv2_ControlPort)) { + if (lilv_port_is_a(plug, id, info->morph_MorphPort)) { + is_morph = true; + LilvNodes* types = lilv_port_get_value( + plug, id, info->morph_supportsType); + LILV_FOREACH(nodes, i, types) { + const LilvNode* type = lilv_nodes_get(types, i); + if (lilv_node_equals(type, info->lv2_CVPort)) { + port_type = PortType::CV; + buffer_type = uris.atom_Sound; + } + } + lilv_nodes_free(types); + } + if (port_type == PortType::UNKNOWN) { + port_type = PortType::CONTROL; + buffer_type = uris.atom_Float; + } + } else if (lilv_port_is_a(plug, id, info->lv2_CVPort)) { + port_type = PortType::CV; + buffer_type = uris.atom_Sound; + } else if (lilv_port_is_a(plug, id, info->lv2_AudioPort)) { + port_type = PortType::AUDIO; + buffer_type = uris.atom_Sound; + } else if (lilv_port_is_a(plug, id, info->atom_AtomPort)) { + port_type = PortType::ATOM; + } + + if (lilv_port_is_a(plug, id, info->morph_AutoMorphPort)) { + is_auto_morph = true; + } + + // Get buffer type if necessary (atom ports) + if (!buffer_type) { + LilvNodes* types = lilv_port_get_value( + plug, id, info->atom_bufferType); + LILV_FOREACH(nodes, i, types) { + const LilvNode* type = lilv_nodes_get(types, i); + if (lilv_node_is_uri(type)) { + buffer_type = bufs.engine().world()->uri_map().map_uri( + lilv_node_as_uri(type)); + } + } + lilv_nodes_free(types); + } + + uint32_t port_buffer_size = bufs.default_size(buffer_type); + + if (port_type == PortType::ATOM) { + // Get default value, and its length + LilvNodes* defaults = lilv_port_get_value(plug, id, info->lv2_default); + LILV_FOREACH(nodes, i, defaults) { + const LilvNode* d = lilv_nodes_get(defaults, i); + if (lilv_node_is_string(d)) { + const char* str_val = lilv_node_as_string(d); + const uint32_t str_val_len = strlen(str_val); + val = forge.alloc(str_val); + port_buffer_size = std::max(port_buffer_size, str_val_len); + } + } + lilv_nodes_free(defaults); + + // Get minimum size, if set in data + LilvNodes* sizes = lilv_port_get_value(plug, id, info->rsz_minimumSize); + LILV_FOREACH(nodes, i, sizes) { + const LilvNode* d = lilv_nodes_get(sizes, i); + if (lilv_node_is_int(d)) { + uint32_t size_val = lilv_node_as_int(d); + port_buffer_size = std::max(port_buffer_size, size_val); + } + } + lilv_nodes_free(sizes); + + bufs.engine().log().info( + Raul::fmt("Atom port %1% buffer size %2%\n") + % path().c_str() % port_buffer_size); + } + + enum { UNKNOWN, INPUT, OUTPUT } direction = UNKNOWN; + if (lilv_port_is_a(plug, id, info->lv2_InputPort)) { + direction = INPUT; + } else if (lilv_port_is_a(plug, id, info->lv2_OutputPort)) { + direction = OUTPUT; + } + + if (port_type == PortType::UNKNOWN || direction == UNKNOWN) { + parent_patch()->engine().log().error( + Raul::fmt("<%1%> port %2% has unknown type or direction\n") + % _lv2_plugin->uri().c_str() % port_sym.c_str()); + ret = false; + break; + } + + if (!val.type()) + val = forge.make(isnan(def_values[j]) ? 0.0f : def_values[j]); + + PortImpl* port = (direction == INPUT) + ? static_cast( + new InputPort(bufs, this, port_sym, j, _polyphony, + port_type, buffer_type, val)) + : static_cast( + new OutputPort(bufs, this, port_sym, j, _polyphony, + port_type, buffer_type, val)); + + port->set_morphable(is_morph, is_auto_morph); + if (direction == INPUT && (port_type == PortType::CONTROL + || port_type == PortType::CV)) { + port->set_value(val); + if (!isnan(min_values[j])) { + port->set_property(uris.lv2_minimum, forge.make(min_values[j])); + port->set_minimum(forge.make(min_values[j])); + } + if (!isnan(max_values[j])) { + port->set_property(uris.lv2_maximum, forge.make(max_values[j])); + port->set_maximum(forge.make(max_values[j])); + } + } + + // Inherit certain properties from plugin port + LilvNode* preds[] = { info->lv2_portProperty, info->atom_supports, 0 }; + for (int p = 0; preds[p]; ++p) { + LilvNodes* values = lilv_port_get_value(plug, id, preds[p]); + LILV_FOREACH(nodes, v, values) { + const LilvNode* val = lilv_nodes_get(values, v); + if (lilv_node_is_uri(val)) { + port->add_property(Raul::URI(lilv_node_as_uri(preds[p])), + forge.alloc_uri(lilv_node_as_uri(val))); + } + } + lilv_nodes_free(values); + } + + port->cache_properties(); + + _ports->at(j) = port; + } + + delete[] min_values; + delete[] max_values; + delete[] def_values; + + if (!ret) { + delete _ports; + _ports = NULL; + return ret; + } + + _features = info->world().lv2_features().lv2_features(&info->world(), this); + + // Actually create plugin instances and port buffers. + const SampleRate rate = bufs.engine().driver()->sample_rate(); + _instances = new Instances(_polyphony, SharedPtr()); + for (uint32_t i = 0; i < _polyphony; ++i) { + _instances->at(i) = make_instance(bufs.uris(), rate, i, false); + if (!_instances->at(i)) { + return false; + } + } + + // FIXME: Polyphony + worker? + if (lilv_plugin_has_feature(plug, info->work_schedule)) { + _worker_iface = (const LV2_Worker_Interface*) + lilv_instance_get_extension_data(instance(0), + LV2_WORKER__interface); + } + + return ret; +} + +void +LV2Block::activate(BufferFactory& bufs) +{ + BlockImpl::activate(bufs); + + for (uint32_t i = 0; i < _polyphony; ++i) + lilv_instance_activate(instance(i)); +} + +void +LV2Block::deactivate() +{ + BlockImpl::deactivate(); + + for (uint32_t i = 0; i < _polyphony; ++i) + lilv_instance_deactivate(instance(i)); +} + +LV2_Worker_Status +LV2Block::work_respond(LV2_Worker_Respond_Handle handle, + uint32_t size, + const void* data) +{ + LV2Block* block = (LV2Block*)handle; + LV2Block::Response* r = new LV2Block::Response(size, data); + block->_responses.push_back(*r); + return LV2_WORKER_SUCCESS; +} + +void +LV2Block::work(uint32_t size, const void* data) +{ + if (_worker_iface) { + LV2_Handle inst = lilv_instance_get_handle(instance(0)); + if (_worker_iface->work(inst, work_respond, this, size, data)) { + parent_patch()->engine().log().error( + Raul::fmt("Error calling %1% work method\n") % _path); + } + } +} + +void +LV2Block::process(ProcessContext& context) +{ + BlockImpl::pre_process(context); + + for (uint32_t i = 0; i < _polyphony; ++i) + lilv_instance_run(instance(i), context.nframes()); + + if (_worker_iface) { + LV2_Handle inst = lilv_instance_get_handle(instance(0)); + while (!_responses.empty()) { + Response& r = _responses.front(); + _worker_iface->work_response(inst, r.size, r.data); + _responses.pop_front(); + context.engine().maid()->dispose(&r); + } + + if (_worker_iface->end_run) { + _worker_iface->end_run(inst); + } + } + + BlockImpl::post_process(context); +} + +void +LV2Block::set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf) +{ + BlockImpl::set_port_buffer(voice, port_num, buf); + lilv_instance_connect_port( + instance(voice), port_num, + buf ? buf->port_data(_ports->at(port_num)->type()) : NULL); +} + +} // namespace Server +} // namespace Ingen + diff --git a/src/server/LV2Block.hpp b/src/server/LV2Block.hpp new file mode 100644 index 00000000..3746b201 --- /dev/null +++ b/src/server/LV2Block.hpp @@ -0,0 +1,116 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_ENGINE_LV2BLOCK_HPP +#define INGEN_ENGINE_LV2BLOCK_HPP + +#include "lilv/lilv.h" +#include "lv2/lv2plug.in/ns/ext/worker/worker.h" +#include "raul/Disposable.hpp" + +#include "BufferRef.hpp" +#include "BlockImpl.hpp" +#include "ingen/LV2Features.hpp" +#include "types.hpp" + +namespace Ingen { +namespace Server { + +class LV2Plugin; + +/** An instance of a LV2 plugin. + * + * \ingroup engine + */ +class LV2Block : public BlockImpl +{ +public: + LV2Block(LV2Plugin* plugin, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + SampleRate srate); + + ~LV2Block(); + + bool instantiate(BufferFactory& bufs); + + bool prepare_poly(BufferFactory& bufs, uint32_t poly); + bool apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly); + + void activate(BufferFactory& bufs); + void deactivate(); + + void work(uint32_t size, const void* data); + + void process(ProcessContext& context); + + void set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf); + +protected: + SharedPtr make_instance(URIs& uris, + SampleRate rate, + uint32_t voice, + bool preparing); + + inline LilvInstance* instance(uint32_t voice) { + return (LilvInstance*)(*_instances)[voice].get(); + } + + typedef Raul::Array< SharedPtr > Instances; + + struct Response : public Raul::Disposable + , public Raul::Noncopyable + , public boost::intrusive::slist_base_hook<> + { + inline Response(uint32_t s, const void* d) + : size(s) + , data(malloc(s)) + { + memcpy(data, d, s); + } + + ~Response() { + free(data); + } + + const uint32_t size; + void* const data; + }; + + typedef boost::intrusive::slist, + boost::intrusive::constant_time_size + > Responses; + + static LV2_Worker_Status work_respond( + LV2_Worker_Respond_Handle handle, uint32_t size, const void* data); + + LV2Plugin* _lv2_plugin; + Instances* _instances; + Instances* _prepared_instances; + const LV2_Worker_Interface* _worker_iface; + Responses _responses; + SharedPtr _features; +}; + +} // namespace Server +} // namespace Ingen + +#endif // INGEN_ENGINE_LV2BLOCK_HPP + diff --git a/src/server/LV2Node.cpp b/src/server/LV2Node.cpp deleted file mode 100644 index 654aeab0..00000000 --- a/src/server/LV2Node.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#include - -#include -#include - -#include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" -#include "lv2/lv2plug.in/ns/ext/morph/morph.h" - -#include "raul/Maid.hpp" -#include "raul/Array.hpp" - -#include "ingen/Log.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/URIs.hpp" - -#include "Buffer.hpp" -#include "Driver.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "LV2Node.hpp" -#include "LV2Plugin.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { -namespace Server { - -/** Partially construct a LV2Node. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LV2Node::LV2Node(LV2Plugin* plugin, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - SampleRate srate) - : NodeImpl(plugin, symbol, polyphonic, parent, srate) - , _lv2_plugin(plugin) - , _instances(NULL) - , _prepared_instances(NULL) - , _worker_iface(NULL) -{ - assert(_lv2_plugin); -} - -LV2Node::~LV2Node() -{ - delete _instances; -} - -SharedPtr -LV2Node::make_instance(URIs& uris, - SampleRate rate, - uint32_t voice, - bool preparing) -{ - LilvInstance* inst = lilv_plugin_instantiate( - _lv2_plugin->lilv_plugin(), rate, _features->array()); - - if (!inst) { - parent_patch()->engine().log().error( - Raul::fmt("Failed to instantiate <%1%>\n") - % _lv2_plugin->uri().c_str()); - return SharedPtr(); - } - - const LV2_Morph_Interface* morph_iface = (const LV2_Morph_Interface*) - lilv_instance_get_extension_data(inst, LV2_MORPH__interface); - - for (uint32_t p = 0; p < num_ports(); ++p) { - PortImpl* const port = _ports->at(p); - Buffer* const buffer = (preparing) - ? port->prepared_buffer(voice).get() - : port->buffer(voice).get(); - if (port->is_morph() && port->is_a(PortType::CV)) { - if (morph_iface) { - morph_iface->morph_port( - inst->lv2_handle, p, uris.lv2_CVPort, NULL); - } - } - - if (buffer) { - if (port->is_a(PortType::CV) || port->is_a(PortType::CONTROL)) { - buffer->set_block(port->value().get_float(), 0, buffer->nframes()); - } else { - buffer->clear(); - } - } - } - - if (morph_iface) { - for (uint32_t p = 0; p < num_ports(); ++p) { - PortImpl* const port = _ports->at(p); - if (port->is_auto_morph()) { - LV2_URID type = morph_iface->port_type( - inst->lv2_handle, p, NULL); - if (type == _uris.lv2_ControlPort) { - port->set_type(PortType::CONTROL, 0); - } else if (type == _uris.lv2_CVPort) { - port->set_type(PortType::CV, 0); - } else { - parent_patch()->engine().log().error( - Raul::fmt("%1% auto-morphed to unknown type %2%\n") - % port->path().c_str() % type); - return SharedPtr(); - } - } - } - } - - return SharedPtr(inst, lilv_instance_free); -} - -bool -LV2Node::prepare_poly(BufferFactory& bufs, uint32_t poly) -{ - if (!_polyphonic) - poly = 1; - - NodeImpl::prepare_poly(bufs, poly); - - if (_polyphony == poly) - return true; - - const SampleRate rate = bufs.engine().driver()->sample_rate(); - assert(!_prepared_instances); - _prepared_instances = new Instances(poly, *_instances, SharedPtr()); - for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - SharedPtr inst = make_instance(bufs.uris(), rate, i, true); - if (!inst) { - return false; - } - - _prepared_instances->at(i) = inst; - - if (_activated) { - lilv_instance_activate(inst.get()); - } - } - - return true; -} - -bool -LV2Node::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - poly = 1; - - if (_prepared_instances) { - maid.dispose(_instances); - _instances = _prepared_instances; - _prepared_instances = NULL; - } - assert(poly <= _instances->size()); - - return NodeImpl::apply_poly(context, maid, poly); -} - -/** Instantiate self from LV2 plugin descriptor. - * - * Implemented as a seperate function (rather than in the constructor) to - * allow graceful error-catching of broken plugins. - * - * Returns whether or not plugin was successfully instantiated. If return - * value is false, this object may not be used. - */ -bool -LV2Node::instantiate(BufferFactory& bufs) -{ - const Ingen::URIs& uris = bufs.uris(); - SharedPtr info = _lv2_plugin->lv2_info(); - const LilvPlugin* plug = _lv2_plugin->lilv_plugin(); - Ingen::Forge& forge = bufs.forge(); - const uint32_t num_ports = lilv_plugin_get_num_ports(plug); - - _ports = new Raul::Array(num_ports, NULL); - - bool ret = true; - - float* min_values = new float[num_ports]; - float* max_values = new float[num_ports]; - float* def_values = new float[num_ports]; - lilv_plugin_get_port_ranges_float(plug, min_values, max_values, def_values); - - // Get all the necessary information about ports - for (uint32_t j = 0; j < num_ports; ++j) { - const LilvPort* id = lilv_plugin_get_port_by_index(plug, j); - - /* LV2 port symbols are guaranteed to be unique, valid C identifiers, - and Lilv guarantees that lilv_port_get_symbol() is valid. */ - const Raul::Symbol port_sym( - lilv_node_as_string(lilv_port_get_symbol(plug, id))); - - // Get port type - Raul::Atom val; - PortType port_type = PortType::UNKNOWN; - LV2_URID buffer_type = 0; - bool is_morph = false; - bool is_auto_morph = false; - if (lilv_port_is_a(plug, id, info->lv2_ControlPort)) { - if (lilv_port_is_a(plug, id, info->morph_MorphPort)) { - is_morph = true; - LilvNodes* types = lilv_port_get_value( - plug, id, info->morph_supportsType); - LILV_FOREACH(nodes, i, types) { - const LilvNode* type = lilv_nodes_get(types, i); - if (lilv_node_equals(type, info->lv2_CVPort)) { - port_type = PortType::CV; - buffer_type = uris.atom_Sound; - } - } - lilv_nodes_free(types); - } - if (port_type == PortType::UNKNOWN) { - port_type = PortType::CONTROL; - buffer_type = uris.atom_Float; - } - } else if (lilv_port_is_a(plug, id, info->lv2_CVPort)) { - port_type = PortType::CV; - buffer_type = uris.atom_Sound; - } else if (lilv_port_is_a(plug, id, info->lv2_AudioPort)) { - port_type = PortType::AUDIO; - buffer_type = uris.atom_Sound; - } else if (lilv_port_is_a(plug, id, info->atom_AtomPort)) { - port_type = PortType::ATOM; - } - - if (lilv_port_is_a(plug, id, info->morph_AutoMorphPort)) { - is_auto_morph = true; - } - - // Get buffer type if necessary (atom ports) - if (!buffer_type) { - LilvNodes* types = lilv_port_get_value( - plug, id, info->atom_bufferType); - LILV_FOREACH(nodes, i, types) { - const LilvNode* type = lilv_nodes_get(types, i); - if (lilv_node_is_uri(type)) { - buffer_type = bufs.engine().world()->uri_map().map_uri( - lilv_node_as_uri(type)); - } - } - lilv_nodes_free(types); - } - - uint32_t port_buffer_size = bufs.default_size(buffer_type); - - if (port_type == PortType::ATOM) { - // Get default value, and its length - LilvNodes* defaults = lilv_port_get_value(plug, id, info->lv2_default); - LILV_FOREACH(nodes, i, defaults) { - const LilvNode* d = lilv_nodes_get(defaults, i); - if (lilv_node_is_string(d)) { - const char* str_val = lilv_node_as_string(d); - const uint32_t str_val_len = strlen(str_val); - val = forge.alloc(str_val); - port_buffer_size = std::max(port_buffer_size, str_val_len); - } - } - lilv_nodes_free(defaults); - - // Get minimum size, if set in data - LilvNodes* sizes = lilv_port_get_value(plug, id, info->rsz_minimumSize); - LILV_FOREACH(nodes, i, sizes) { - const LilvNode* d = lilv_nodes_get(sizes, i); - if (lilv_node_is_int(d)) { - uint32_t size_val = lilv_node_as_int(d); - port_buffer_size = std::max(port_buffer_size, size_val); - } - } - lilv_nodes_free(sizes); - - bufs.engine().log().info( - Raul::fmt("Atom port %1% buffer size %2%\n") - % path().c_str() % port_buffer_size); - } - - enum { UNKNOWN, INPUT, OUTPUT } direction = UNKNOWN; - if (lilv_port_is_a(plug, id, info->lv2_InputPort)) { - direction = INPUT; - } else if (lilv_port_is_a(plug, id, info->lv2_OutputPort)) { - direction = OUTPUT; - } - - if (port_type == PortType::UNKNOWN || direction == UNKNOWN) { - parent_patch()->engine().log().error( - Raul::fmt("<%1%> port %2% has unknown type or direction\n") - % _lv2_plugin->uri().c_str() % port_sym.c_str()); - ret = false; - break; - } - - if (!val.type()) - val = forge.make(isnan(def_values[j]) ? 0.0f : def_values[j]); - - PortImpl* port = (direction == INPUT) - ? static_cast( - new InputPort(bufs, this, port_sym, j, _polyphony, - port_type, buffer_type, val)) - : static_cast( - new OutputPort(bufs, this, port_sym, j, _polyphony, - port_type, buffer_type, val)); - - port->set_morphable(is_morph, is_auto_morph); - if (direction == INPUT && (port_type == PortType::CONTROL - || port_type == PortType::CV)) { - port->set_value(val); - if (!isnan(min_values[j])) { - port->set_property(uris.lv2_minimum, forge.make(min_values[j])); - port->set_minimum(forge.make(min_values[j])); - } - if (!isnan(max_values[j])) { - port->set_property(uris.lv2_maximum, forge.make(max_values[j])); - port->set_maximum(forge.make(max_values[j])); - } - } - - // Inherit certain properties from plugin port - LilvNode* preds[] = { info->lv2_portProperty, info->atom_supports, 0 }; - for (int p = 0; preds[p]; ++p) { - LilvNodes* values = lilv_port_get_value(plug, id, preds[p]); - LILV_FOREACH(nodes, v, values) { - const LilvNode* val = lilv_nodes_get(values, v); - if (lilv_node_is_uri(val)) { - port->add_property(Raul::URI(lilv_node_as_uri(preds[p])), - forge.alloc_uri(lilv_node_as_uri(val))); - } - } - lilv_nodes_free(values); - } - - port->cache_properties(); - - _ports->at(j) = port; - } - - delete[] min_values; - delete[] max_values; - delete[] def_values; - - if (!ret) { - delete _ports; - _ports = NULL; - return ret; - } - - _features = info->world().lv2_features().lv2_features(&info->world(), this); - - // Actually create plugin instances and port buffers. - const SampleRate rate = bufs.engine().driver()->sample_rate(); - _instances = new Instances(_polyphony, SharedPtr()); - for (uint32_t i = 0; i < _polyphony; ++i) { - _instances->at(i) = make_instance(bufs.uris(), rate, i, false); - if (!_instances->at(i)) { - return false; - } - } - - // FIXME: Polyphony + worker? - if (lilv_plugin_has_feature(plug, info->work_schedule)) { - _worker_iface = (const LV2_Worker_Interface*) - lilv_instance_get_extension_data(instance(0), - LV2_WORKER__interface); - } - - return ret; -} - -void -LV2Node::activate(BufferFactory& bufs) -{ - NodeImpl::activate(bufs); - - for (uint32_t i = 0; i < _polyphony; ++i) - lilv_instance_activate(instance(i)); -} - -void -LV2Node::deactivate() -{ - NodeImpl::deactivate(); - - for (uint32_t i = 0; i < _polyphony; ++i) - lilv_instance_deactivate(instance(i)); -} - -LV2_Worker_Status -LV2Node::work_respond(LV2_Worker_Respond_Handle handle, - uint32_t size, - const void* data) -{ - LV2Node* node = (LV2Node*)handle; - LV2Node::Response* r = new LV2Node::Response(size, data); - node->_responses.push_back(*r); - return LV2_WORKER_SUCCESS; -} - -void -LV2Node::work(uint32_t size, const void* data) -{ - if (_worker_iface) { - LV2_Handle inst = lilv_instance_get_handle(instance(0)); - if (_worker_iface->work(inst, work_respond, this, size, data)) { - parent_patch()->engine().log().error( - Raul::fmt("Error calling %1% work method\n") % _path); - } - } -} - -void -LV2Node::process(ProcessContext& context) -{ - NodeImpl::pre_process(context); - - for (uint32_t i = 0; i < _polyphony; ++i) - lilv_instance_run(instance(i), context.nframes()); - - if (_worker_iface) { - LV2_Handle inst = lilv_instance_get_handle(instance(0)); - while (!_responses.empty()) { - Response& r = _responses.front(); - _worker_iface->work_response(inst, r.size, r.data); - _responses.pop_front(); - context.engine().maid()->dispose(&r); - } - - if (_worker_iface->end_run) { - _worker_iface->end_run(inst); - } - } - - NodeImpl::post_process(context); -} - -void -LV2Node::set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf) -{ - NodeImpl::set_port_buffer(voice, port_num, buf); - lilv_instance_connect_port( - instance(voice), port_num, - buf ? buf->port_data(_ports->at(port_num)->type()) : NULL); -} - -} // namespace Server -} // namespace Ingen - diff --git a/src/server/LV2Node.hpp b/src/server/LV2Node.hpp deleted file mode 100644 index e7f8eae6..00000000 --- a/src/server/LV2Node.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#ifndef INGEN_ENGINE_LV2NODE_HPP -#define INGEN_ENGINE_LV2NODE_HPP - -#include "lilv/lilv.h" -#include "lv2/lv2plug.in/ns/ext/worker/worker.h" -#include "raul/Disposable.hpp" - -#include "BufferRef.hpp" -#include "NodeImpl.hpp" -#include "ingen/LV2Features.hpp" -#include "types.hpp" - -namespace Ingen { -namespace Server { - -class LV2Plugin; - -/** An instance of a LV2 plugin. - * - * \ingroup engine - */ -class LV2Node : public NodeImpl -{ -public: - LV2Node(LV2Plugin* plugin, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - SampleRate srate); - - ~LV2Node(); - - bool instantiate(BufferFactory& bufs); - - bool prepare_poly(BufferFactory& bufs, uint32_t poly); - bool apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly); - - void activate(BufferFactory& bufs); - void deactivate(); - - void work(uint32_t size, const void* data); - - void process(ProcessContext& context); - - void set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf); - -protected: - SharedPtr make_instance(URIs& uris, - SampleRate rate, - uint32_t voice, - bool preparing); - - inline LilvInstance* instance(uint32_t voice) { - return (LilvInstance*)(*_instances)[voice].get(); - } - - typedef Raul::Array< SharedPtr > Instances; - - struct Response : public Raul::Disposable - , public Raul::Noncopyable - , public boost::intrusive::slist_base_hook<> - { - inline Response(uint32_t s, const void* d) - : size(s) - , data(malloc(s)) - { - memcpy(data, d, s); - } - - ~Response() { - free(data); - } - - const uint32_t size; - void* const data; - }; - - typedef boost::intrusive::slist, - boost::intrusive::constant_time_size - > Responses; - - static LV2_Worker_Status work_respond( - LV2_Worker_Respond_Handle handle, uint32_t size, const void* data); - - LV2Plugin* _lv2_plugin; - Instances* _instances; - Instances* _prepared_instances; - const LV2_Worker_Interface* _worker_iface; - Responses _responses; - SharedPtr _features; -}; - -} // namespace Server -} // namespace Ingen - -#endif // INGEN_ENGINE_LV2NODE_HPP - diff --git a/src/server/LV2Plugin.cpp b/src/server/LV2Plugin.cpp index 0e2a16b2..0febfc7d 100644 --- a/src/server/LV2Plugin.cpp +++ b/src/server/LV2Plugin.cpp @@ -20,7 +20,7 @@ #include "Driver.hpp" #include "Engine.hpp" -#include "LV2Node.hpp" +#include "LV2Block.hpp" #include "LV2Plugin.hpp" using namespace std; @@ -56,21 +56,21 @@ LV2Plugin::symbol() const return Raul::Symbol("lv2_symbol"); } -NodeImpl* +BlockImpl* LV2Plugin::instantiate(BufferFactory& bufs, const Raul::Symbol& symbol, bool polyphonic, PatchImpl* parent, Engine& engine) { - LV2Node* n = new LV2Node( + LV2Block* b = new LV2Block( this, symbol, polyphonic, parent, engine.driver()->sample_rate()); - if (!n->instantiate(bufs)) { - delete n; + if (!b->instantiate(bufs)) { + delete b; return NULL; } else { - return n; + return b; } } diff --git a/src/server/LV2Plugin.hpp b/src/server/LV2Plugin.hpp index 226d61ab..ed26b4ae 100644 --- a/src/server/LV2Plugin.hpp +++ b/src/server/LV2Plugin.hpp @@ -30,7 +30,7 @@ namespace Ingen { namespace Server { class PatchImpl; -class NodeImpl; +class BlockImpl; /** Implementation of an LV2 plugin (loaded shared library). */ @@ -39,11 +39,11 @@ class LV2Plugin : public PluginImpl public: LV2Plugin(SharedPtr lv2_info, const Raul::URI& uri); - NodeImpl* instantiate(BufferFactory& bufs, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - Engine& engine); + BlockImpl* instantiate(BufferFactory& bufs, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + Engine& engine); const Raul::Symbol symbol() const; diff --git a/src/server/LV2ResizeFeature.hpp b/src/server/LV2ResizeFeature.hpp index eeab3d4a..5b385a2f 100644 --- a/src/server/LV2ResizeFeature.hpp +++ b/src/server/LV2ResizeFeature.hpp @@ -20,9 +20,9 @@ #include "ingen/LV2Features.hpp" #include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" +#include "BlockImpl.hpp" #include "Buffer.hpp" +#include "PortImpl.hpp" namespace Ingen { namespace Server { @@ -32,9 +32,9 @@ struct ResizeFeature : public Ingen::LV2Features::Feature { LV2_Resize_Port_Feature_Data data, uint32_t index, size_t size) { - NodeImpl* node = (NodeImpl*)data; - PortImpl* port = node->port_impl(index); - if (node->context() == Context::MESSAGE) { + BlockImpl* block = (BlockImpl*)data; + PortImpl* port = block->port_impl(index); + if (block->context() == Context::MESSAGE) { port->buffer(0)->resize(size); port->connect_buffers(); return LV2_RESIZE_PORT_SUCCESS; @@ -48,12 +48,12 @@ struct ResizeFeature : public Ingen::LV2Features::Feature { } SharedPtr feature(World* w, GraphObject* n) { - NodeImpl* node = dynamic_cast(n); - if (!node) + BlockImpl* block = dynamic_cast(n); + if (!block) return SharedPtr(); LV2_Resize_Port_Resize* data = (LV2_Resize_Port_Resize*)malloc(sizeof(LV2_Resize_Port_Resize)); - data->data = node; + data->data = block; data->resize = &resize_port; LV2_Feature* f = (LV2_Feature*)malloc(sizeof(LV2_Feature)); f->URI = LV2_RESIZE_PORT_URI; diff --git a/src/server/NodeFactory.cpp b/src/server/NodeFactory.cpp deleted file mode 100644 index 6683658b..00000000 --- a/src/server/NodeFactory.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#include - -#include "lilv/lilv.h" - -#include "ingen/World.hpp" -#include "internals/Controller.hpp" -#include "internals/Delay.hpp" -#include "internals/Note.hpp" -#include "internals/Trigger.hpp" - -#include "InternalPlugin.hpp" -#include "LV2Plugin.hpp" -#include "NodeFactory.hpp" -#include "ThreadManager.hpp" - -using namespace std; - -namespace Ingen { -namespace Server { - -using namespace Internals; - -NodeFactory::NodeFactory(Ingen::World* world) - : _world(world) - , _lv2_info(new LV2Info(world)) - , _has_loaded(false) -{ - load_internal_plugins(); -} - -NodeFactory::~NodeFactory() -{ - for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) - delete i->second; - - _plugins.clear(); -} - -const NodeFactory::Plugins& -NodeFactory::plugins() -{ - ThreadManager::assert_thread(THREAD_PRE_PROCESS); - if (!_has_loaded) { - _has_loaded = true; - // TODO: Plugin list refreshing - load_lv2_plugins(); - _has_loaded = true; - } - return _plugins; -} - -PluginImpl* -NodeFactory::plugin(const Raul::URI& uri) -{ - load_plugin(uri); - const Plugins::const_iterator i = _plugins.find(uri); - return ((i != _plugins.end()) ? i->second : NULL); -} - -void -NodeFactory::load_internal_plugins() -{ - Ingen::URIs& uris = _world->uris(); - InternalPlugin* controller_plug = ControllerNode::internal_plugin(uris); - _plugins.insert(make_pair(controller_plug->uri(), controller_plug)); - - InternalPlugin* delay_plug = DelayNode::internal_plugin(uris); - _plugins.insert(make_pair(delay_plug->uri(), delay_plug)); - - InternalPlugin* note_plug = NoteNode::internal_plugin(uris); - _plugins.insert(make_pair(note_plug->uri(), note_plug)); - - InternalPlugin* trigger_plug = TriggerNode::internal_plugin(uris); - _plugins.insert(make_pair(trigger_plug->uri(), trigger_plug)); -} - -void -NodeFactory::load_plugin(const Raul::URI& uri) -{ - if (_has_loaded || _plugins.find(uri) != _plugins.end()) { - return; - } - - LilvNode* node = lilv_new_uri(_world->lilv_world(), uri.c_str()); - const LilvPlugins* plugs = lilv_world_get_all_plugins(_world->lilv_world()); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugs, node); - if (plug) { - LV2Plugin* const ingen_plugin = new LV2Plugin(_lv2_info, uri); - ingen_plugin->lilv_plugin(plug); - _plugins.insert(make_pair(uri, ingen_plugin)); - } - lilv_node_free(node); -} - -/** Loads information about all LV2 plugins into internal plugin database. - */ -void -NodeFactory::load_lv2_plugins() -{ - const LilvPlugins* plugins = lilv_world_get_all_plugins(_world->lilv_world()); - LILV_FOREACH(plugins, i, plugins) { - const LilvPlugin* lv2_plug = lilv_plugins_get(plugins, i); - - const Raul::URI uri(lilv_node_as_uri(lilv_plugin_get_uri(lv2_plug))); - - if (_plugins.find(uri) != _plugins.end()) { - continue; - } - - LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri); - - plugin->lilv_plugin(lv2_plug); - _plugins.insert(make_pair(uri, plugin)); - } -} - -} // namespace Server -} // namespace Ingen diff --git a/src/server/NodeFactory.hpp b/src/server/NodeFactory.hpp deleted file mode 100644 index 502d7757..00000000 --- a/src/server/NodeFactory.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#ifndef INGEN_ENGINE_NODEFACTORY_HPP -#define INGEN_ENGINE_NODEFACTORY_HPP - -#include - -#include "ingen/World.hpp" -#include "raul/Noncopyable.hpp" -#include "raul/SharedPtr.hpp" -#include "raul/URI.hpp" - -namespace Ingen { -namespace Server { - -class NodeImpl; -class PatchImpl; -class PluginImpl; -class LV2Info; - -/** Discovers and loads plugin libraries. - * - * \ingroup engine - */ -class NodeFactory : public Raul::Noncopyable -{ -public: - explicit NodeFactory(Ingen::World* world); - ~NodeFactory(); - - void load_plugin(const Raul::URI& uri); - - typedef std::map Plugins; - const Plugins& plugins(); - - PluginImpl* plugin(const Raul::URI& uri); - -private: - void load_lv2_plugins(); - void load_internal_plugins(); - - Plugins _plugins; - Ingen::World* _world; - SharedPtr _lv2_info; - bool _has_loaded; -}; - -} // namespace Server -} // namespace Ingen - -#endif // INGEN_ENGINE_NODEFACTORY_HPP diff --git a/src/server/NodeImpl.cpp b/src/server/NodeImpl.cpp deleted file mode 100644 index f1f6c362..00000000 --- a/src/server/NodeImpl.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#include -#include - -#include "raul/Array.hpp" - -#include "Buffer.hpp" -#include "Engine.hpp" -#include "NodeImpl.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "ProcessContext.hpp" -#include "ThreadManager.hpp" - -using namespace std; - -namespace Ingen { -namespace Server { - -NodeImpl::NodeImpl(PluginImpl* plugin, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - SampleRate srate) - : GraphObjectImpl(plugin->uris(), parent, symbol) - , _plugin(plugin) - , _ports(NULL) - , _context(Context::AUDIO) - , _polyphony((polyphonic && parent) ? parent->internal_poly() : 1) - , _polyphonic(polyphonic) - , _activated(false) - , _traversed(false) -{ - assert(_plugin); - assert(_polyphony > 0); -} - -NodeImpl::~NodeImpl() -{ - if (_activated) { - deactivate(); - } - - if (is_linked()) { - parent_patch()->remove_node(*this); - } - - delete _ports; -} - -GraphObject* -NodeImpl::port(uint32_t index) const -{ - return (*_ports)[index]; -} - -const Plugin* -NodeImpl::plugin() const -{ - return _plugin; -} - -void -NodeImpl::activate(BufferFactory& bufs) -{ - ThreadManager::assert_thread(THREAD_PRE_PROCESS); - - _activated = true; - for (uint32_t p = 0; p < num_ports(); ++p) { - PortImpl* const port = _ports->at(p); - port->setup_buffers(bufs, port->poly(), false); - port->connect_buffers(); - port->clear_buffers(); - } -} - -void -NodeImpl::deactivate() -{ - _activated = false; - for (uint32_t i = 0; i < _polyphony; ++i) { - for (uint32_t j = 0; j < num_ports(); ++j) { - PortImpl* const port = _ports->at(j); - if (port->is_output() && port->buffer(i)) - port->buffer(i)->clear(); - } - } -} - -bool -NodeImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) -{ - ThreadManager::assert_thread(THREAD_PRE_PROCESS); - - if (!_polyphonic) - poly = 1; - - if (_ports) - for (uint32_t i = 0; i < _ports->size(); ++i) - _ports->at(i)->prepare_poly(bufs, poly); - - return true; -} - -bool -NodeImpl::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - poly = 1; - - _polyphony = poly; - - if (_ports) - for (uint32_t i = 0; i < num_ports(); ++i) - _ports->at(i)->apply_poly(context, maid, poly); - - return true; -} - -void -NodeImpl::set_buffer_size(Context& context, - BufferFactory& bufs, - LV2_URID type, - uint32_t size) -{ - if (_ports) { - for (uint32_t i = 0; i < _ports->size(); ++i) { - PortImpl* const p = _ports->at(i); - if (p->buffer_type() == type) { - p->set_buffer_size(context, bufs, size); - } - } - } -} - -/** Prepare to run a cycle (in the audio thread) - */ -void -NodeImpl::pre_process(ProcessContext& context) -{ - // Mix down input ports - for (uint32_t i = 0; i < num_ports(); ++i) { - PortImpl* const port = _ports->at(i); - port->pre_process(context); - port->connect_buffers(); - } -} - -/** Prepare to run a cycle (in the audio thread) - */ -void -NodeImpl::post_process(ProcessContext& context) -{ - // Write output ports - for (uint32_t i = 0; _ports && i < _ports->size(); ++i) { - _ports->at(i)->post_process(context); - } -} - -void -NodeImpl::set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf) -{ - /*std::cout << path() << " set port " << port_num << " voice " << voice - << " buffer " << buf << " offset " << offset << std::endl;*/ -} - -} // namespace Server -} // namespace Ingen - diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp deleted file mode 100644 index 86741156..00000000 --- a/src/server/NodeImpl.hpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#ifndef INGEN_ENGINE_NODEIMPL_HPP -#define INGEN_ENGINE_NODEIMPL_HPP - -#include - -#include - -#include "raul/Array.hpp" -#include "raul/AtomicInt.hpp" - -#include "BufferRef.hpp" -#include "Context.hpp" -#include "GraphObjectImpl.hpp" -#include "PortType.hpp" -#include "types.hpp" - -namespace Raul { -class Maid; -} - -namespace Ingen { - -class Plugin; - -namespace Server { - -class Buffer; -class BufferFactory; -class Context; -class PatchImpl; -class PluginImpl; -class PortImpl; -class ProcessContext; - -/** A Node (or "module") in a Patch (which is also a Node). - * - * A Node is a unit with input/output ports, a process() method, and some other - * things. - * - * \ingroup engine - */ -class NodeImpl : public GraphObjectImpl - , public boost::intrusive::slist_base_hook<> // In PatchImpl -{ -public: - NodeImpl(PluginImpl* plugin, - const Raul::Symbol& symbol, - bool poly, - PatchImpl* parent, - SampleRate rate); - - virtual ~NodeImpl(); - - virtual GraphType graph_type() const { return NODE; } - - /** Activate this Node. - * - * This function must be called in a non-realtime thread before it is - * inserted in to a patch. Any non-realtime actions that need to be - * done before the Node is ready for use should be done here. - */ - virtual void activate(BufferFactory& bufs); - - /** Deactivate this Node. - * - * This function must be called in a non-realtime thread after the - * node has been removed from its patch (i.e. processing is finished). - */ - virtual void deactivate(); - - /** Return true iff this node is activated */ - bool activated() { return _activated; } - - /** Learn the next incoming MIDI event (for internals) */ - virtual void learn() {} - - /** Do whatever needs doing in the process thread before process() is called */ - virtual void pre_process(ProcessContext& context); - - /** Run the node for @a nframes input/output. - * - * @a start and @a end are transport times: end is not redundant in the case - * of varispeed, where end-start != nframes. - */ - virtual void process(ProcessContext& context) = 0; - - /** Do whatever needs doing in the process thread after process() is called */ - virtual void post_process(ProcessContext& context); - - /** Set the buffer of a port to a given buffer (e.g. connect plugin to buffer) */ - virtual void set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf); - - virtual GraphObject* port(uint32_t index) const; - virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; } - - /** Nodes that are connected to this Node's inputs. */ - std::list& providers() { return _providers; } - - /** Nodes are are connected to this Node's outputs. */ - std::list& dependants() { return _dependants; } - - /** Flag node as polyphonic. - * - * Note this will not actually allocate voices etc., prepare_poly - * and apply_poly must be called after this function to truly make - * a node polyphonic. - */ - virtual void set_polyphonic(bool p) { _polyphonic = p; } - - virtual bool prepare_poly(BufferFactory& bufs, uint32_t poly); - virtual bool apply_poly( - ProcessContext& context, Raul::Maid& maid, uint32_t poly); - - /** Information about the Plugin this Node is an instance of. - * Not the best name - not all nodes come from plugins (e.g. Patch) - */ - virtual PluginImpl* plugin_impl() const { return _plugin; } - - /** Information about the Plugin this Node is an instance of. - * Not the best name - not all nodes come from plugins (ie Patch) - */ - virtual const Plugin* plugin() const; - - virtual void plugin(PluginImpl* pi) { _plugin = pi; } - - virtual void set_buffer_size(Context& context, - BufferFactory& bufs, - LV2_URID type, - uint32_t size); - - /** The Patch this Node belongs to. */ - inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; } - - Context::ID context() const { return _context; } - uint32_t num_ports() const { return _ports ? _ports->size() : 0; } - virtual uint32_t polyphony() const { return _polyphony; } - - /** Used by the process order finding algorithm (ie during connections) */ - bool traversed() const { return _traversed; } - void traversed(bool b) { _traversed = b; } - -protected: - PluginImpl* _plugin; - Raul::Array* _ports; ///< Access in audio thread only - Context::ID _context; ///< Context this node runs in - uint32_t _polyphony; - std::list _providers; ///< Nodes connected to this one's input ports - std::list _dependants; ///< Nodes this one's output ports are connected to - bool _polyphonic; - bool _activated; - bool _traversed; ///< Flag for process order algorithm -}; - -} // namespace Server -} // namespace Ingen - -#endif // INGEN_ENGINE_NODEIMPL_HPP diff --git a/src/server/OutputPort.cpp b/src/server/OutputPort.cpp index 7558dda3..1fa53451 100644 --- a/src/server/OutputPort.cpp +++ b/src/server/OutputPort.cpp @@ -19,7 +19,7 @@ #include "Buffer.hpp" #include "BufferFactory.hpp" #include "Engine.hpp" -#include "NodeImpl.hpp" +#include "BlockImpl.hpp" #include "OutputPort.hpp" using namespace std; @@ -28,7 +28,7 @@ namespace Ingen { namespace Server { OutputPort::OutputPort(BufferFactory& bufs, - NodeImpl* parent, + BlockImpl* parent, const Raul::Symbol& symbol, uint32_t index, uint32_t poly, diff --git a/src/server/OutputPort.hpp b/src/server/OutputPort.hpp index 2156c2ab..b117847f 100644 --- a/src/server/OutputPort.hpp +++ b/src/server/OutputPort.hpp @@ -39,7 +39,7 @@ class OutputPort : virtual public PortImpl { public: OutputPort(BufferFactory& bufs, - NodeImpl* parent, + BlockImpl* parent, const Raul::Symbol& symbol, uint32_t index, uint32_t poly, diff --git a/src/server/PatchImpl.cpp b/src/server/PatchImpl.cpp index b280886e..ae16c634 100644 --- a/src/server/PatchImpl.cpp +++ b/src/server/PatchImpl.cpp @@ -20,11 +20,11 @@ #include "ingen/URIs.hpp" #include "ingen/World.hpp" +#include "BlockImpl.hpp" #include "BufferFactory.hpp" -#include "EdgeImpl.hpp" #include "DuplexPort.hpp" +#include "EdgeImpl.hpp" #include "Engine.hpp" -#include "NodeImpl.hpp" #include "PatchImpl.hpp" #include "PatchPlugin.hpp" #include "PortImpl.hpp" @@ -41,10 +41,10 @@ PatchImpl::PatchImpl(Engine& engine, PatchImpl* parent, SampleRate srate, uint32_t internal_poly) - : NodeImpl(new PatchPlugin(engine.world()->uris(), - engine.world()->uris().ingen_Patch, - Raul::Symbol("patch"), - "Ingen Patch"), + : BlockImpl(new PatchPlugin(engine.world()->uris(), + engine.world()->uris().ingen_Patch, + Raul::Symbol("patch"), + "Ingen Patch"), symbol, poly, parent, srate) , _engine(engine) , _poly_pre(internal_poly) @@ -65,9 +65,9 @@ PatchImpl::~PatchImpl() void PatchImpl::activate(BufferFactory& bufs) { - NodeImpl::activate(bufs); + BlockImpl::activate(bufs); - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { i->activate(bufs); } @@ -78,9 +78,9 @@ void PatchImpl::deactivate() { if (_activated) { - NodeImpl::deactivate(); + BlockImpl::deactivate(); - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { if (i->activated()) { i->deactivate(); } @@ -104,7 +104,7 @@ PatchImpl::prepare_internal_poly(BufferFactory& bufs, uint32_t poly) // TODO: Subpatch dynamic polyphony (i.e. changing port polyphony) - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { i->prepare_poly(bufs, poly); } @@ -120,11 +120,11 @@ PatchImpl::apply_internal_poly(ProcessContext& context, { // TODO: Subpatch dynamic polyphony (i.e. changing port polyphony) - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { i->apply_poly(context, maid, poly); } - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { for (uint32_t j = 0; j < i->num_ports(); ++j) { PortImpl* const port = i->port_impl(j); if (port->is_input() && dynamic_cast(port)->direct_connect()) @@ -143,7 +143,7 @@ PatchImpl::apply_internal_poly(ProcessContext& context, /** Run the patch for the specified number of frames. * - * Calls all Nodes in (roughly, if parallel) the order _compiled_patch specifies. + * Calls all Blocks in (roughly, if parallel) the order _compiled_patch specifies. */ void PatchImpl::process(ProcessContext& context) @@ -151,16 +151,16 @@ PatchImpl::process(ProcessContext& context) if (!_process) return; - NodeImpl::pre_process(context); + BlockImpl::pre_process(context); if (_compiled_patch && _compiled_patch->size() > 0) { - // Run all nodes + // Run all blocks for (size_t i = 0; i < _compiled_patch->size(); ++i) { - (*_compiled_patch)[i].node()->process(context); + (*_compiled_patch)[i].block()->process(context); } } - NodeImpl::post_process(context); + BlockImpl::post_process(context); } void @@ -169,31 +169,31 @@ PatchImpl::set_buffer_size(Context& context, LV2_URID type, uint32_t size) { - NodeImpl::set_buffer_size(context, bufs, type, size); + BlockImpl::set_buffer_size(context, bufs, type, size); for (size_t i = 0; i < _compiled_patch->size(); ++i) - (*_compiled_patch)[i].node()->set_buffer_size(context, bufs, type, size); + (*_compiled_patch)[i].block()->set_buffer_size(context, bufs, type, size); } // Patch specific stuff -/** Add a node. +/** Add a block. * Preprocessing thread only. */ void -PatchImpl::add_node(NodeImpl& node) +PatchImpl::add_block(BlockImpl& block) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - _nodes.push_front(node); + _blocks.push_front(block); } -/** Remove a node. +/** Remove a block. * Preprocessing thread only. */ void -PatchImpl::remove_node(NodeImpl& node) +PatchImpl::remove_block(BlockImpl& block) { - _nodes.erase(_nodes.iterator_to(node)); + _blocks.erase(_blocks.iterator_to(block)); } void @@ -317,7 +317,7 @@ PatchImpl::build_ports_array() } static inline void -compile_recursive(NodeImpl* n, CompiledPatch* output) +compile_recursive(BlockImpl* n, CompiledPatch* output) { if (n == NULL || n->traversed()) return; @@ -325,12 +325,12 @@ compile_recursive(NodeImpl* n, CompiledPatch* output) n->traversed(true); assert(output != NULL); - for (std::list::iterator i = n->providers().begin(); + for (std::list::iterator i = n->providers().begin(); i != n->providers().end(); ++i) if (!(*i)->traversed()) compile_recursive(*i, output); - output->push_back(CompiledNode(n, n->providers().size(), n->dependants())); + output->push_back(CompiledBlock(n, n->providers().size(), n->dependants())); } /** Find the process order for this Patch. @@ -350,25 +350,25 @@ PatchImpl::compile() CompiledPatch* const compiled_patch = new CompiledPatch(); - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { i->traversed(false); } - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { // Either a sink or connected to our output ports: if (!i->traversed() && i->dependants().empty()) { compile_recursive(&*i, compiled_patch); } } - // Traverse any nodes we didn't hit yet - for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { + // Traverse any blocks we didn't hit yet + for (Blocks::iterator i = _blocks.begin(); i != _blocks.end(); ++i) { if (!i->traversed()) { compile_recursive(&*i, compiled_patch); } } - if (compiled_patch->size() != _nodes.size()) { + if (compiled_patch->size() != _blocks.size()) { _engine.log().error(Raul::fmt("Failed to compile patch %1%\n") % _path); delete compiled_patch; return NULL; diff --git a/src/server/PatchImpl.hpp b/src/server/PatchImpl.hpp index badbfb81..fa212b1a 100644 --- a/src/server/PatchImpl.hpp +++ b/src/server/PatchImpl.hpp @@ -19,9 +19,9 @@ #include +#include "BlockImpl.hpp" #include "CompiledPatch.hpp" #include "DuplexPort.hpp" -#include "NodeImpl.hpp" #include "PluginImpl.hpp" #include "PortType.hpp" #include "ThreadManager.hpp" @@ -38,15 +38,15 @@ class Context; class Engine; class ProcessContext; -/** A group of nodes in a graph, possibly polyphonic. +/** A group of blocks in a graph, possibly polyphonic. * - * Note that this is also a Node, just one which contains Nodes. + * Note that this is also a Block, just one which contains Blocks. * Therefore infinite subpatching is possible, of polyphonic - * patches of polyphonic nodes etc. etc. + * patches of polyphonic blocks etc. etc. * * \ingroup engine */ -class PatchImpl : public NodeImpl +class PatchImpl : public BlockImpl { public: PatchImpl(Engine& engine, @@ -91,16 +91,16 @@ public: Raul::Maid& maid, uint32_t poly); - // Patch specific stuff not inherited from Node + // Patch specific stuff not inherited from Block typedef boost::intrusive::slist< - NodeImpl, boost::intrusive::constant_time_size > Nodes; + BlockImpl, boost::intrusive::constant_time_size > Blocks; - void add_node(NodeImpl& node); - void remove_node(NodeImpl& node); + void add_block(BlockImpl& block); + void remove_block(BlockImpl& block); - Nodes& nodes() { return _nodes; } - const Nodes& nodes() const { return _nodes; } + Blocks& blocks() { return _blocks; } + const Blocks& blocks() const { return _blocks; } uint32_t num_ports_non_rt() const; @@ -161,7 +161,7 @@ private: CompiledPatch* _compiled_patch; ///< Process thread only Ports _inputs; ///< Pre-process thread only Ports _outputs; ///< Pre-process thread only - Nodes _nodes; ///< Pre-process thread only + Blocks _blocks; ///< Pre-process thread only bool _process; }; diff --git a/src/server/PatchPlugin.hpp b/src/server/PatchPlugin.hpp index ba1cfa40..1fd9069f 100644 --- a/src/server/PatchPlugin.hpp +++ b/src/server/PatchPlugin.hpp @@ -23,7 +23,7 @@ namespace Ingen { namespace Server { -class NodeImpl; +class BlockImpl; /** Implementation of a Patch plugin. * @@ -39,11 +39,11 @@ public: : PluginImpl(uris, Plugin::Patch, uri) {} - NodeImpl* instantiate(BufferFactory& bufs, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - Engine& engine) + BlockImpl* instantiate(BufferFactory& bufs, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + Engine& engine) { return NULL; } diff --git a/src/server/PluginImpl.hpp b/src/server/PluginImpl.hpp index 13e78b1f..624b3f6d 100644 --- a/src/server/PluginImpl.hpp +++ b/src/server/PluginImpl.hpp @@ -32,14 +32,14 @@ class URIs; namespace Server { -class PatchImpl; -class NodeImpl; -class Engine; +class BlockImpl; class BufferFactory; +class Engine; +class PatchImpl; /** Implementation of a plugin (internal code, or a loaded shared library). * - * Conceptually, a Node is an instance of this. + * Conceptually, a Block is an instance of this. */ class PluginImpl : public Plugin , public boost::noncopyable @@ -52,11 +52,11 @@ public: , _type(type) {} - virtual NodeImpl* instantiate(BufferFactory& bufs, - const Raul::Symbol& symbol, - bool polyphonic, - PatchImpl* parent, - Engine& engine) = 0; + virtual BlockImpl* instantiate(BufferFactory& bufs, + const Raul::Symbol& symbol, + bool polyphonic, + PatchImpl* parent, + Engine& engine) = 0; virtual const Raul::Symbol symbol() const = 0; diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 698cd458..bd088913 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -19,10 +19,10 @@ #include "raul/Array.hpp" #include "raul/Maid.hpp" +#include "BlockImpl.hpp" #include "Buffer.hpp" #include "BufferFactory.hpp" #include "Engine.hpp" -#include "NodeImpl.hpp" #include "PortImpl.hpp" #include "PortType.hpp" #include "ThreadManager.hpp" @@ -33,7 +33,7 @@ namespace Ingen { namespace Server { PortImpl::PortImpl(BufferFactory& bufs, - NodeImpl* const node, + BlockImpl* const block, const Raul::Symbol& name, uint32_t index, uint32_t poly, @@ -41,7 +41,7 @@ PortImpl::PortImpl(BufferFactory& bufs, LV2_URID buffer_type, const Raul::Atom& value, size_t buffer_size) - : GraphObjectImpl(bufs.uris(), node, name) + : GraphObjectImpl(bufs.uris(), block, name) , _bufs(bufs) , _index(index) , _poly(poly) @@ -64,7 +64,7 @@ PortImpl::PortImpl(BufferFactory& bufs, , _is_sample_rate(false) , _is_toggled(false) { - assert(node != NULL); + assert(block != NULL); assert(_poly > 0); const Ingen::URIs& uris = bufs.uris(); @@ -163,7 +163,7 @@ PortImpl::set_voice_value(const Context& context, break; case PortType::AUDIO: case PortType::CV: { - // Time may be at end so internal nodes can set triggers + // Time may be at end so internal blocks can set triggers assert(time >= context.start()); assert(time <= context.start() + context.nframes()); @@ -298,7 +298,7 @@ void PortImpl::connect_buffers() { for (uint32_t v = 0; v < _poly; ++v) - PortImpl::parent_node()->set_port_buffer(v, _index, buffer(v)); + PortImpl::parent_block()->set_port_buffer(v, _index, buffer(v)); } void diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp index 68787db8..d7aed3ff 100644 --- a/src/server/PortImpl.hpp +++ b/src/server/PortImpl.hpp @@ -33,14 +33,10 @@ namespace Raul { class Maid; } namespace Ingen { namespace Server { -class NodeImpl; +class BlockImpl; class BufferFactory; -/** A port on a Node. - * - * This is a non-template abstract base class, which basically exists so - * things can pass around Port pointers and not have to worry about type, - * templates, etc. +/** A port (input or output) on a Block. * * \ingroup engine */ @@ -51,8 +47,8 @@ public: virtual GraphType graph_type() const { return PORT; } - /** A port's parent is always a node, so static cast should be safe */ - NodeImpl* parent_node() const { return (NodeImpl*)_parent; } + /** A port's parent is always a block, so static cast should be safe */ + BlockImpl* parent_block() const { return (BlockImpl*)_parent; } /** Set the buffers array for this port. * @@ -175,7 +171,7 @@ public: protected: PortImpl(BufferFactory& bufs, - NodeImpl* node, + BlockImpl* block, const Raul::Symbol& name, uint32_t index, uint32_t poly, diff --git a/src/server/Worker.cpp b/src/server/Worker.cpp index e8c51335..6a39cba8 100644 --- a/src/server/Worker.cpp +++ b/src/server/Worker.cpp @@ -20,7 +20,7 @@ #include "Driver.hpp" #include "Engine.hpp" -#include "LV2Node.hpp" +#include "LV2Block.hpp" #include "PatchImpl.hpp" #include "Worker.hpp" @@ -29,8 +29,8 @@ namespace Server { /// A message in the Worker::_requests ring struct MessageHeader { - LV2Node* node; ///< Node this message is from - uint32_t size; ///< Size of following data + LV2Block* block; ///< Node this message is from + uint32_t size; ///< Size of following data // `size' bytes of data follow here }; @@ -39,25 +39,25 @@ schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data) { - LV2Node* node = (LV2Node*)handle; - Engine& engine = node->parent_patch()->engine(); - Worker* worker = engine.worker(); + LV2Block* block = (LV2Block*)handle; + Engine& engine = block->parent_patch()->engine(); + Worker* worker = engine.worker(); - return worker->request(node, size, data); + return worker->request(block, size, data); } LV2_Worker_Status -Worker::request(LV2Node* node, +Worker::request(LV2Block* block, uint32_t size, const void* data) { - Engine& engine = node->parent_patch()->engine(); + Engine& engine = block->parent_patch()->engine(); if (_requests.write_space() < sizeof(MessageHeader) + size) { engine.log().error("Work request ring overflow\n"); return LV2_WORKER_ERR_NO_SPACE; } - const MessageHeader msg = { node, size }; + const MessageHeader msg = { block, size }; if (_requests.write(sizeof(msg), &msg) != sizeof(msg)) { engine.log().error("Error writing header to work request ring\n"); return LV2_WORKER_ERR_UNKNOWN; @@ -82,14 +82,14 @@ delete_feature(LV2_Feature* feature) SharedPtr Worker::Schedule::feature(World* world, GraphObject* n) { - LV2Node* node = dynamic_cast(n); - if (!node) { + LV2Block* block = dynamic_cast(n); + if (!block) { return SharedPtr(); } LV2_Worker_Schedule* data = (LV2_Worker_Schedule*)malloc( sizeof(LV2_Worker_Schedule)); - data->handle = node; + data->handle = block; data->schedule_work = schedule; LV2_Feature* f = (LV2_Feature*)malloc(sizeof(LV2_Feature)); @@ -139,7 +139,7 @@ Worker::_run() continue; } - msg.node->work(msg.size, _buffer); + msg.block->work(msg.size, _buffer); } } } diff --git a/src/server/Worker.hpp b/src/server/Worker.hpp index 0310de90..f8c9216e 100644 --- a/src/server/Worker.hpp +++ b/src/server/Worker.hpp @@ -29,7 +29,7 @@ class Log; namespace Server { -class LV2Node; +class LV2Block; class Worker : public Raul::Thread { @@ -41,7 +41,7 @@ public: SharedPtr feature(World* world, GraphObject* n); }; - LV2_Worker_Status request(LV2Node* node, + LV2_Worker_Status request(LV2Block* block, uint32_t size, const void* data); diff --git a/src/server/events.hpp b/src/server/events.hpp index cf764fa9..95f3d35f 100644 --- a/src/server/events.hpp +++ b/src/server/events.hpp @@ -18,7 +18,7 @@ #define INGEN_ENGINE_EVENTS_HPP #include "events/Connect.hpp" -#include "events/CreateNode.hpp" +#include "events/CreateBlock.hpp" #include "events/CreatePatch.hpp" #include "events/CreatePort.hpp" #include "events/Delete.hpp" diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp index 2403b327..db8e044f 100644 --- a/src/server/events/Connect.cpp +++ b/src/server/events/Connect.cpp @@ -70,15 +70,15 @@ Connect::pre_process() return Event::pre_process_done(BAD_REQUEST, _head_path); } - NodeImpl* const tail_node = tail_output->parent_node(); - NodeImpl* const head_node = _head->parent_node(); - if (!tail_node || !head_node) { + BlockImpl* const tail_block = tail_output->parent_block(); + BlockImpl* const head_block = _head->parent_block(); + if (!tail_block || !head_block) { return Event::pre_process_done(PARENT_NOT_FOUND, _head_path); } - if (tail_node->parent() != head_node->parent() - && tail_node != head_node->parent() - && tail_node->parent() != head_node) { + if (tail_block->parent() != head_block->parent() + && tail_block != head_block->parent() + && tail_block->parent() != head_block) { return Event::pre_process_done(PARENT_DIFFERS, _head_path); } @@ -86,20 +86,20 @@ Connect::pre_process() return Event::pre_process_done(TYPE_MISMATCH, _head_path); } - if (tail_node->parent_patch() != head_node->parent_patch()) { + if (tail_block->parent_patch() != head_block->parent_patch()) { // Edge to a patch port from inside the patch - assert(tail_node->parent() == head_node || head_node->parent() == tail_node); - if (tail_node->parent() == head_node) { - _patch = dynamic_cast(head_node); + assert(tail_block->parent() == head_block || head_block->parent() == tail_block); + if (tail_block->parent() == head_block) { + _patch = dynamic_cast(head_block); } else { - _patch = dynamic_cast(tail_node); + _patch = dynamic_cast(tail_block); } - } else if (tail_node == head_node && dynamic_cast(tail_node)) { + } else if (tail_block == head_block && dynamic_cast(tail_block)) { // Edge from a patch input to a patch output (pass through) - _patch = dynamic_cast(tail_node); + _patch = dynamic_cast(tail_block); } else { - // Normal edge between nodes with the same parent - _patch = tail_node->parent_patch(); + // Normal edge between blocks with the same parent + _patch = tail_block->parent_patch(); } if (_patch->has_edge(tail_output, _head)) { @@ -114,12 +114,12 @@ Connect::pre_process() Glib::RWLock::ReaderLock wlock(_engine.store()->lock()); /* Need to be careful about patch port edges here and adding a - node's parent as a dependant/provider, or adding a patch as its own + block's parent as a dependant/provider, or adding a patch as its own provider... */ - if (tail_node != head_node && tail_node->parent() == head_node->parent()) { - head_node->providers().push_back(tail_node); - tail_node->dependants().push_back(head_node); + if (tail_block != head_block && tail_block->parent() == head_block->parent()) { + head_block->providers().push_back(tail_block); + tail_block->dependants().push_back(head_block); } _patch->add_edge(_edge); diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp new file mode 100644 index 00000000..73ff7ba2 --- /dev/null +++ b/src/server/events/CreateBlock.cpp @@ -0,0 +1,144 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include "ingen/Store.hpp" +#include "ingen/URIs.hpp" +#include "raul/Maid.hpp" +#include "raul/Path.hpp" + +#include "BlockFactory.hpp" +#include "BlockImpl.hpp" +#include "Broadcaster.hpp" +#include "CreateBlock.hpp" +#include "Engine.hpp" +#include "PatchImpl.hpp" +#include "PluginImpl.hpp" +#include "PortImpl.hpp" + +namespace Ingen { +namespace Server { +namespace Events { + +CreateBlock::CreateBlock(Engine& engine, + SharedPtr client, + int32_t id, + SampleCount timestamp, + const Raul::Path& path, + const Resource::Properties& properties) + : Event(engine, client, id, timestamp) + , _path(path) + , _properties(properties) + , _patch(NULL) + , _block(NULL) + , _compiled_patch(NULL) +{} + +bool +CreateBlock::pre_process() +{ + Ingen::URIs& uris = _engine.world()->uris(); + + typedef Resource::Properties::const_iterator iterator; + + if (_path.is_root()) { + return Event::pre_process_done(BAD_URI, _path); + } + + std::string plugin_uri_str; + const iterator t = _properties.find(uris.ingen_prototype); + if (t != _properties.end() && t->second.type() == uris.forge.URI) { + plugin_uri_str = t->second.get_uri(); + } else { + return Event::pre_process_done(BAD_REQUEST); + } + + if (_engine.store()->get(_path)) { + return Event::pre_process_done(EXISTS, _path); + } + + _patch = dynamic_cast(_engine.store()->get(_path.parent())); + if (!_patch) { + return Event::pre_process_done(PARENT_NOT_FOUND, _path.parent()); + } + + const Raul::URI plugin_uri(plugin_uri_str); + PluginImpl* plugin = _engine.block_factory()->plugin(plugin_uri); + if (!plugin) { + return Event::pre_process_done(PLUGIN_NOT_FOUND, Raul::URI(plugin_uri)); + } + + const iterator p = _properties.find(uris.ingen_polyphonic); + const bool polyphonic = ( + p != _properties.end() && + p->second.type() == _engine.world()->forge().Bool && + p->second.get_bool()); + + if (!(_block = plugin->instantiate(*_engine.buffer_factory(), + Raul::Symbol(_path.symbol()), + polyphonic, + _patch, + _engine))) { + return Event::pre_process_done(CREATION_FAILED, _path); + } + + _block->properties().insert(_properties.begin(), _properties.end()); + _block->activate(*_engine.buffer_factory()); + + // Add block to the store and the patch's pre-processor only block list + _patch->add_block(*_block); + _engine.store()->add(_block); + + /* Compile patch with new block added for insertion in audio thread + TODO: Since the block is not connected at this point, a full compilation + could be avoided and the block simply appended. */ + if (_patch->enabled()) { + _compiled_patch = _patch->compile(); + } + + _update.push_back(make_pair(_block->uri(), _block->properties())); + for (uint32_t i = 0; i < _block->num_ports(); ++i) { + const PortImpl* port = _block->port_impl(i); + Resource::Properties pprops = port->properties(); + pprops.erase(uris.ingen_value); + pprops.insert(std::make_pair(uris.ingen_value, port->value())); + _update.push_back(std::make_pair(port->uri(), pprops)); + } + + return Event::pre_process_done(SUCCESS); +} + +void +CreateBlock::execute(ProcessContext& context) +{ + if (_block) { + _engine.maid()->dispose(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } +} + +void +CreateBlock::post_process() +{ + if (!respond()) { + for (Update::const_iterator i = _update.begin(); i != _update.end(); ++i) { + _engine.broadcaster()->put(i->first, i->second); + } + } +} + +} // namespace Events +} // namespace Server +} // namespace Ingen diff --git a/src/server/events/CreateBlock.hpp b/src/server/events/CreateBlock.hpp new file mode 100644 index 00000000..ea3c4b5c --- /dev/null +++ b/src/server/events/CreateBlock.hpp @@ -0,0 +1,70 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_EVENTS_CREATEBLOCK_HPP +#define INGEN_EVENTS_CREATEBLOCK_HPP + +#include +#include + +#include "ingen/Resource.hpp" + +#include "Event.hpp" + +namespace Ingen { +namespace Server { + +class BlockImpl; +class CompiledPatch; +class PatchImpl; + +namespace Events { + +/** An event to load a Block and insert it into a Patch. + * + * \ingroup engine + */ +class CreateBlock : public Event +{ +public: + CreateBlock(Engine& engine, + SharedPtr client, + int32_t id, + SampleCount timestamp, + const Raul::Path& block_path, + const Resource::Properties& properties); + + bool pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + /// Update put message to broadcast to clients + typedef std::list< std::pair > Update; + + Raul::Path _path; + Resource::Properties _properties; + Update _update; + PatchImpl* _patch; + BlockImpl* _block; + CompiledPatch* _compiled_patch; +}; + +} // namespace Events +} // namespace Server +} // namespace Ingen + +#endif // INGEN_EVENTS_CREATEBLOCK_HPP diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp deleted file mode 100644 index ca2be305..00000000 --- a/src/server/events/CreateNode.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#include "ingen/Store.hpp" -#include "ingen/URIs.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" - -#include "Broadcaster.hpp" -#include "CreateNode.hpp" -#include "Engine.hpp" -#include "NodeFactory.hpp" -#include "NodeImpl.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" - -namespace Ingen { -namespace Server { -namespace Events { - -CreateNode::CreateNode(Engine& engine, - SharedPtr client, - int32_t id, - SampleCount timestamp, - const Raul::Path& path, - const Resource::Properties& properties) - : Event(engine, client, id, timestamp) - , _path(path) - , _properties(properties) - , _patch(NULL) - , _node(NULL) - , _compiled_patch(NULL) -{} - -bool -CreateNode::pre_process() -{ - Ingen::URIs& uris = _engine.world()->uris(); - - typedef Resource::Properties::const_iterator iterator; - - if (_path.is_root()) { - return Event::pre_process_done(BAD_URI, _path); - } - - std::string plugin_uri_str; - const iterator t = _properties.find(uris.ingen_prototype); - if (t != _properties.end() && t->second.type() == uris.forge.URI) { - plugin_uri_str = t->second.get_uri(); - } else { - return Event::pre_process_done(BAD_REQUEST); - } - - if (_engine.store()->get(_path)) { - return Event::pre_process_done(EXISTS, _path); - } - - _patch = dynamic_cast(_engine.store()->get(_path.parent())); - if (!_patch) { - return Event::pre_process_done(PARENT_NOT_FOUND, _path.parent()); - } - - const Raul::URI plugin_uri(plugin_uri_str); - PluginImpl* plugin = _engine.node_factory()->plugin(plugin_uri); - if (!plugin) { - return Event::pre_process_done(PLUGIN_NOT_FOUND, Raul::URI(plugin_uri)); - } - - const iterator p = _properties.find(uris.ingen_polyphonic); - const bool polyphonic = ( - p != _properties.end() && - p->second.type() == _engine.world()->forge().Bool && - p->second.get_bool()); - - if (!(_node = plugin->instantiate(*_engine.buffer_factory(), - Raul::Symbol(_path.symbol()), - polyphonic, - _patch, - _engine))) { - return Event::pre_process_done(CREATION_FAILED, _path); - } - - _node->properties().insert(_properties.begin(), _properties.end()); - _node->activate(*_engine.buffer_factory()); - - // Add node to the store and the patch's pre-processor only node list - _patch->add_node(*_node); - _engine.store()->add(_node); - - /* Compile patch with new node added for insertion in audio thread - TODO: Since the node is not connected at this point, a full compilation - could be avoided and the node simply appended. */ - if (_patch->enabled()) { - _compiled_patch = _patch->compile(); - } - - _update.push_back(make_pair(_node->uri(), _node->properties())); - for (uint32_t i = 0; i < _node->num_ports(); ++i) { - const PortImpl* port = _node->port_impl(i); - Resource::Properties pprops = port->properties(); - pprops.erase(uris.ingen_value); - pprops.insert(std::make_pair(uris.ingen_value, port->value())); - _update.push_back(std::make_pair(port->uri(), pprops)); - } - - return Event::pre_process_done(SUCCESS); -} - -void -CreateNode::execute(ProcessContext& context) -{ - if (_node) { - _engine.maid()->dispose(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - -void -CreateNode::post_process() -{ - if (!respond()) { - for (Update::const_iterator i = _update.begin(); i != _update.end(); ++i) { - _engine.broadcaster()->put(i->first, i->second); - } - } -} - -} // namespace Events -} // namespace Server -} // namespace Ingen diff --git a/src/server/events/CreateNode.hpp b/src/server/events/CreateNode.hpp deleted file mode 100644 index 32c0f4b9..00000000 --- a/src/server/events/CreateNode.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#ifndef INGEN_EVENTS_CREATENODE_HPP -#define INGEN_EVENTS_CREATENODE_HPP - -#include -#include - -#include "ingen/Resource.hpp" - -#include "Event.hpp" - -namespace Ingen { -namespace Server { - -class PatchImpl; -class NodeImpl; -class CompiledPatch; - -namespace Events { - -/** An event to load a Node and insert it into a Patch. - * - * \ingroup engine - */ -class CreateNode : public Event -{ -public: - CreateNode(Engine& engine, - SharedPtr client, - int32_t id, - SampleCount timestamp, - const Raul::Path& node_path, - const Resource::Properties& properties); - - bool pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - /// Update put message to broadcast to clients - typedef std::list< std::pair > Update; - - Raul::Path _path; - Resource::Properties _properties; - Update _update; - PatchImpl* _patch; - NodeImpl* _node; - CompiledPatch* _compiled_patch; -}; - -} // namespace Events -} // namespace Server -} // namespace Ingen - -#endif // INGEN_EVENTS_CREATENODE_HPP diff --git a/src/server/events/CreatePatch.cpp b/src/server/events/CreatePatch.cpp index 4f14ade5..e9adc547 100644 --- a/src/server/events/CreatePatch.cpp +++ b/src/server/events/CreatePatch.cpp @@ -81,9 +81,9 @@ CreatePatch::pre_process() _patch->properties().insert(_properties.begin(), _properties.end()); _patch->add_property(uris.rdf_type, uris.ingen_Patch); _patch->add_property(uris.rdf_type, - Resource::Property(uris.ingen_Node, Resource::EXTERNAL)); + Resource::Property(uris.ingen_Block, Resource::EXTERNAL)); - _parent->add_node(*_patch); + _parent->add_block(*_patch); if (_parent->enabled()) { _patch->enable(); _compiled_patch = _parent->compile(); diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index d2e3e58e..dbda331c 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -18,6 +18,7 @@ #include "raul/Maid.hpp" #include "raul/Path.hpp" +#include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "ControlBindings.hpp" #include "Delete.hpp" @@ -25,7 +26,6 @@ #include "Driver.hpp" #include "Engine.hpp" #include "EnginePort.hpp" -#include "NodeImpl.hpp" #include "PatchImpl.hpp" #include "PluginImpl.hpp" #include "PortImpl.hpp" @@ -73,24 +73,24 @@ Delete::pre_process() return Event::pre_process_done(NOT_FOUND, _path); } - if (!(_node = PtrCast(iter->second))) { + if (!(_block = PtrCast(iter->second))) { _port = PtrCast(iter->second); } - if (!_node && !_port) { + if (!_block && !_port) { return Event::pre_process_done(NOT_DELETABLE, _path); } - PatchImpl* parent = _node ? _node->parent_patch() : _port->parent_patch(); + PatchImpl* parent = _block ? _block->parent_patch() : _port->parent_patch(); if (!parent) { return Event::pre_process_done(INTERNAL_ERROR, _path); } _engine.store()->remove(iter, _removed_objects); - if (_node) { - parent->remove_node(*_node); - _disconnect_event = new DisconnectAll(_engine, parent, _node.get()); + if (_block) { + parent->remove_block(*_block); + _disconnect_event = new DisconnectAll(_engine, parent, _block.get()); _disconnect_event->pre_process(); if (parent->enabled()) { @@ -122,7 +122,7 @@ Delete::execute(ProcessContext& context) _disconnect_event->execute(context); } - PatchImpl* parent = _node ? _node->parent_patch() : _port->parent_patch(); + PatchImpl* parent = _block ? _block->parent_patch() : _port->parent_patch(); if (_port) { _engine.maid()->dispose(parent->external_ports()); parent->external_ports(_ports_array); @@ -143,9 +143,9 @@ Delete::post_process() { _lock.release(); _removed_bindings.reset(); - if (!respond() && (_node || _port)) { - if (_node) { - _node->deactivate(); + if (!respond() && (_block || _port)) { + if (_block) { + _block->deactivate(); } _engine.broadcaster()->bundle_begin(); diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp index f307eba4..c14c5567 100644 --- a/src/server/events/Delete.hpp +++ b/src/server/events/Delete.hpp @@ -30,11 +30,11 @@ template class Array; namespace Ingen { namespace Server { -class NodeImpl; -class PortImpl; +class BlockImpl; +class CompiledPatch; class DuplexPort; class EnginePort; -class CompiledPatch; +class PortImpl; namespace Events { @@ -72,7 +72,7 @@ public: private: Raul::URI _uri; Raul::Path _path; - SharedPtr _node; ///< Non-NULL iff a node + SharedPtr _block; ///< Non-NULL iff a block SharedPtr _port; ///< Non-NULL iff a port EnginePort* _engine_port; Raul::Array* _ports_array; ///< New (external) ports for Patch diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index 1120af92..3b31cedb 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -24,7 +24,7 @@ #include "Broadcaster.hpp" #include "ControlBindings.hpp" -#include "CreateNode.hpp" +#include "CreateBlock.hpp" #include "CreatePatch.hpp" #include "CreatePort.hpp" #include "Delta.hpp" @@ -112,7 +112,7 @@ Delta::pre_process() _object = is_graph_object ? static_cast(_engine.store()->get(GraphObject::uri_to_path(_subject))) - : static_cast(_engine.node_factory()->plugin(_subject)); + : static_cast(_engine.block_factory()->plugin(_subject)); if (!_object && (!is_graph_object || !_create)) { return Event::pre_process_done(NOT_FOUND, _subject); @@ -122,14 +122,14 @@ Delta::pre_process() if (is_graph_object && !_object) { Raul::Path path(GraphObject::uri_to_path(_subject)); - bool is_patch = false, is_node = false, is_port = false, is_output = false; - Ingen::Resource::type(uris, _properties, is_patch, is_node, is_port, is_output); + bool is_patch = false, is_block = false, is_port = false, is_output = false; + Ingen::Resource::type(uris, _properties, is_patch, is_block, is_port, is_output); if (is_patch) { _create_event = new CreatePatch( _engine, _request_client, _request_id, _time, path, _properties); - } else if (is_node) { - _create_event = new CreateNode( + } else if (is_block) { + _create_event = new CreateBlock( _engine, _request_client, _request_id, _time, path, _properties); } else if (is_port) { _create_event = new CreatePort( @@ -223,9 +223,9 @@ Delta::pre_process() if (value.type() == uris.forge.Bool) { op = POLYPHONIC; obj->set_property(key, value, value.context()); - NodeImpl* node = dynamic_cast(obj); - if (node) - node->set_polyphonic(value.get_bool()); + BlockImpl* block = dynamic_cast(obj); + if (block) + block->set_polyphonic(value.get_bool()); if (value.get_bool()) { obj->prepare_poly(*_engine.buffer_factory(), parent->internal_poly()); } else { @@ -271,7 +271,7 @@ Delta::execute(ProcessContext& context) } GraphObjectImpl* const object = dynamic_cast(_object); - NodeImpl* const node = dynamic_cast(_object); + BlockImpl* const block = dynamic_cast(_object); PortImpl* const port = dynamic_cast(_object); std::vector::const_iterator t = _types.begin(); @@ -315,9 +315,9 @@ Delta::execute(ProcessContext& context) case CONTROL_BINDING: if (port) { _engine.control_bindings()->port_binding_changed(context, port, value); - } else if (node) { - if (node->plugin_impl()->type() == Plugin::Internal) { - node->learn(); + } else if (block) { + if (block->plugin_impl()->type() == Plugin::Internal) { + block->learn(); } } break; diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp index 9e1e9531..9cf2974a 100644 --- a/src/server/events/Disconnect.cpp +++ b/src/server/events/Disconnect.cpp @@ -67,21 +67,21 @@ Disconnect::Impl::Impl(Engine& e, { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - NodeImpl* const src_node = _src_output_port->parent_node(); - NodeImpl* const dst_node = _dst_input_port->parent_node(); + BlockImpl* const src_block = _src_output_port->parent_block(); + BlockImpl* const dst_block = _dst_input_port->parent_block(); - for (std::list::iterator i = dst_node->providers().begin(); - i != dst_node->providers().end(); ++i) { - if ((*i) == src_node) { - dst_node->providers().erase(i); + for (std::list::iterator i = dst_block->providers().begin(); + i != dst_block->providers().end(); ++i) { + if ((*i) == src_block) { + dst_block->providers().erase(i); break; } } - for (std::list::iterator i = src_node->dependants().begin(); - i != src_node->dependants().end(); ++i) { - if ((*i) == dst_node) { - src_node->dependants().erase(i); + for (std::list::iterator i = src_block->dependants().begin(); + i != src_block->dependants().end(); ++i) { + if ((*i) == dst_block) { + src_block->dependants().erase(i); break; } } @@ -130,23 +130,23 @@ Disconnect::pre_process() return Event::pre_process_done(PORT_NOT_FOUND, _head_path); } - NodeImpl* const src_node = tail->parent_node(); - NodeImpl* const dst_node = head->parent_node(); + BlockImpl* const src_block = tail->parent_block(); + BlockImpl* const dst_block = head->parent_block(); - if (src_node->parent_patch() != dst_node->parent_patch()) { + if (src_block->parent_patch() != dst_block->parent_patch()) { // Edge to a patch port from inside the patch - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) { - _patch = dynamic_cast(dst_node); + assert(src_block->parent() == dst_block || dst_block->parent() == src_block); + if (src_block->parent() == dst_block) { + _patch = dynamic_cast(dst_block); } else { - _patch = dynamic_cast(src_node); + _patch = dynamic_cast(src_block); } - } else if (src_node == dst_node && dynamic_cast(src_node)) { + } else if (src_block == dst_block && dynamic_cast(src_block)) { // Edge from a patch input to a patch output (pass through) - _patch = dynamic_cast(src_node); + _patch = dynamic_cast(src_block); } else { - // Normal edge between nodes with the same parent - _patch = src_node->parent_patch(); + // Normal edge between blocks with the same parent + _patch = src_block->parent_patch(); } assert(_patch); @@ -155,7 +155,7 @@ Disconnect::pre_process() return Event::pre_process_done(NOT_FOUND, _head_path); } - if (src_node == NULL || dst_node == NULL) { + if (src_block == NULL || dst_block == NULL) { return Event::pre_process_done(PARENT_NOT_FOUND, _head_path); } diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp index 693c8784..4169622d 100644 --- a/src/server/events/DisconnectAll.cpp +++ b/src/server/events/DisconnectAll.cpp @@ -24,11 +24,11 @@ #include "raul/Maid.hpp" #include "raul/Path.hpp" +#include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "EdgeImpl.hpp" #include "Engine.hpp" #include "InputPort.hpp" -#include "NodeImpl.hpp" #include "OutputPort.hpp" #include "PatchImpl.hpp" #include "PortImpl.hpp" @@ -50,7 +50,7 @@ DisconnectAll::DisconnectAll(Engine& engine, , _parent_path(parent_path) , _path(path) , _parent(NULL) - , _node(NULL) + , _block(NULL) , _port(NULL) , _compiled_patch(NULL) , _deleting(false) @@ -66,7 +66,7 @@ DisconnectAll::DisconnectAll(Engine& engine, , _parent_path(parent->path()) , _path(object->path()) , _parent(parent) - , _node(dynamic_cast(object)) + , _block(dynamic_cast(object)) , _port(dynamic_cast(object)) , _compiled_patch(NULL) , _deleting(true) @@ -104,10 +104,10 @@ DisconnectAll::pre_process() } // Only one of these will succeed - _node = dynamic_cast(object); - _port = dynamic_cast(object); + _block = dynamic_cast(object); + _port = dynamic_cast(object); - assert((_node || _port) && !(_node && _port)); + assert((_block || _port) && !(_block && _port)); } // Find set of edges to remove @@ -115,9 +115,9 @@ DisconnectAll::pre_process() for (GraphObject::Edges::const_iterator i = _parent->edges().begin(); i != _parent->edges().end(); ++i) { EdgeImpl* const c = (EdgeImpl*)i->second.get(); - if (_node) { - if (c->tail()->parent_node() == _node - || c->head()->parent_node() == _node) { + if (_block) { + if (c->tail()->parent_block() == _block + || c->head()->parent_block() == _block) { to_remove.insert(c); } } else { @@ -149,7 +149,7 @@ DisconnectAll::execute(ProcessContext& context) if (_status == SUCCESS) { for (Impls::iterator i = _impls.begin(); i != _impls.end(); ++i) { (*i)->execute(context, - !_deleting || ((*i)->head()->parent_node() != _node)); + !_deleting || ((*i)->head()->parent_block() != _block)); } } diff --git a/src/server/events/DisconnectAll.hpp b/src/server/events/DisconnectAll.hpp index 12c04ffa..68ba8ebe 100644 --- a/src/server/events/DisconnectAll.hpp +++ b/src/server/events/DisconnectAll.hpp @@ -27,8 +27,8 @@ namespace Ingen { namespace Server { +class BlockImpl; class CompiledPatch; -class NodeImpl; class PatchImpl; class PortImpl; @@ -36,7 +36,7 @@ namespace Events { class Disconnect; -/** An event to disconnect all connections to a Node. +/** An event to disconnect all connections to a Block. * * \ingroup engine */ @@ -66,7 +66,7 @@ private: Raul::Path _parent_path; Raul::Path _path; PatchImpl* _parent; - NodeImpl* _node; + BlockImpl* _block; PortImpl* _port; Impls _impls; CompiledPatch* _compiled_patch; diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index 294a15b3..24b4daae 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -20,12 +20,12 @@ #include "ingen/Interface.hpp" #include "ingen/Store.hpp" +#include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "BufferFactory.hpp" #include "Driver.hpp" #include "Engine.hpp" #include "Get.hpp" -#include "NodeImpl.hpp" #include "PatchImpl.hpp" #include "PluginImpl.hpp" #include "PortImpl.hpp" @@ -56,7 +56,7 @@ Get::pre_process() _lock.acquire(); if (_uri == "ingen:plugins") { - _plugins = _engine.node_factory()->plugins(); + _plugins = _engine.block_factory()->plugins(); return Event::pre_process_done(SUCCESS); } else if (_uri == "ingen:engine") { return Event::pre_process_done(SUCCESS); @@ -64,7 +64,7 @@ Get::pre_process() _object = _engine.store()->get(GraphObject::uri_to_path(_uri)); return Event::pre_process_done(_object ? SUCCESS : NOT_FOUND, _uri); } else { - _plugin = _engine.node_factory()->plugin(_uri); + _plugin = _engine.block_factory()->plugin(_uri); return Event::pre_process_done(_plugin ? SUCCESS : NOT_FOUND, _uri); } } @@ -84,15 +84,15 @@ send_port(Interface* client, const PortImpl* port) } static void -send_node(Interface* client, const NodeImpl* node) +send_block(Interface* client, const BlockImpl* block) { - PluginImpl* const plugin = node->plugin_impl(); + PluginImpl* const plugin = block->plugin_impl(); if (plugin->type() == Plugin::Patch) { - send_patch(client, (const PatchImpl*)node); + send_patch(client, (const PatchImpl*)block); } else { - client->put(node->uri(), node->properties()); - for (size_t j = 0; j < node->num_ports(); ++j) { - send_port(client, node->port_impl(j)); + client->put(block->uri(), block->properties()); + for (size_t j = 0; j < block->num_ports(); ++j) { + send_port(client, block->port_impl(j)); } } } @@ -108,10 +108,10 @@ send_patch(Interface* client, const PatchImpl* patch) patch->properties(Resource::EXTERNAL), Resource::EXTERNAL); - // Send nodes - for (PatchImpl::Nodes::const_iterator j = patch->nodes().begin(); - j != patch->nodes().end(); ++j) { - send_node(client, &*j); + // Send blocks + for (PatchImpl::Blocks::const_iterator j = patch->blocks().begin(); + j != patch->blocks().end(); ++j) { + send_block(client, &*j); } // Send ports @@ -141,13 +141,13 @@ Get::post_process() uris.forge.make(int32_t(_engine.driver()->sample_rate()))); } else if (_object) { _request_client->bundle_begin(); - const NodeImpl* node = NULL; + const BlockImpl* block = NULL; const PatchImpl* patch = NULL; const PortImpl* port = NULL; if ((patch = dynamic_cast(_object))) { send_patch(_request_client.get(), patch); - } else if ((node = dynamic_cast(_object))) { - send_node(_request_client.get(), node); + } else if ((block = dynamic_cast(_object))) { + send_block(_request_client.get(), block); } else if ((port = dynamic_cast(_object))) { send_port(_request_client.get(), port); } diff --git a/src/server/events/Get.hpp b/src/server/events/Get.hpp index 12cedd4d..7b33304e 100644 --- a/src/server/events/Get.hpp +++ b/src/server/events/Get.hpp @@ -20,7 +20,7 @@ #include #include "Event.hpp" -#include "NodeFactory.hpp" +#include "BlockFactory.hpp" #include "types.hpp" namespace Ingen { @@ -51,7 +51,7 @@ private: const Raul::URI _uri; const GraphObject* _object; const PluginImpl* _plugin; - NodeFactory::Plugins _plugins; + BlockFactory::Plugins _plugins; Glib::RWLock::ReaderLock _lock; }; diff --git a/src/server/events/Move.cpp b/src/server/events/Move.cpp index 5fa58825..d5b4d116 100644 --- a/src/server/events/Move.cpp +++ b/src/server/events/Move.cpp @@ -19,11 +19,11 @@ #include "ingen/Store.hpp" #include "raul/Path.hpp" +#include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "Driver.hpp" #include "Engine.hpp" #include "EnginePort.hpp" -#include "NodeImpl.hpp" #include "PatchImpl.hpp" #include "events/Move.hpp" diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp index d81a38f7..7a994caa 100644 --- a/src/server/events/SetPortValue.cpp +++ b/src/server/events/SetPortValue.cpp @@ -19,12 +19,12 @@ #include "ingen/URIs.hpp" #include "ingen/World.hpp" +#include "BlockImpl.hpp" #include "Broadcaster.hpp" #include "Buffer.hpp" #include "ControlBindings.hpp" #include "Driver.hpp" #include "Engine.hpp" -#include "NodeImpl.hpp" #include "PortImpl.hpp" #include "ProcessContext.hpp" #include "SetPortValue.hpp" @@ -71,7 +71,7 @@ SetPortValue::execute(ProcessContext& context) { assert(_time >= context.start() && _time <= context.end()); - if (_port->parent_node()->context() == Context::MESSAGE) + if (_port->parent_block()->context() == Context::MESSAGE) return; apply(context); diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp index 69775873..5158e441 100644 --- a/src/server/ingen_lv2.cpp +++ b/src/server/ingen_lv2.cpp @@ -432,7 +432,7 @@ find_patches(const Glib::ustring& manifest_uri) const Sord::URI rdf_type (world, NS_RDF "type"); const Sord::URI rdfs_seeAlso(world, NS_RDFS "seeAlso"); - SerdEnv* env = serd_env_new(sord_node_to_serd_node(base.c_obj())); + SerdEnv* env = serd_env_new(sord_node_to_serd_node(base.c_obj())); Sord::Model model(world, manifest_uri); model.load_file(env, SERD_TURTLE, manifest_uri); diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp index 1fb3cf76..0e8d125e 100644 --- a/src/server/internals/Controller.cpp +++ b/src/server/internals/Controller.cpp @@ -47,7 +47,7 @@ ControllerNode::ControllerNode(InternalPlugin* plugin, bool polyphonic, PatchImpl* parent, SampleRate srate) - : NodeImpl(plugin, symbol, false, parent, srate) + : BlockImpl(plugin, symbol, false, parent, srate) , _learning(false) { const Ingen::URIs& uris = bufs.uris(); @@ -91,7 +91,7 @@ ControllerNode::ControllerNode(InternalPlugin* plugin, void ControllerNode::process(ProcessContext& context) { - NodeImpl::pre_process(context); + BlockImpl::pre_process(context); Buffer* const midi_in = _midi_in_port->buffer(0).get(); LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)midi_in->atom(); @@ -104,7 +104,7 @@ ControllerNode::process(ProcessContext& context) } } - NodeImpl::post_process(context); + BlockImpl::post_process(context); } void diff --git a/src/server/internals/Controller.hpp b/src/server/internals/Controller.hpp index 4a366b08..23401826 100644 --- a/src/server/internals/Controller.hpp +++ b/src/server/internals/Controller.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_INTERNALS_CONTROLLER_HPP #define INGEN_INTERNALS_CONTROLLER_HPP -#include "NodeImpl.hpp" +#include "BlockImpl.hpp" namespace Ingen { namespace Server { @@ -28,14 +28,14 @@ class InternalPlugin; namespace Internals { -/** MIDI control input node. +/** MIDI control input block. * * Creating one of these nodes is how a user makes "MIDI Bindings". Note that * this node will always be monophonic, the poly parameter is ignored. * * \ingroup engine */ -class ControllerNode : public NodeImpl +class ControllerNode : public BlockImpl { public: ControllerNode(InternalPlugin* plugin, diff --git a/src/server/internals/Delay.cpp b/src/server/internals/Delay.cpp index 26799260..1e7ed5a5 100644 --- a/src/server/internals/Delay.cpp +++ b/src/server/internals/Delay.cpp @@ -55,7 +55,7 @@ DelayNode::DelayNode(InternalPlugin* plugin, bool polyphonic, PatchImpl* parent, SampleRate srate) - : NodeImpl(plugin, symbol, polyphonic, parent, srate) + : BlockImpl(plugin, symbol, polyphonic, parent, srate) , _buffer(0) , _buffer_length(0) , _buffer_mask(0) @@ -100,7 +100,7 @@ DelayNode::~DelayNode() void DelayNode::activate(BufferFactory& bufs) { - NodeImpl::activate(bufs); + BlockImpl::activate(bufs); const SampleRate rate = bufs.engine().driver()->sample_rate(); const SampleCount min_size = MAX_DELAY_SECONDS * rate; @@ -144,7 +144,7 @@ DelayNode::process(ProcessContext& context) Buffer* const in_buf = _in_port->buffer(0).get(); Buffer* const out_buf = _out_port->buffer(0).get(); - NodeImpl::pre_process(context); + BlockImpl::pre_process(context); DelayNode* plugin_data = this; @@ -201,7 +201,7 @@ DelayNode::process(ProcessContext& context) _write_phase = write_phase; - NodeImpl::post_process(context); + BlockImpl::post_process(context); } } // namespace Internals diff --git a/src/server/internals/Delay.hpp b/src/server/internals/Delay.hpp index 3c512d2c..8f4b758b 100644 --- a/src/server/internals/Delay.hpp +++ b/src/server/internals/Delay.hpp @@ -19,7 +19,7 @@ #include -#include "NodeImpl.hpp" +#include "BlockImpl.hpp" #include "types.hpp" namespace Ingen { @@ -32,7 +32,7 @@ class BufferFactory; namespace Internals { -class DelayNode : public NodeImpl +class DelayNode : public BlockImpl { public: DelayNode(InternalPlugin* plugin, diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp index 25e8aee5..00ab0835 100644 --- a/src/server/internals/Note.cpp +++ b/src/server/internals/Note.cpp @@ -52,7 +52,7 @@ NoteNode::NoteNode(InternalPlugin* plugin, bool polyphonic, PatchImpl* parent, SampleRate srate) - : NodeImpl(plugin, symbol, polyphonic, parent, srate) + : BlockImpl(plugin, symbol, polyphonic, parent, srate) , _voices(new Raul::Array(_polyphony)) , _prepared_voices(NULL) , _sustain(false) @@ -103,7 +103,7 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly) if (!_polyphonic) return true; - NodeImpl::prepare_poly(bufs, poly); + BlockImpl::prepare_poly(bufs, poly); if (_prepared_voices && poly <= _prepared_voices->size()) return true; @@ -116,7 +116,7 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly) bool NoteNode::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) { - if (!NodeImpl::apply_poly(context, maid, poly)) + if (!BlockImpl::apply_poly(context, maid, poly)) return false; if (_prepared_voices) { @@ -133,7 +133,7 @@ NoteNode::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) void NoteNode::process(ProcessContext& context) { - NodeImpl::pre_process(context); + BlockImpl::pre_process(context); Buffer* const midi_in = _midi_in_port->buffer(0).get(); LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)midi_in->atom(); @@ -173,7 +173,7 @@ NoteNode::process(ProcessContext& context) } } - NodeImpl::post_process(context); + BlockImpl::post_process(context); } void diff --git a/src/server/internals/Note.hpp b/src/server/internals/Note.hpp index 6c7d9a13..290908e8 100644 --- a/src/server/internals/Note.hpp +++ b/src/server/internals/Note.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_INTERNALS_NOTE_HPP #define INGEN_INTERNALS_NOTE_HPP -#include "NodeImpl.hpp" +#include "BlockImpl.hpp" #include "types.hpp" namespace Ingen { @@ -29,13 +29,13 @@ class InternalPlugin; namespace Internals { -/** MIDI note input node. +/** MIDI note input block. * * For pitched instruments like keyboard, etc. * * \ingroup engine */ -class NoteNode : public NodeImpl +class NoteNode : public BlockImpl { public: NoteNode(InternalPlugin* plugin, diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp index f7bbd4c5..31943425 100644 --- a/src/server/internals/Trigger.cpp +++ b/src/server/internals/Trigger.cpp @@ -47,7 +47,7 @@ TriggerNode::TriggerNode(InternalPlugin* plugin, bool polyphonic, PatchImpl* parent, SampleRate srate) - : NodeImpl(plugin, symbol, false, parent, srate) + : BlockImpl(plugin, symbol, false, parent, srate) , _learning(false) { const Ingen::URIs& uris = bufs.uris(); @@ -89,7 +89,7 @@ TriggerNode::TriggerNode(InternalPlugin* plugin, void TriggerNode::process(ProcessContext& context) { - NodeImpl::pre_process(context); + BlockImpl::pre_process(context); Buffer* const midi_in = _midi_in_port->buffer(0).get(); LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)midi_in->atom(); @@ -121,7 +121,7 @@ TriggerNode::process(ProcessContext& context) } } - NodeImpl::post_process(context); + BlockImpl::post_process(context); } void diff --git a/src/server/internals/Trigger.hpp b/src/server/internals/Trigger.hpp index 59badc70..750cd287 100644 --- a/src/server/internals/Trigger.hpp +++ b/src/server/internals/Trigger.hpp @@ -17,7 +17,7 @@ #ifndef INGEN_INTERNALS_TRIGGER_HPP #define INGEN_INTERNALS_TRIGGER_HPP -#include "NodeImpl.hpp" +#include "BlockImpl.hpp" namespace Ingen { namespace Server { @@ -28,17 +28,17 @@ class InternalPlugin; namespace Internals { -/** MIDI trigger input node. +/** MIDI trigger input block. * - * Just has a gate, for drums etc. A control port is used to select + * Just has a gate, for drums etc. A control port is used to select * which note number is responded to. * - * Note that this node is always monophonic, the poly parameter is ignored. + * Note that this block is always monophonic, the poly parameter is ignored. * (Should that change?) * * \ingroup engine */ -class TriggerNode : public NodeImpl +class TriggerNode : public BlockImpl { public: TriggerNode(InternalPlugin* plugin, diff --git a/src/server/wscript b/src/server/wscript index 5c98d189..9664545a 100644 --- a/src/server/wscript +++ b/src/server/wscript @@ -3,6 +3,8 @@ from waflib.extras import autowaf as autowaf def build(bld): core_source = ''' + BlockFactory.cpp + BlockImpl.cpp Broadcaster.cpp Buffer.cpp BufferFactory.cpp @@ -15,11 +17,9 @@ def build(bld): GraphObjectImpl.cpp InputPort.cpp InternalPlugin.cpp + LV2Block.cpp LV2Info.cpp - LV2Node.cpp LV2Plugin.cpp - NodeFactory.cpp - NodeImpl.cpp OutputPort.cpp PatchImpl.cpp PortImpl.cpp @@ -27,7 +27,7 @@ def build(bld): PreProcessor.cpp Worker.cpp events/Connect.cpp - events/CreateNode.cpp + events/CreateBlock.cpp events/CreatePatch.cpp events/CreatePort.cpp events/Delete.cpp -- cgit v1.2.1