From 87597f85c5a69a9accd3ce2ed88f2a006173e885 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 3 Feb 2010 04:46:56 +0000 Subject: Comprehensive use of cached URIs and more advanced Value (Atom) system. Atoms (e.g. property values or port values) can now be an Atom::DICT, which maps directly to/from an RDF resource. This is now used to store control bindings as a port property, eliminating the special API. Full interned URIs used everywhere, instead of CURIEs pretending to be URIs. Avoid converting string literals to URIs all over the place. Support for binding MIDI pitch bender and MIDI channel pressure. Saving/restoring of MIDI bindings as a free side-effect of the above. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2409 a436a847-0d15-0410-975c-d299462d15a1 --- src/bindings/Client.hpp | 1 - src/bindings/test_ingen.py | 7 +- src/client/ClientStore.cpp | 35 ++++---- src/client/ClientStore.hpp | 3 +- src/client/DeprecatedLoader.cpp | 60 ++++++++------ src/client/HTTPClientReceiver.cpp | 1 + src/client/HTTPEngineSender.cpp | 2 +- src/client/NodeModel.cpp | 7 +- src/client/ObjectModel.cpp | 4 +- src/client/PatchModel.cpp | 5 +- src/client/PatchModel.hpp | 2 +- src/client/PluginModel.cpp | 14 ++-- src/client/PluginUI.cpp | 2 +- src/client/PluginUI.hpp | 3 +- src/client/PortModel.cpp | 4 +- src/client/PortModel.hpp | 6 +- src/client/SigClientInterface.hpp | 6 +- src/client/ThreadedSigClientInterface.hpp | 8 +- src/common/interface/ClientInterface.hpp | 4 - src/common/interface/EventType.hpp | 21 +++-- src/common/interface/MessageType.hpp | 120 --------------------------- src/common/interface/Plugin.hpp | 34 ++++---- src/common/interface/PortType.hpp | 39 ++++----- src/engine/ClientBroadcaster.hpp | 6 +- src/engine/ControlBindings.cpp | 106 ++++++++++++++++++----- src/engine/ControlBindings.hpp | 24 +++++- src/engine/Engine.cpp | 8 +- src/engine/Engine.hpp | 3 +- src/engine/HTTPClientSender.cpp | 11 +-- src/engine/HTTPClientSender.hpp | 2 - src/engine/InputPort.cpp | 9 +- src/engine/InternalPlugin.cpp | 3 +- src/engine/JackDriver.cpp | 1 + src/engine/LADSPANode.cpp | 8 +- src/engine/LADSPAPlugin.cpp | 5 +- src/engine/LV2Node.cpp | 9 +- src/engine/LV2Plugin.cpp | 3 +- src/engine/NodeImpl.hpp | 1 - src/engine/OSCClientSender.cpp | 20 ----- src/engine/OSCClientSender.hpp | 2 - src/engine/OSCEngineReceiver.cpp | 2 +- src/engine/ObjectSender.cpp | 3 +- src/engine/OutputPort.cpp | 5 +- src/engine/PortImpl.cpp | 7 +- src/engine/QueuedEngineInterface.hpp | 2 +- src/engine/events/AllNotesOff.cpp | 1 - src/engine/events/CreateNode.cpp | 1 - src/engine/events/CreatePort.cpp | 23 +++-- src/engine/events/SendBinding.cpp | 15 +++- src/engine/events/SendBinding.hpp | 28 +++++-- src/engine/events/SetMetadata.cpp | 17 +++- src/engine/events/SetMetadata.hpp | 3 +- src/engine/events/SetPortValue.cpp | 2 +- src/engine/ingen_engine.cpp | 1 + src/engine/internals/Controller.cpp | 10 ++- src/engine/internals/Note.cpp | 10 ++- src/engine/internals/Trigger.cpp | 16 ++-- src/gui/LoadPluginWindow.cpp | 12 +-- src/gui/NodeModule.cpp | 5 +- src/gui/PatchCanvas.cpp | 20 ++--- src/gui/PatchWindow.cpp | 12 +-- src/gui/Port.cpp | 10 +-- src/gui/PropertiesWindow.cpp | 16 +++- src/gui/RenameWindow.cpp | 10 ++- src/gui/UploadPatchWindow.cpp | 12 ++- src/ingen/main.cpp | 2 + src/scripts/python/scripts/flatten.py | 4 +- src/scripts/python/scripts/sillysinepatch.py | 4 +- src/serialisation/Parser.cpp | 73 ++++++++-------- src/serialisation/Parser.hpp | 4 +- src/serialisation/Serialiser.cpp | 16 ++-- src/shared/Builder.cpp | 4 +- src/shared/LV2Object.cpp | 27 +++--- src/shared/LV2URIMap.cpp | 87 +++++++++++++------ src/shared/LV2URIMap.hpp | 24 +++++- src/shared/ResourceImpl.cpp | 71 ++++++++-------- 76 files changed, 619 insertions(+), 549 deletions(-) delete mode 100644 src/common/interface/MessageType.hpp (limited to 'src') diff --git a/src/bindings/Client.hpp b/src/bindings/Client.hpp index 956b51d4..fdb8d62c 100644 --- a/src/bindings/Client.hpp +++ b/src/bindings/Client.hpp @@ -26,5 +26,4 @@ public: void set_property(const Raul::URI& subject, const Raul::URI& key, const Raul::Atom& value) {} void set_voice_value(const Raul::Path& port_path, uint32_t voice, const Raul::Atom& value) {} void activity(const Raul::Path& port_path) {} - void binding(const Raul::Path& path, const MessageType& type) {} }; diff --git a/src/bindings/test_ingen.py b/src/bindings/test_ingen.py index c858e7df..921bdd1b 100755 --- a/src/bindings/test_ingen.py +++ b/src/bindings/test_ingen.py @@ -26,12 +26,7 @@ e.activate() c.subscribe(e) -e.create_port("/I", "ingen:midi", False) -e.create_port("/made", "ingen:audio", False) -e.create_port("/these", "ingen:audio", False) -e.create_port("/in", "ingen:midi", True) -e.create_port("/a", "ingen:audio", True) -e.create_port("/script", "ingen:audio", True) +e.create_port("/dynamic_port", "http://lv2plug.in/ns/ext/event#EventPort", False) while True: world.iteration() diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index eb42f6a9..e5fbab6a 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -17,7 +17,7 @@ #include "raul/log.hpp" #include "raul/PathTable.hpp" -#include "interface/MessageType.hpp" +#include "shared/LV2URIMap.hpp" #include "ClientStore.hpp" #include "ObjectModel.hpp" #include "PatchModel.hpp" @@ -53,7 +53,6 @@ ClientStore::ClientStore(SharedPtr engine, SharedPtrsignal_property_change.connect(sigc::mem_fun(this, &ClientStore::set_property)); emitter->signal_voice_value.connect(sigc::mem_fun(this, &ClientStore::set_voice_value)); emitter->signal_activity.connect(sigc::mem_fun(this, &ClientStore::activity)); - emitter->signal_binding.connect(sigc::mem_fun(this, &ClientStore::binding)); } @@ -258,12 +257,19 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) bool is_path = Path::is_valid(uri.str()); bool is_meta = ResourceImpl::is_meta_uri(uri); + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + if (!(is_path || is_meta)) { - const URI& type_uri = properties.find("rdf:type")->second.get_uri(); - if (Plugin::type_from_uri(type_uri.str()) != Plugin::NIL) { - SharedPtr p(new PluginModel(uri, type_uri, properties)); - add_plugin(p); - return; + const Atom& type = properties.find(uris.rdf_type)->second; + if (type.type() == Atom::URI) { + const URI& type_uri = type.get_uri(); + if (Plugin::type_from_uri(type_uri) != Plugin::NIL) { + SharedPtr p(new PluginModel(uri, type_uri, properties)); + add_plugin(p); + return; + } + } else { + LOG(error) << "Non-URI type " << type << endl; } } @@ -287,20 +293,20 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) if (is_patch) { uint32_t poly = 1; - iterator p = properties.find("ingen:polyphony"); + iterator p = properties.find(uris.ingen_polyphony); if (p != properties.end() && p->second.is_valid() && p->second.type() == Atom::INT) poly = p->second.get_int32(); SharedPtr model(new PatchModel(path, poly)); model->set_properties(properties); add_object(model); } else if (is_node) { - const Resource::Properties::const_iterator p = properties.find("rdf:instanceOf"); + const Resource::Properties::const_iterator p = properties.find(uris.rdf_instanceOf); SharedPtr plug; if (p->second.is_valid() && p->second.type() == Atom::URI) { if (!(plug = plugin(p->second.get_uri()))) { LOG(warn) << "Unable to find plugin " << p->second.get_uri() << endl; plug = SharedPtr( - new PluginModel(p->second.get_uri(), "ingen:nil", Resource::Properties())); + new PluginModel(p->second.get_uri(), uris.ingen_nil, Resource::Properties())); add_plugin(plug); } @@ -313,7 +319,7 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) } else if (is_port) { if (data_type != PortType::UNKNOWN) { PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - const Resource::Properties::const_iterator i = properties.find("lv2:index"); + const Resource::Properties::const_iterator i = properties.find(uris.lv2_index); if (i != properties.end() && i->second.type() == Atom::INT) { SharedPtr p(new PortModel(path, i->second.get_int32(), data_type, pdir)); p->set_properties(properties); @@ -378,13 +384,6 @@ ClientStore::activity(const Path& path) } -void -ClientStore::binding(const Path& path, const Shared::MessageType& type) -{ - LOG(info) << "Bind " << path << " : " << type << endl; -} - - SharedPtr ClientStore::connection_patch(const Path& src_port_path, const Path& dst_port_path) { diff --git a/src/client/ClientStore.hpp b/src/client/ClientStore.hpp index 309e7795..38df414e 100644 --- a/src/client/ClientStore.hpp +++ b/src/client/ClientStore.hpp @@ -33,7 +33,7 @@ namespace Raul { class Atom; } namespace Ingen { -namespace Shared { class GraphObject; class MessageType; } +namespace Shared { class GraphObject; } namespace Client { @@ -95,7 +95,6 @@ private: // Slots for SigClientInterface signals void object_moved(const Raul::Path& old_path, const Raul::Path& new_path); void activity(const Raul::Path& path); - void binding(const Raul::Path& path, const Shared::MessageType& type); bool attempt_connection(const Raul::Path& src_port_path, const Raul::Path& dst_port_path); diff --git a/src/client/DeprecatedLoader.cpp b/src/client/DeprecatedLoader.cpp index ec603760..8d774e17 100644 --- a/src/client/DeprecatedLoader.cpp +++ b/src/client/DeprecatedLoader.cpp @@ -29,6 +29,7 @@ #include #include "raul/log.hpp" #include "raul/Path.hpp" +#include "shared/LV2URIMap.hpp" #include "interface/EngineInterface.hpp" #include "DeprecatedLoader.hpp" @@ -224,13 +225,15 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, size_t poly = 0; + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + /* Use parameter overridden polyphony, if given */ - GraphObject::Properties::iterator poly_param = initial_data.find("ingen:polyphony"); + GraphObject::Properties::iterator poly_param = initial_data.find(uris.ingen_polyphony); if (poly_param != initial_data.end() && poly_param->second.type() == Atom::INT) poly = poly_param->second.get_int32(); - if (initial_data.find("filename") == initial_data.end()) - initial_data.insert(make_pair("filename", Atom(filename.c_str()))); // FIXME: URL? + if (initial_data.find(uris.ingen_document) == initial_data.end()) + initial_data.insert(make_pair(uris.ingen_document, filename)); xmlDocPtr doc = xmlParseFile(filename.c_str()); @@ -294,8 +297,8 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, // Create it, if we're not merging if (!existing && !path.is_root()) { Resource::Properties props; - props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Patch"))); - props.insert(make_pair("ingen:polyphony", Atom((int32_t)poly))); + props.insert(make_pair(uris.rdf_type, uris.ingen_Patch)); + props.insert(make_pair(uris.ingen_polyphony, Atom((int32_t)poly))); _engine->put(path, props); for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) _engine->set_property(path, i->first, i->second); @@ -340,7 +343,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, for ( ; i != pm->controls().end(); ++i) { const float value = i->value(); _engine->set_property(translate_load_path(i->port_path().str()), - "ingen:value", Atom(value)); + uris.ingen_value, Atom(value)); } } else { LOG(warn) << "Unknown preset `" << pm->name() << "'" << endl; @@ -357,7 +360,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, // _engine->set_property(subject, i->first, i->second); if (!existing) - _engine->set_property(path, "ingen:enabled", (bool)true); + _engine->set_property(path, uris.ingen_enabled, (bool)true); _load_path_translations.clear(); @@ -451,38 +454,40 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr return false; } + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + // Compatibility hacks for old patches that represent patch ports as nodes if (plugin_uri == "") { bool is_port = false; Resource::Properties props; - props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Patch"))); + props.insert(make_pair(uris.rdf_type, uris.ingen_Patch)); if (plugin_type == "Internal") { is_port = true; if (plugin_label == "audio_input") { - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:AudioPort"))); - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:InputPort"))); + props.insert(make_pair(uris.rdf_type, uris.lv2_AudioPort)); + props.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); _engine->put(path, props); } else if (plugin_label == "audio_output") { - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:AudioPort"))); - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:OutputPort"))); + props.insert(make_pair(uris.rdf_type, uris.lv2_AudioPort)); + props.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort)); _engine->put(path, props); } else if (plugin_label == "control_input") { - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:ControlPort"))); - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:InputPort"))); + props.insert(make_pair(uris.rdf_type, uris.lv2_ControlPort)); + props.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); _engine->put(path, props); } else if (plugin_label == "control_output" ) { - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:ControlPort"))); - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:OutputPort"))); + props.insert(make_pair(uris.rdf_type, uris.lv2_ControlPort)); + props.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort)); _engine->put(path, props); } else if (plugin_label == "midi_input") { - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2ev:EventPort"))); - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:InputPort"))); + props.insert(make_pair(uris.rdf_type, uris.lv2ev_EventPort)); + props.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); _engine->put(path, props); } else if (plugin_label == "midi_output" ) { - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2ev:EventPort"))); - props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:OutputPort"))); + props.insert(make_pair(uris.rdf_type, uris.lv2ev_EventPort)); + props.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort)); _engine->put(path, props); } else { is_port = false; @@ -528,11 +533,11 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr plugin_uri = "om:" + plugin_type + ":" + library_name + ":" + plugin_label; Resource::Properties props; - props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Node"))); - props.insert(make_pair("rdf:instanceOf", Atom(Atom::URI, plugin_uri))); + props.insert(make_pair(uris.rdf_type, uris.ingen_Node)); + props.insert(make_pair(uris.rdf_instanceOf, Atom(Atom::URI, plugin_uri))); _engine->put(path, props); - _engine->set_property(path, "ingen:polyphonic", bool(polyphonic)); + _engine->set_property(path, uris.ingen_polyphonic, bool(polyphonic)); for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) _engine->set_property(path, i->first, i->second); @@ -543,10 +548,10 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr // Not deprecated } else { Resource::Properties props; - props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Node"))); - props.insert(make_pair("rdf:instanceOf", Atom(Atom::URI, plugin_uri))); + props.insert(make_pair(uris.rdf_type, uris.ingen_Node)); + props.insert(make_pair(uris.rdf_instanceOf, Atom(Atom::URI, plugin_uri))); _engine->put(path, props); - _engine->set_property(path, "ingen:polyphonic", bool(polyphonic)); + _engine->set_property(path, uris.ingen_polyphonic, bool(polyphonic)); for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) _engine->set_property(path, i->first, i->second); return true; @@ -567,6 +572,7 @@ DeprecatedLoader::load_subpatch(const string& base_filename, const Path& parent, size_t poly = 0; GraphObject::Properties initial_data; + const LV2URIMap& uris = Shared::LV2URIMap::instance(); while (cur != NULL) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); @@ -574,7 +580,7 @@ DeprecatedLoader::load_subpatch(const string& base_filename, const Path& parent, if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { name = (const char*)key; } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) { - initial_data.insert(make_pair("ingen::polyphony", (int)poly)); + initial_data.insert(make_pair(uris.ingen_polyphony, (int)poly)); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"filename"))) { filename = base_filename + "/" + (const char*)key; } else { // Don't know what this tag is, add it as variable diff --git a/src/client/HTTPClientReceiver.cpp b/src/client/HTTPClientReceiver.cpp index c4eb2416..0eee23ca 100644 --- a/src/client/HTTPClientReceiver.cpp +++ b/src/client/HTTPClientReceiver.cpp @@ -24,6 +24,7 @@ #include "raul/log.hpp" #include "raul/Atom.hpp" #include "module/Module.hpp" +#include "module/World.hpp" #include "HTTPClientReceiver.hpp" #define LOG(s) s << "[HTTPClientReceiver] " diff --git a/src/client/HTTPEngineSender.cpp b/src/client/HTTPEngineSender.cpp index 91c8d76c..0b544600 100644 --- a/src/client/HTTPEngineSender.cpp +++ b/src/client/HTTPEngineSender.cpp @@ -124,7 +124,7 @@ HTTPEngineSender::put(const URI& uri, model.add_statement( Redland::Resource(_world, path), i->first.str(), - AtomRDF::atom_to_node(_world, i->second)); + AtomRDF::atom_to_node(model, i->second)); const string str = model.serialise_to_string(); SoupMessage* msg = soup_message_new(SOUP_METHOD_PUT, full_uri.c_str()); diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp index df72c9e2..bed43e7a 100644 --- a/src/client/NodeModel.cpp +++ b/src/client/NodeModel.cpp @@ -19,6 +19,8 @@ #include #include "ingen-config.h" #include "interface/Port.hpp" +#include "module/World.hpp" +#include "shared/LV2URIMap.hpp" #include "NodeModel.hpp" using namespace std; @@ -204,13 +206,14 @@ NodeModel::default_port_value_range(SharedPtr port, float& min, float void NodeModel::port_value_range(SharedPtr port, float& min, float& max) const { + const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance(); assert(port->parent().get() == this); default_port_value_range(port, min, max); // Possibly overriden - const Atom& min_atom = port->get_property("lv2:minimum"); - const Atom& max_atom = port->get_property("lv2:maximum"); + const Atom& min_atom = port->get_property(uris.lv2_minimum); + const Atom& max_atom = port->get_property(uris.lv2_maximum); if (min_atom.type() == Atom::FLOAT) min = min_atom.get_float(); if (max_atom.type() == Atom::FLOAT) diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index 69d79d1e..e121a868 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -17,8 +17,6 @@ #include "raul/TableImpl.hpp" #include "interface/GraphObject.hpp" -#include "module/ingen_module.hpp" -#include "module/World.hpp" #include "shared/LV2URIMap.hpp" #include "ObjectModel.hpp" @@ -78,7 +76,7 @@ ObjectModel::get_property(const Raul::URI& key) const bool ObjectModel::polyphonic() const { - const Raul::Atom& polyphonic = get_property(ingen_get_world()->uris->ingen_polyphonic); + const Raul::Atom& polyphonic = get_property(Shared::LV2URIMap::instance().ingen_polyphonic); return (polyphonic.is_valid() && polyphonic.get_bool()); } diff --git a/src/client/PatchModel.cpp b/src/client/PatchModel.cpp index 7b29b3f6..7d44eb1c 100644 --- a/src/client/PatchModel.cpp +++ b/src/client/PatchModel.cpp @@ -17,7 +17,6 @@ #include #include "raul/log.hpp" -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "PatchModel.hpp" #include "NodeModel.hpp" @@ -165,7 +164,7 @@ PatchModel::remove_connection(const Path& src_port_path, const Path& dst_port_pa bool PatchModel::enabled() const { - const Raul::Atom& enabled = get_property(ingen_get_world()->uris->ingen_enabled); + const Raul::Atom& enabled = get_property(Shared::LV2URIMap::instance().ingen_enabled); return (enabled.is_valid() && enabled.get_bool()); } @@ -173,7 +172,7 @@ PatchModel::enabled() const Raul::Atom& PatchModel::set_meta_property(const Raul::URI& key, const Atom& value) { - if (key == ingen_get_world()->uris->ingen_polyphony) + if (key == Shared::LV2URIMap::instance().ingen_polyphony) _poly = value.get_int32(); return NodeModel::set_meta_property(key, value); diff --git a/src/client/PatchModel.hpp b/src/client/PatchModel.hpp index 748c2704..d87c4ee8 100644 --- a/src/client/PatchModel.hpp +++ b/src/client/PatchModel.hpp @@ -75,7 +75,7 @@ private: friend class ClientStore; PatchModel(const Raul::Path& patch_path, size_t internal_poly) - : NodeModel("ingen:Patch", patch_path) + : NodeModel("http://drobilla.net/ns/ingen#Patch", patch_path) , _connections(new Connections()) , _poly(internal_poly) , _editable(true) diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp index d740a3c1..43571f08 100644 --- a/src/client/PluginModel.cpp +++ b/src/client/PluginModel.cpp @@ -21,7 +21,6 @@ #include "raul/Path.hpp" #include "raul/Atom.hpp" #include "ingen-config.h" -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "PluginModel.hpp" #include "PatchModel.hpp" @@ -49,14 +48,15 @@ PluginModel::PluginModel(const URI& uri, const URI& type_uri, const Resource::Pr Glib::Mutex::Lock lock(_rdf_world->mutex()); assert(_rdf_world); - add_property("rdf:type", Atom(Atom::URI, this->type_uri())); + add_property("http://www.w3.org/1999/02/22-rdf-syntax-ns#type", this->type_uri()); #ifdef HAVE_SLV2 SLV2Value plugin_uri = slv2_value_new_uri(_slv2_world, uri.c_str()); _slv2_plugin = slv2_plugins_get_by_uri(_slv2_plugins, plugin_uri); slv2_value_free(plugin_uri); #endif if (_type == Internal) - set_property("doap:name", Atom(uri.substr(uri.find_last_of('#') + 1).c_str())); + set_property("http://usefulinc.com/ns/doap#name", + Atom(uri.substr(uri.find_last_of('#') + 1).c_str())); } @@ -69,7 +69,7 @@ PluginModel::get_property(const URI& key) const return val; // No lv2:symbol from data or engine, invent one - if (key == ingen_get_world()->uris->lv2_symbol) { + if (key == Shared::LV2URIMap::instance().lv2_symbol) { const URI& uri = this->uri(); size_t last_slash = uri.find_last_of('/'); size_t last_hash = uri.find_last_of('#'); @@ -92,7 +92,7 @@ PluginModel::get_property(const URI& key) const else symbol = uri.str().substr(first_delim + 1, last_delim - first_delim - 1); } - set_property("lv2:symbol", symbol); + set_property("http://lv2plug.in/ns/lv2core#symbol", symbol); return get_property(key); } @@ -153,7 +153,7 @@ PluginModel::set(SharedPtr p) Symbol PluginModel::default_node_symbol() { - const Atom& name_atom = get_property("lv2:symbol"); + const Atom& name_atom = get_property("http://lv2plug.in/ns/lv2core#symbol"); if (name_atom.is_valid() && name_atom.type() == Atom::STRING) return Symbol::symbolify(name_atom.get_string()); else @@ -164,7 +164,7 @@ PluginModel::default_node_symbol() string PluginModel::human_name() { - const Atom& name_atom = get_property("doap:name"); + const Atom& name_atom = get_property("http://usefulinc.com/ns/doap#name"); if (name_atom.type() == Atom::STRING) return name_atom.get_string(); else diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp index 0df3b060..89adb8da 100644 --- a/src/client/PluginUI.cpp +++ b/src/client/PluginUI.cpp @@ -75,7 +75,7 @@ lv2_ui_write(LV2UI_Controller controller, if (ev->type == map->midi_event.id) { // FIXME: bundle multiple events by writing an entire buffer here ui->world()->engine->set_property(port->path(), map->ingen_value, - Atom("lv2midi:MidiEvent", ev->size, data)); + Atom("http://lv2plug.in/ns/ext/midi#MidiEvent", ev->size, data)); } else { warn << "Unable to send event type " << ev->type << " over OSC, ignoring event" << endl; diff --git a/src/client/PluginUI.hpp b/src/client/PluginUI.hpp index e33f149f..f0baba3c 100644 --- a/src/client/PluginUI.hpp +++ b/src/client/PluginUI.hpp @@ -20,11 +20,10 @@ #include "slv2/slv2.h" #include "raul/SharedPtr.hpp" -#include "module/World.hpp" #include "LV2Features.hpp" namespace Ingen { -namespace Shared { class EngineInterface; } +namespace Shared { class EngineInterface; class World; } namespace Client { class NodeModel; diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp index 5eb578d7..5d4cb417 100644 --- a/src/client/PortModel.cpp +++ b/src/client/PortModel.cpp @@ -15,8 +15,6 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "module/ingen_module.hpp" -#include "module/World.hpp" #include "shared/LV2URIMap.hpp" #include "PortModel.hpp" #include "NodeModel.hpp" @@ -30,7 +28,7 @@ PortModel::set_property(const Raul::URI& uri, const Raul::Atom& value) { Raul::Atom& ret = ObjectModel::set_property(uri, value); - if (uri == ingen_get_world()->uris->ingen_value) + if (uri == Shared::LV2URIMap::instance().ingen_value) this->value(value); return ret; } diff --git a/src/client/PortModel.hpp b/src/client/PortModel.hpp index 5a944532..b199d05b 100644 --- a/src/client/PortModel.hpp +++ b/src/client/PortModel.hpp @@ -50,9 +50,9 @@ public: bool has_hint(const std::string& qname) const; - bool is_logarithmic() const { return has_hint("ingen:logarithmic"); } - bool is_integer() const { return has_hint("lv2:integer"); } - bool is_toggle() const { return has_hint("lv2:toggled"); } + bool is_logarithmic() const { return has_hint("http://drobilla.net/ns/ingen#logarithmic"); } + bool is_integer() const { return has_hint("http://lv2plug.in/ns/lv2core#integer"); } + bool is_toggle() const { return has_hint("http://lv2plug.in/ns/lv2core#toggled"); } inline bool operator==(const PortModel& pm) const { return (path() == pm.path()); } diff --git a/src/client/SigClientInterface.hpp b/src/client/SigClientInterface.hpp index 382813d3..bc2ee3f9 100644 --- a/src/client/SigClientInterface.hpp +++ b/src/client/SigClientInterface.hpp @@ -41,7 +41,7 @@ class SigClientInterface : public Ingen::Shared::ClientInterface, public sigc::t public: SigClientInterface() {} - Raul::URI uri() const { return "ingen:internal"; } + Raul::URI uri() const { return "http://drobilla.net/ns/ingen#internal"; } sigc::signal signal_response_ok; sigc::signal signal_response_error; @@ -60,7 +60,6 @@ public: sigc::signal signal_port_value; sigc::signal signal_voice_value; sigc::signal signal_activity; - sigc::signal signal_binding; /** Fire pending signals. Only does anything on derived classes (that may queue) */ virtual bool emit_signals() { return false; } @@ -112,9 +111,6 @@ protected: void activity(const Raul::Path& port_path) { EMIT(activity, port_path); } - - void binding(const Raul::Path& path, const Shared::MessageType& type) - { EMIT(binding, path, type); } }; diff --git a/src/client/ThreadedSigClientInterface.hpp b/src/client/ThreadedSigClientInterface.hpp index 16eb98c3..128f6d86 100644 --- a/src/client/ThreadedSigClientInterface.hpp +++ b/src/client/ThreadedSigClientInterface.hpp @@ -24,7 +24,6 @@ #include #include "raul/Atom.hpp" #include "interface/ClientInterface.hpp" -#include "interface/MessageType.hpp" #include "SigClientInterface.hpp" #include "raul/SRSWQueue.hpp" @@ -61,11 +60,10 @@ public: , property_change_slot(signal_property_change.make_slot()) , port_value_slot(signal_port_value.make_slot()) , activity_slot(signal_activity.make_slot()) - , binding_slot(signal_binding.make_slot()) { } - virtual Raul::URI uri() const { return "ingen:internal"; } + virtual Raul::URI uri() const { return "http://drobilla.net/ns/ingen#internal"; } void bundle_begin() { push_sig(bundle_begin_slot); } @@ -109,9 +107,6 @@ public: void activity(const Raul::Path& port_path) { push_sig(sigc::bind(activity_slot, port_path)); } - void binding(const Raul::Path& path, const Shared::MessageType& type) - { push_sig(sigc::bind(binding_slot, path, type)); } - /** Process all queued events - Called from GTK thread to emit signals. */ bool emit_signals(); @@ -141,7 +136,6 @@ private: sigc::slot port_value_slot; sigc::slot voice_value_slot; sigc::slot activity_slot; - sigc::slot binding_slot; }; diff --git a/src/common/interface/ClientInterface.hpp b/src/common/interface/ClientInterface.hpp index 676c7eb6..e12788f9 100644 --- a/src/common/interface/ClientInterface.hpp +++ b/src/common/interface/ClientInterface.hpp @@ -28,8 +28,6 @@ namespace Raul { class Path; class URI; } namespace Ingen { namespace Shared { -class MessageType; - /** The (only) interface the engine uses to communicate with clients. * Purely virtual (except for the destructor). * @@ -56,8 +54,6 @@ public: virtual void error(const std::string& msg) = 0; virtual void activity(const Raul::Path& path) = 0; - - virtual void binding(const Raul::Path& path, const MessageType& type) = 0; }; diff --git a/src/common/interface/EventType.hpp b/src/common/interface/EventType.hpp index 3f3def1d..1e9a1b16 100644 --- a/src/common/interface/EventType.hpp +++ b/src/common/interface/EventType.hpp @@ -18,6 +18,8 @@ #ifndef INGEN_INTERFACE_EVENTTYPE_HPP #define INGEN_INTERFACE_EVENTTYPE_HPP +#include "raul/URI.hpp" + namespace Ingen { namespace Shared { @@ -33,7 +35,7 @@ public: OSC = 2 }; - EventType(const std::string& uri) + EventType(const Raul::URI& uri) : _symbol(UNKNOWN) { if (uri == type_uri(MIDI)) { @@ -47,7 +49,7 @@ public: : _symbol(symbol) {} - inline const char* uri() const { return type_uri(_symbol); } + inline const Raul::URI& uri() const { return type_uri(_symbol); } inline bool operator==(const Symbol& symbol) const { return (_symbol == symbol); } inline bool operator!=(const Symbol& symbol) const { return (_symbol != symbol); } @@ -58,13 +60,14 @@ public: inline bool is_osc() { return _symbol == OSC; } private: - - static inline const char* type_uri(unsigned symbol_num) { - switch (symbol_num) { - case 1: return "ingen:MidiEvent"; - case 2: return "ingen:OSCEvent"; - default: return ""; - } + static inline const Raul::URI& type_uri(unsigned symbol_num) { + assert(symbol_num <= OSC); + static const Raul::URI uris[] = { + "http://drobilla.net/ns/ingen#nil", + "http://drobilla.net/ns/ingen#MidiEvent", + "http://drobilla.net/ns/ingen#OSCEvent" + }; + return uris[symbol_num]; } Symbol _symbol; diff --git a/src/common/interface/MessageType.hpp b/src/common/interface/MessageType.hpp deleted file mode 100644 index 3f18aaac..00000000 --- a/src/common/interface/MessageType.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) 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 General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_INTERFACE_MESSAGETYPE_HPP -#define INGEN_INTERFACE_MESSAGETYPE_HPP - -#include -#include -#include - -namespace Ingen { -namespace Shared { - - -/** A type of control message that could be bound to a control port. - * - * \ingroup interface - */ -class MessageType -{ -public: - enum Type { - MIDI_PITCH, - MIDI_CC, - MIDI_RPN, - MIDI_NRPN - }; - - MessageType(Type type, int16_t num) - : _type(type) - { - switch (type) { - case MIDI_PITCH: - break; - case MIDI_CC: - assert(num >= 0 && num < 128); - _id.midi_cc = num; - break; - case MIDI_RPN: - assert(num >= 0 && num < 16384); - _id.midi_pn = num; - break; - case MIDI_NRPN: - assert(num >= 0 && num < 16384); - _id.midi_pn = num; - break; - } - } - - inline Type type() const { return _type; } - inline int8_t midi_cc_num() const { assert(_type == MIDI_CC); return _id.midi_cc; } - inline int8_t midi_rpn_num() const { assert(_type == MIDI_RPN); return _id.midi_pn; } - inline int8_t midi_nrpn_num() const { assert(_type == MIDI_NRPN); return _id.midi_pn; } - - inline int num() const { - switch (_type) { - case MIDI_CC: - return _id.midi_cc; - case MIDI_RPN: - case MIDI_NRPN: - return _id.midi_pn; - default: - return -1; - } - } - - inline const char* type_uri() const { - switch (_type) { - case MIDI_PITCH: - return "midi:PitchBend"; - case MIDI_CC: - return "midi:Control"; - case MIDI_RPN: - return "midi:RPN"; - case MIDI_NRPN: - return "midi:NRPN"; - } - } - -private: - union { - int8_t midi_cc; ///< Controller number [0..2^7) - int16_t midi_pn; ///< RPN or NRPN number [0..2^14) - } _id; - - Type _type; -}; - - -} // namespace Shared -} // namespace Ingen - - -static inline std::ostream& operator<<(std::ostream& os, const Ingen::Shared::MessageType& type) -{ - using namespace Ingen::Shared; - switch (type.type()) { - case MessageType::MIDI_PITCH: return os << "MIDI Pitch Bender"; - case MessageType::MIDI_CC: return os << "MIDI CC " << type.num(); - case MessageType::MIDI_RPN: return os << "MIDI RPN " << type.num(); - case MessageType::MIDI_NRPN: return os << "MIDI NRPN " << type.num(); - } - return os; -} - -#endif // INGEN_INTERFACE_MESSAGETYPE_HPP diff --git a/src/common/interface/Plugin.hpp b/src/common/interface/Plugin.hpp index d3d74970..22464e91 100644 --- a/src/common/interface/Plugin.hpp +++ b/src/common/interface/Plugin.hpp @@ -19,6 +19,7 @@ #define INGEN_INTERFACE_PLUGIN_HPP #include +#include "raul/URI.hpp" #include "interface/Resource.hpp" namespace Ingen { @@ -32,26 +33,31 @@ public: virtual Type type() const = 0; - inline const char* type_uri() const { - switch (type()) { - case LV2: return "lv2:Plugin"; - case LADSPA: return "ingen:LADSPAPlugin"; - case Internal: return "ingen:Internal"; - case Patch: return "ingen:Patch"; - default: return ""; - } + static inline const Raul::URI& type_uri(Type type) { + static const Raul::URI uris[] = { + "http://drobilla.net/ns/ingen#nil", + "http://lv2plug.in/ns/lv2core#Plugin", + "http://drobilla.net/ns/ingen#LADSPAPlugin", + "http://drobilla.net/ns/ingen#Internal", + "http://drobilla.net/ns/ingen#Patch" + }; + + return uris[type]; } - static inline Type type_from_uri(const std::string& uri) { - if (uri == "lv2:Plugin") + inline const Raul::URI& type_uri() const { return type_uri(type()); } + + static inline Type type_from_uri(const Raul::URI& uri) { + if (uri == type_uri(LV2)) return LV2; - else if (uri == "ingen:LADSPAPlugin") + else if (uri == type_uri(LADSPA)) return LADSPA; - else if (uri == "ingen:Internal") + else if (uri == type_uri(Internal)) return Internal; - else if (uri == "ingen:Patch") + else if (uri == type_uri(Patch)) return Patch; - return NIL; + else + return NIL; } }; diff --git a/src/common/interface/PortType.hpp b/src/common/interface/PortType.hpp index ca739cb8..e1d51e21 100644 --- a/src/common/interface/PortType.hpp +++ b/src/common/interface/PortType.hpp @@ -37,22 +37,22 @@ public: AUDIO = 1, CONTROL = 2, EVENTS = 3, - VALUE = 7, - MESSAGE = 8, + VALUE = 4, + MESSAGE = 5, }; PortType(const Raul::URI& uri) : _symbol(UNKNOWN) { - if (uri.str() == type_uri(AUDIO)) { + if (uri == type_uri(AUDIO)) { _symbol = AUDIO; - } else if (uri.str() == type_uri(CONTROL)) { + } else if (uri == type_uri(CONTROL)) { _symbol = CONTROL; - } else if (uri.str() == type_uri(EVENTS)) { + } else if (uri == type_uri(EVENTS)) { _symbol = EVENTS; - } else if (uri.str() == type_uri(VALUE)) { + } else if (uri == type_uri(VALUE)) { _symbol = VALUE; - } else if (uri.str() == type_uri(MESSAGE)) { + } else if (uri == type_uri(MESSAGE)) { _symbol = MESSAGE; } } @@ -61,8 +61,8 @@ public: : _symbol(symbol) {} - inline const char* uri() const { return type_uri(_symbol); } - inline Symbol symbol() const { return _symbol; } + inline const Raul::URI& uri() const { return type_uri(_symbol); } + inline Symbol symbol() const { return _symbol; } inline bool operator==(const Symbol& symbol) const { return (_symbol == symbol); } inline bool operator!=(const Symbol& symbol) const { return (_symbol != symbol); } @@ -76,16 +76,17 @@ public: inline bool is_message() { return _symbol == MESSAGE; } private: - - static inline const char* type_uri(unsigned symbol_num) { - switch (symbol_num) { - case 1: return "lv2:AudioPort"; - case 2: return "lv2:ControlPort"; - case 3: return "lv2ev:EventPort"; - case 7: return "obj:ValuePort"; - case 8: return "obj:MessagePort"; - default: return ""; - } + static inline const Raul::URI& type_uri(unsigned symbol_num) { + assert(symbol_num <= MESSAGE); + static const Raul::URI uris[] = { + "http://drobilla.net/ns/ingen#nil", + "http://lv2plug.in/ns/lv2core#AudioPort", + "http://lv2plug.in/ns/lv2core#ControlPort", + "http://lv2plug.in/ns/ext/event#EventPort", + "http://lv2plug.in/ns/dev/objects#ValuePort", + "http://lv2plug.in/ns/dev/objects#MessagePort" + }; + return uris[symbol_num]; } Symbol _symbol; diff --git a/src/engine/ClientBroadcaster.hpp b/src/engine/ClientBroadcaster.hpp index 808c861a..37593730 100644 --- a/src/engine/ClientBroadcaster.hpp +++ b/src/engine/ClientBroadcaster.hpp @@ -108,7 +108,7 @@ public: // ClientInterface - Raul::URI uri() const { return "ingen:broadcaster"; } ///< N/A + Raul::URI uri() const { return "http://drobilla.net/ns/ingen#broadcaster"; } ///< N/A void response_ok(int32_t id) {} ///< N/A void response_error(int32_t id, const std::string& msg) {} ///< N/A @@ -118,10 +118,6 @@ public: void error(const std::string& msg) { BROADCAST(error, msg); } void activity(const Raul::Path& path) { BROADCAST(activity, path); } - void binding(const Raul::Path& path, const Shared::MessageType& type) { - BROADCAST(binding, path, type); - } - private: typedef std::map Clients; Clients _clients; diff --git a/src/engine/ControlBindings.cpp b/src/engine/ControlBindings.cpp index 43e30338..2144aba7 100644 --- a/src/engine/ControlBindings.cpp +++ b/src/engine/ControlBindings.cpp @@ -20,6 +20,7 @@ #include "events/SendPortValue.hpp" #include "events/SendBinding.hpp" #include "ControlBindings.hpp" +#include "Engine.hpp" #include "EventBuffer.hpp" #include "PortImpl.hpp" #include "ProcessContext.hpp" @@ -33,6 +34,29 @@ using namespace Raul; namespace Ingen { +void +ControlBindings::update_port(ProcessContext& context, PortImpl* port) +{ + const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance(); + const Raul::Atom& binding = port->get_property(uris.ingen_controlBinding); + if (binding.type() == Atom::DICT) { + Atom::DictValue::const_iterator t = binding.get_dict().find(uris.rdf_type); + Atom::DictValue::const_iterator n = binding.get_dict().find(uris.midi_controllerNumber); + if (t != binding.get_dict().end() && n != binding.get_dict().end()) { + if (t->second == uris.midi_Controller) { + _bindings->insert(make_pair(Key(MIDI_CC, n->second.get_int32()), port)); + } else if (t->second == uris.midi_Bender) { + _bindings->insert(make_pair(Key(MIDI_BENDER), port)); + } else if (t->second == uris.midi_ChannelPressure) { + _bindings->insert(make_pair(Key(MIDI_CHANNEL_PRESSURE), port)); + } else { + error << "Unknown binding type " << t->second << endl; + } + } + } +} + + void ControlBindings::learn(PortImpl* port) { @@ -42,28 +66,40 @@ ControlBindings::learn(PortImpl* port) void -ControlBindings::set_port_value(ProcessContext& context, PortImpl* port, int8_t cc_value) +ControlBindings::set_port_value(ProcessContext& context, PortImpl* port, Type type, int16_t value) { // TODO: cache these to avoid the lookup - float min = port->get_property("lv2:minimum").get_float(); - float max = port->get_property("lv2:maximum").get_float(); + float min = port->get_property(Shared::LV2URIMap::instance().lv2_minimum).get_float(); + float max = port->get_property(Shared::LV2URIMap::instance().lv2_maximum).get_float(); + + float normal; + switch (type) { + case MIDI_CC: + case MIDI_CHANNEL_PRESSURE: + normal = (float)value / 127.0; + break; + case MIDI_BENDER: + normal = (float)value / 16383.0; + default: + break; + } - Raul::Atom value(static_cast(((float)cc_value / 127.0) * (max - min) + min)); - port->set_value(value); + Raul::Atom atom(static_cast(normal * (max - min) + min)); + port->set_value(atom); const Events::SendPortValue ev(context.engine(), context.start(), port, true, 0, - value.get_float()); + atom.get_float()); context.event_sink().write(sizeof(ev), &ev); } void -ControlBindings::bind(ProcessContext& context, int8_t cc_num) +ControlBindings::bind(ProcessContext& context, Type type, int16_t num) { - _bindings->insert(make_pair(cc_num, _learn_port)); + assert(_learn_port); + _bindings->insert(make_pair(Key(type, num), _learn_port)); - const Events::SendBinding ev(context.engine(), context.start(), _learn_port, - MessageType(MessageType::MIDI_CC, cc_num)); + const Events::SendBinding ev(context.engine(), context.start(), _learn_port, type, num); context.event_sink().write(sizeof(ev), &ev); _learn_port = NULL; @@ -106,12 +142,26 @@ ControlBindings::process(ProcessContext& context, EventBuffer* buffer) if (_learn_port) { buffer->rewind(); + int16_t num; while (buffer->get_event(&frames, &subframes, &type, &size, &buf)) { - if (type == _map->midi_event.id && (buf[0] & 0xF0) == MIDI_CMD_CONTROL) { - const int8_t controller = static_cast(buf[1]); - bind(context, controller); - break; + if (type == _map->midi_event.id) { + switch (buf[0] & 0xF0) { + case MIDI_CMD_CONTROL: + num = static_cast(buf[1]); + bind(context, MIDI_CC, num); + break; + case MIDI_CMD_BENDER: + bind(context, MIDI_BENDER); + break; + case MIDI_CMD_CHANNEL_PRESSURE: + bind(context, MIDI_CHANNEL_PRESSURE); + break; + default: + break; + } } + if (!_learn_port) + break; buffer->increment(); } } @@ -119,12 +169,28 @@ ControlBindings::process(ProcessContext& context, EventBuffer* buffer) if (!bindings->empty()) { buffer->rewind(); while (buffer->get_event(&frames, &subframes, &type, &size, &buf)) { - if (type == _map->midi_event.id && (buf[0] & 0xF0) == MIDI_CMD_CONTROL) { - const int8_t controller = static_cast(buf[1]); - const int8_t value = static_cast(buf[2]); - Bindings::const_iterator i = bindings->find(controller); - if (i != bindings->end()) { - set_port_value(context, i->second, value); + if (type == _map->midi_event.id) { + if ((buf[0] & 0xF0) == MIDI_CMD_CONTROL) { + const int8_t controller = static_cast(buf[1]); + Bindings::const_iterator i = bindings->find(Key(MIDI_CC, controller)); + if (i != bindings->end()) { + const int8_t value = static_cast(buf[2]); + set_port_value(context, i->second, MIDI_CC, value); + } + } else if ((buf[0] & 0xF0) == MIDI_CMD_BENDER) { + Bindings::const_iterator i = bindings->find(Key(MIDI_BENDER)); + if (i != bindings->end()) { + const int8_t lsb = static_cast(buf[1]); + const int8_t msb = static_cast(buf[2]); + const int16_t value = (msb << 7) + lsb; + set_port_value(context, i->second, MIDI_BENDER, value); + } + } else if ((buf[0] & 0xF0) == MIDI_CMD_CHANNEL_PRESSURE) { + Bindings::const_iterator i = bindings->find(Key(MIDI_CHANNEL_PRESSURE)); + if (i != bindings->end()) { + const int8_t value = static_cast(buf[1]); + set_port_value(context, i->second, MIDI_CHANNEL_PRESSURE, value); + } } } buffer->increment(); diff --git a/src/engine/ControlBindings.hpp b/src/engine/ControlBindings.hpp index e9ab290f..bae3cc73 100644 --- a/src/engine/ControlBindings.hpp +++ b/src/engine/ControlBindings.hpp @@ -33,7 +33,24 @@ class PortImpl; class ControlBindings { public: - typedef std::map Bindings; + enum Type { + MIDI_BENDER, + MIDI_CC, + MIDI_RPN, + MIDI_NRPN, + MIDI_CHANNEL_PRESSURE + }; + + struct Key { + Key(Type t, int16_t n=0) : type(t), num(n) {} + inline bool operator<(const Key& other) const { + return (type == other.type) ? (num < other.num) : (type < other.type); + } + Type type; + int16_t num; + }; + + typedef std::map Bindings; ControlBindings(Engine& engine, SharedPtr map) : _engine(engine) @@ -43,6 +60,7 @@ public: {} void learn(PortImpl* port); + void update_port(ProcessContext& context, PortImpl* port); void process(ProcessContext& context, EventBuffer* buffer); /** Remove all bindings for @a path or children of @a path. @@ -56,8 +74,8 @@ private: SharedPtr _map; PortImpl* _learn_port; - void set_port_value(ProcessContext& context, PortImpl* port, int8_t cc_value); - void bind(ProcessContext& context, int8_t cc_num); + void set_port_value(ProcessContext& context, PortImpl* port, Type type, int16_t value); + void bind(ProcessContext& context, Type type, int16_t num=0); SharedPtr _bindings; }; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 26febf3b..e57c144f 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -170,9 +170,9 @@ Engine::activate() if (!root_patch) { root_patch = new PatchImpl(*this, "root", 1, NULL, _driver->sample_rate(), _driver->buffer_size(), 1); - root_patch->meta().set_property(uris.rdf_type, Raul::Atom(Raul::Atom::URI, "ingen:Patch")); + root_patch->meta().set_property(uris.rdf_type, uris.ingen_Patch); root_patch->meta().set_property(uris.ingen_polyphony, Raul::Atom(int32_t(1))); - root_patch->set_property(uris.rdf_type, Raul::Atom(Raul::Atom::URI, "ingen:Node")); + root_patch->set_property(uris.rdf_type, uris.ingen_Node); root_patch->activate(); _world->store->add(root_patch); root_patch->compiled_patch(root_patch->compile()); @@ -181,8 +181,10 @@ Engine::activate() // Add control port Shared::Resource::Properties properties; properties.insert(make_pair(uris.lv2_name, "Control")); + properties.insert(make_pair(uris.rdf_type, uris.lv2ev_EventPort)); + properties.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); Events::CreatePort* ev = new Events::CreatePort(*this, SharedPtr(), 0, - "/ingen_control", "lv2ev:EventPort", false, NULL, properties); + "/ingen_control", uris.lv2ev_EventPort, false, NULL, properties); ev->pre_process(); ProcessContext context(*this); ev->execute(context); diff --git a/src/engine/Engine.hpp b/src/engine/Engine.hpp index e7892f84..e575db50 100644 --- a/src/engine/Engine.hpp +++ b/src/engine/Engine.hpp @@ -23,7 +23,6 @@ #include #include #include "raul/SharedPtr.hpp" -#include "module/World.hpp" #include "interface/PortType.hpp" #include "interface/EventType.hpp" @@ -33,6 +32,8 @@ namespace Raul { class Maid; } namespace Ingen { +namespace Shared { class World; } + class BufferFactory; class ClientBroadcaster; class ControlBindings; diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp index 77f4fbad..dcea6288 100644 --- a/src/engine/HTTPClientSender.cpp +++ b/src/engine/HTTPClientSender.cpp @@ -64,7 +64,7 @@ HTTPClientSender::put(const URI& uri, model.add_statement( Redland::Resource(*_engine.world()->rdf_world, path), i->first.str(), - AtomRDF::atom_to_node(*_engine.world()->rdf_world, i->second)); + AtomRDF::atom_to_node(model, i->second)); const string str = model.serialise_to_string(); send_chunk(str); @@ -102,6 +102,7 @@ HTTPClientSender::disconnect(const Path& src_path, const Path& dst_path) void HTTPClientSender::set_property(const URI& subject, const URI& key, const Atom& value) { +#if 0 Redland::Node node = AtomRDF::atom_to_node(*_engine.world()->rdf_world, value); const string msg = string( "@prefix rdf: .\n" @@ -111,6 +112,7 @@ HTTPClientSender::set_property(const URI& subject, const URI& key, const Atom& v "rdf:predicate ").append(key.str()).append(" ;\n" "rdf:value ").append(node.to_string()).append("\n] .\n"); send_chunk(msg); +#endif } @@ -131,13 +133,6 @@ HTTPClientSender::activity(const Path& path) } -void -HTTPClientSender::binding(const Path& path, const MessageType& type) -{ - warn << "TODO: HTTP binding" << endl; -} - - void HTTPClientSender::move(const Path& old_path, const Path& new_path) { diff --git a/src/engine/HTTPClientSender.hpp b/src/engine/HTTPClientSender.hpp index 4c975304..cbfd17f0 100644 --- a/src/engine/HTTPClientSender.hpp +++ b/src/engine/HTTPClientSender.hpp @@ -90,8 +90,6 @@ public: virtual void activity(const Raul::Path& path); - virtual void binding(const Raul::Path& path, const Shared::MessageType& type); - private: Engine& _engine; std::string _url; diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index cc72a7c5..e1859b79 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -19,6 +19,7 @@ #include #include #include "interface/Patch.hpp" +#include "shared/LV2URIMap.hpp" #include "AudioBuffer.hpp" #include "BufferFactory.hpp" #include "ConnectionImpl.hpp" @@ -47,13 +48,15 @@ InputPort::InputPort(BufferFactory& bufs, size_t buffer_size) : PortImpl(bufs, parent, name, index, poly, type, value, buffer_size) { + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + if (!dynamic_cast(parent)) - add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "lv2:InputPort")); + add_property(uris.rdf_type, uris.lv2_InputPort); // Set default control range if (type == PortType::CONTROL) { - set_property("lv2:minimum", 0.0f); - set_property("lv2:maximum", 1.0f); + set_property(uris.lv2_minimum, 0.0f); + set_property(uris.lv2_maximum, 1.0f); } } diff --git a/src/engine/InternalPlugin.cpp b/src/engine/InternalPlugin.cpp index 946ed956..b312a24b 100644 --- a/src/engine/InternalPlugin.cpp +++ b/src/engine/InternalPlugin.cpp @@ -16,7 +16,6 @@ */ #include -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "internals/Note.hpp" #include "internals/Trigger.hpp" @@ -36,7 +35,7 @@ InternalPlugin::InternalPlugin(const std::string& uri, const std::string& symbol : PluginImpl(Plugin::Internal, uri) , _symbol(symbol) { - const LV2URIMap& uris = *ingen_get_world()->uris.get(); + const LV2URIMap& uris = Shared::LV2URIMap::instance(); set_property(uris.rdf_type, uris.ingen_Internal); } diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp index 24291fa9..feb8d802 100644 --- a/src/engine/JackDriver.cpp +++ b/src/engine/JackDriver.cpp @@ -19,6 +19,7 @@ #include #include "raul/log.hpp" #include "raul/List.hpp" +#include "module/World.hpp" #include "shared/LV2Features.hpp" #include "shared/LV2URIMap.hpp" #include "AudioBuffer.hpp" diff --git a/src/engine/LADSPANode.cpp b/src/engine/LADSPANode.cpp index d3db5a04..ecfb9d32 100644 --- a/src/engine/LADSPANode.cpp +++ b/src/engine/LADSPANode.cpp @@ -20,6 +20,7 @@ #include #include #include +#include "shared/LV2URIMap.hpp" #include "raul/log.hpp" #include "raul/Maid.hpp" #include "LADSPANode.hpp" @@ -144,6 +145,7 @@ nameify_if_invalid(const string& name) bool LADSPANode::instantiate(BufferFactory& bufs) { + const LV2URIMap& uris = Shared::LV2URIMap::instance(); if (!_ports) _ports = new Raul::Array(_descriptor->PortCount); @@ -241,11 +243,11 @@ LADSPANode::instantiate(BufferFactory& bufs) if (port->is_input() && port->buffer_size() == 1) { if (min) - port->set_meta_property("lv2:minimum", min.get()); + port->set_meta_property(uris.lv2_minimum, min.get()); if (max) - port->set_meta_property("lv2:maximum", max.get()); + port->set_meta_property(uris.lv2_maximum, max.get()); if (default_val) - port->set_meta_property("lv2:default", default_val.get()); + port->set_meta_property(uris.lv2_default, default_val.get()); } } diff --git a/src/engine/LADSPAPlugin.cpp b/src/engine/LADSPAPlugin.cpp index e1fdff40..9d8c3b63 100644 --- a/src/engine/LADSPAPlugin.cpp +++ b/src/engine/LADSPAPlugin.cpp @@ -18,7 +18,6 @@ #include #include #include -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "LADSPAPlugin.hpp" #include "LADSPANode.hpp" @@ -42,7 +41,7 @@ LADSPAPlugin::LADSPAPlugin( , _label(label) , _name(name) { - const LV2URIMap& uris = *ingen_get_world()->uris; + const LV2URIMap& uris = Shared::LV2URIMap::instance(); set_property(uris.rdf_type, uris.ingen_LADSPAPlugin); set_property(uris.lv2_symbol, Symbol::symbolify(label)); set_property(uris.doap_name, name); @@ -52,7 +51,7 @@ LADSPAPlugin::LADSPAPlugin( const Raul::Atom& LADSPAPlugin::get_property(const Raul::URI& uri) const { - if (uri == ingen_get_world()->uris->doap_name) + if (uri == Shared::LV2URIMap::instance().doap_name) return _name; else return ResourceImpl::get_property(uri); diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp index 574a4eeb..a0c7dd07 100644 --- a/src/engine/LV2Node.cpp +++ b/src/engine/LV2Node.cpp @@ -142,6 +142,7 @@ LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly) bool LV2Node::instantiate(BufferFactory& bufs) { + const LV2URIMap& uris = Shared::LV2URIMap::instance(); SharedPtr info = _lv2_plugin->lv2_info(); SLV2Plugin plug = _lv2_plugin->slv2_plugin(); @@ -281,12 +282,12 @@ LV2Node::instantiate(BufferFactory& bufs) if (direction == INPUT && data_type == PortType::CONTROL) { ((AudioBuffer*)port->buffer(0).get())->set_value(val.get_float(), 0, 0); if (!isnan(min_values[j])) { - port->meta().set_property("lv2:minimum", min_values[j]); - port->set_property("lv2:minimum", min_values[j]); + port->meta().set_property(uris.lv2_minimum, min_values[j]); + port->set_property(uris.lv2_minimum, min_values[j]); } if (!isnan(max_values[j])) { - port->meta().set_property("lv2:maximum", max_values[j]); - port->set_property("lv2:maximum", max_values[j]); + port->meta().set_property(uris.lv2_maximum, max_values[j]); + port->set_property(uris.lv2_maximum, max_values[j]); } } diff --git a/src/engine/LV2Plugin.cpp b/src/engine/LV2Plugin.cpp index 5a0502d4..95cb93f0 100644 --- a/src/engine/LV2Plugin.cpp +++ b/src/engine/LV2Plugin.cpp @@ -18,7 +18,6 @@ #include #include #include "redlandmm/World.hpp" -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "LV2Plugin.hpp" #include "LV2Node.hpp" @@ -37,7 +36,7 @@ LV2Plugin::LV2Plugin(SharedPtr lv2_info, const std::string& uri) , _slv2_plugin(NULL) , _lv2_info(lv2_info) { - const LV2URIMap& uris = *ingen_get_world()->uris.get(); + const LV2URIMap& uris = Shared::LV2URIMap::instance(); set_property(uris.rdf_type, uris.lv2_Plugin); } diff --git a/src/engine/NodeImpl.hpp b/src/engine/NodeImpl.hpp index d6923ff3..ef7c3400 100644 --- a/src/engine/NodeImpl.hpp +++ b/src/engine/NodeImpl.hpp @@ -31,7 +31,6 @@ namespace Shared { class Plugin; class Node; class Port; } class Buffer; class BufferFactory; -class Engine; class MessageContext; class PatchImpl; class PluginImpl; diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp index 6938b09a..115b22de 100644 --- a/src/engine/OSCClientSender.cpp +++ b/src/engine/OSCClientSender.cpp @@ -20,7 +20,6 @@ #include "raul/log.hpp" #include "raul/AtomLiblo.hpp" #include "interface/ClientInterface.hpp" -#include "interface/MessageType.hpp" #include "EngineStore.hpp" #include "NodeImpl.hpp" #include "OSCClientSender.hpp" @@ -230,23 +229,4 @@ OSCClientSender::activity(const Path& path) } -/** \page client_osc_namespace - *

/ingen/binding

- * \arg \b path (string) - Path of object - * \arg \b type (string) - Type of message (URI) - * \arg \b id (int) - Controller number (if applicable) - * - * Notification of "activity" (e.g. port message blinkenlights). - */ -void -OSCClientSender::binding(const Path& path, const MessageType& type) -{ - if (!_enabled) - return; - - lo_send(_address, "/ingen/binding", "ssi", - path.c_str(), type.type_uri(), type.num(), LO_ARGS_END); -} - - } // namespace Ingen diff --git a/src/engine/OSCClientSender.hpp b/src/engine/OSCClientSender.hpp index d7abfed0..2ca4aad3 100644 --- a/src/engine/OSCClientSender.hpp +++ b/src/engine/OSCClientSender.hpp @@ -90,8 +90,6 @@ public: virtual void activity(const Raul::Path& path); - virtual void binding(const Raul::Path& path, const Shared::MessageType& type); - private: Raul::URI _url; }; diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index 404796fd..2ddfaa59 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -587,7 +587,7 @@ OSCEngineReceiver::_learn_cb(const char* path, const char* types, lo_arg** argv, *

/ingen/set_property

* \arg \b response-id (integer) * \arg \b object-path (string) - Full path of object to associate property with - * \arg \b key (string) - URI/QName for predicate of this property (e.g. "ingen:enabled") + * \arg \b key (string) - URI for predicate of this property (e.g. "http://drobilla.net/ns/ingen#enabled") * \arg \b value (string) - Value of property * * Set a property on a graph object. diff --git a/src/engine/ObjectSender.cpp b/src/engine/ObjectSender.cpp index f4cd6664..2eadf1e9 100644 --- a/src/engine/ObjectSender.cpp +++ b/src/engine/ObjectSender.cpp @@ -17,7 +17,6 @@ #include "ObjectSender.hpp" #include "interface/ClientInterface.hpp" -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "EngineStore.hpp" #include "PatchImpl.hpp" @@ -137,7 +136,7 @@ ObjectSender::send_port(ClientInterface* client, const PortImpl* port, bool bund if (graph_parent) client->put(port->meta_uri(), port->meta().properties()); - const Shared::LV2URIMap& map = *ingen_get_world()->uris.get(); + const Shared::LV2URIMap& map = Shared::LV2URIMap::instance(); client->put(port->path(), port->properties()); diff --git a/src/engine/OutputPort.cpp b/src/engine/OutputPort.cpp index 56e4bfdd..e0b8dc23 100644 --- a/src/engine/OutputPort.cpp +++ b/src/engine/OutputPort.cpp @@ -16,6 +16,7 @@ */ #include "interface/Patch.hpp" +#include "shared/LV2URIMap.hpp" #include "Buffer.hpp" #include "NodeImpl.hpp" #include "OutputPort.hpp" @@ -38,8 +39,10 @@ OutputPort::OutputPort(BufferFactory& bufs, size_t buffer_size) : PortImpl(bufs, parent, name, index, poly, type, value, buffer_size) { + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + if (!dynamic_cast(parent)) - add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "lv2:OutputPort")); + add_property(uris.rdf_type, uris.lv2_OutputPort); if (type == PortType::CONTROL) _broadcast = true; diff --git a/src/engine/PortImpl.cpp b/src/engine/PortImpl.cpp index e2c25dc7..e9dd4f7f 100644 --- a/src/engine/PortImpl.cpp +++ b/src/engine/PortImpl.cpp @@ -17,7 +17,6 @@ #include "raul/Array.hpp" #include "raul/Maid.hpp" -#include "module/ingen_module.hpp" #include "shared/LV2URIMap.hpp" #include "contexts.lv2/contexts.h" #include "interface/PortType.hpp" @@ -77,8 +76,8 @@ PortImpl::PortImpl(BufferFactory& bufs, else _polyphonic = true; - add_property("rdf:type", Atom(Atom::URI, type.uri())); - set_property("lv2:index", Atom((int32_t)index)); + add_property("http://www.w3.org/1999/02/22-rdf-syntax-ns#type", type.uri()); + set_property("http://lv2plug.in/ns/lv2core#index", Atom((int32_t)index)); set_context(_context); if (type == PortType::EVENTS) @@ -209,7 +208,7 @@ PortImpl::broadcast_value(Context& context, bool force) void PortImpl::set_context(Context::ID c) { - const LV2URIMap& uris = *ingen_get_world()->uris.get(); + const LV2URIMap& uris = Shared::LV2URIMap::instance(); _context = c; switch (c) { case Context::AUDIO: diff --git a/src/engine/QueuedEngineInterface.hpp b/src/engine/QueuedEngineInterface.hpp index c1db2ba1..23ab608b 100644 --- a/src/engine/QueuedEngineInterface.hpp +++ b/src/engine/QueuedEngineInterface.hpp @@ -51,7 +51,7 @@ public: QueuedEngineInterface(Engine& engine, size_t queue_size); virtual ~QueuedEngineInterface() {} - Raul::URI uri() const { return "ingen:internal"; } + Raul::URI uri() const { return "http://drobilla.net/ns/ingen#internal"; } void set_next_response_id(int32_t id); diff --git a/src/engine/events/AllNotesOff.cpp b/src/engine/events/AllNotesOff.cpp index 2ddec32b..8ce27c87 100644 --- a/src/engine/events/AllNotesOff.cpp +++ b/src/engine/events/AllNotesOff.cpp @@ -19,7 +19,6 @@ #include "Responder.hpp" #include "Engine.hpp" #include "EngineStore.hpp" -#include "module/World.hpp" #include "shared/Store.hpp" using namespace Raul; diff --git a/src/engine/events/CreateNode.cpp b/src/engine/events/CreateNode.cpp index 7dabd65d..4d3af4db 100644 --- a/src/engine/events/CreateNode.cpp +++ b/src/engine/events/CreateNode.cpp @@ -19,7 +19,6 @@ #include "raul/Path.hpp" #include "raul/Path.hpp" #include "redlandmm/World.hpp" -#include "module/World.hpp" #include "CreateNode.hpp" #include "Responder.hpp" #include "PatchImpl.hpp" diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp index 44ffe90d..151181f4 100644 --- a/src/engine/events/CreatePort.cpp +++ b/src/engine/events/CreatePort.cpp @@ -20,18 +20,20 @@ #include "raul/List.hpp" #include "raul/Maid.hpp" #include "raul/Path.hpp" -#include "Responder.hpp" +#include "shared/LV2URIMap.hpp" +#include "ClientBroadcaster.hpp" +#include "ControlBindings.hpp" #include "CreatePort.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" +#include "Driver.hpp" +#include "DuplexPort.hpp" #include "Engine.hpp" -#include "PatchImpl.hpp" -#include "EventSource.hpp" #include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" +#include "EventSource.hpp" +#include "PatchImpl.hpp" +#include "PatchImpl.hpp" +#include "PluginImpl.hpp" #include "PortImpl.hpp" -#include "Driver.hpp" -#include "DuplexPort.hpp" +#include "Responder.hpp" using namespace std; using namespace Raul; @@ -85,6 +87,8 @@ CreatePort::pre_process() _patch = _engine.engine_store()->find_patch(_path.parent()); + const LV2URIMap& uris = *_engine.world()->uris.get(); + if (_patch != NULL) { assert(_patch->path() == _path.parent()); @@ -94,7 +98,7 @@ CreatePort::pre_process() _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(), _data_type, buffer_size, _is_output); if (_patch->parent()) - _patch_port->set_property("rdf:instanceOf", _patch_port->meta_uri()); + _patch_port->set_property(uris.rdf_instanceOf, _patch_port->meta_uri()); _patch_port->meta().properties().insert(_properties.begin(), _properties.end()); @@ -135,6 +139,7 @@ CreatePort::execute(ProcessContext& context) if (_patch_port) { _engine.maid()->push(_patch->external_ports()); _patch->external_ports(_ports_array); + _engine.control_bindings()->update_port(context, _patch_port); } if (_driver_port) { diff --git a/src/engine/events/SendBinding.cpp b/src/engine/events/SendBinding.cpp index 7168b142..8cc03c79 100644 --- a/src/engine/events/SendBinding.cpp +++ b/src/engine/events/SendBinding.cpp @@ -17,6 +17,7 @@ #include #include "events/SendBinding.hpp" +#include "shared/LV2URIMap.hpp" #include "Engine.hpp" #include "PortImpl.hpp" #include "ClientBroadcaster.hpp" @@ -30,7 +31,19 @@ namespace Events { void SendBinding::post_process() { - _engine.broadcaster()->binding(_port->path(), _type); + const LV2URIMap& uris = *_engine.world()->uris.get(); + Raul::Atom::DictValue dict; + if (_type == ControlBindings::MIDI_CC) { + dict[uris.rdf_type] = uris.midi_Controller; + dict[uris.midi_controllerNumber] = _num; + } else if (_type == ControlBindings::MIDI_BENDER) { + dict[uris.rdf_type] = uris.midi_Bender; + } else if (_type == ControlBindings::MIDI_CHANNEL_PRESSURE) { + dict[uris.rdf_type] = uris.midi_ChannelPressure; + } + // TODO: other event types + _port->set_property(uris.ingen_controlBinding, dict); // FIXME: thread unsafe + _engine.broadcaster()->set_property(_port->path(), uris.ingen_controlBinding, dict); } diff --git a/src/engine/events/SendBinding.hpp b/src/engine/events/SendBinding.hpp index 7cce3767..7f69f777 100644 --- a/src/engine/events/SendBinding.hpp +++ b/src/engine/events/SendBinding.hpp @@ -19,8 +19,8 @@ #define INGEN_EVENTS_SENDBINDING_HPP #include "raul/Atom.hpp" -#include "interface/MessageType.hpp" #include "engine/Event.hpp" +#include "engine/ControlBindings.hpp" #include "engine/types.hpp" namespace Ingen { @@ -43,22 +43,40 @@ public: Engine& engine, SampleCount timestamp, PortImpl* port, - const Shared::MessageType& type) + ControlBindings::Type type, + int16_t num) : Event(engine, SharedPtr(), timestamp) , _port(port) , _type(type) - {} + , _num(num) + { + assert(_port); + switch (type) { + case ControlBindings::MIDI_CC: + assert(num >= 0 && num < 128); + break; + case ControlBindings::MIDI_RPN: + assert(num >= 0 && num < 16384); + break; + case ControlBindings::MIDI_NRPN: + assert(num >= 0 && num < 16384); + default: + break; + } + } inline void operator=(const SendBinding& ev) { _port = ev._port; _type = ev._type; + _num = ev._num; } void post_process(); private: - PortImpl* _port; - Shared::MessageType _type; + PortImpl* _port; + ControlBindings::Type _type; + int16_t _num; }; diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp index 85768b3d..30bf4907 100644 --- a/src/engine/events/SetMetadata.cpp +++ b/src/engine/events/SetMetadata.cpp @@ -21,16 +21,17 @@ #include "interface/PortType.hpp" #include "shared/LV2URIMap.hpp" #include "ClientBroadcaster.hpp" +#include "ControlBindings.hpp" #include "CreateNode.hpp" #include "CreatePatch.hpp" #include "CreatePort.hpp" #include "Engine.hpp" #include "EngineStore.hpp" +#include "EventSource.hpp" #include "GraphObjectImpl.hpp" #include "PatchImpl.hpp" #include "PluginImpl.hpp" #include "PortImpl.hpp" -#include "EventSource.hpp" #include "Responder.hpp" #include "SetMetadata.hpp" #include "SetPortValue.hpp" @@ -183,6 +184,17 @@ SetMetadata::pre_process() } else { warn << "Set value for non-port " << _object->uri() << endl; } + } else if (key == uris.ingen_controlBinding) { + PortImpl* port = dynamic_cast(_object); + if (port) { + if (value.type() == Atom::DICT) { + op = CONTROL_BINDING; + } else { + _error = BAD_VALUE_TYPE; + } + } else { + warn << "Set binding for non-port " << _object->uri() << endl; + } } } @@ -245,6 +257,9 @@ SetMetadata::execute(ProcessContext& context) if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) _error = INTERNAL; break; + case CONTROL_BINDING: + if ((port = dynamic_cast(_object))) + _engine.control_bindings()->update_port(context, port); default: _success = true; } diff --git a/src/engine/events/SetMetadata.hpp b/src/engine/events/SetMetadata.hpp index cf49efae..6376a1fe 100644 --- a/src/engine/events/SetMetadata.hpp +++ b/src/engine/events/SetMetadata.hpp @@ -94,7 +94,8 @@ private: ENABLE, ENABLE_BROADCAST, POLYPHONY, - POLYPHONIC + POLYPHONIC, + CONTROL_BINDING }; typedef std::vector SetEvents; diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp index 0ec5d98b..33cf628c 100644 --- a/src/engine/events/SetPortValue.cpp +++ b/src/engine/events/SetPortValue.cpp @@ -194,7 +194,7 @@ SetPortValue::apply(Context& context) _port->raise_set_by_user_flag(); return; - } else if (!strcmp(_value.get_blob_type(), "lv2midi:MidiEvent")) { + } else if (!strcmp(_value.get_blob_type(), "http://lv2plug.in/ns/ext/midi#MidiEvent")) { ebuf->prepare_write(context); ebuf->append(frames, 0, uris->midi_event.id, _value.data_size(), (const uint8_t*)_value.get_blob()); diff --git a/src/engine/ingen_engine.cpp b/src/engine/ingen_engine.cpp index b5fe92a9..b2f626c7 100644 --- a/src/engine/ingen_engine.cpp +++ b/src/engine/ingen_engine.cpp @@ -16,6 +16,7 @@ */ #include "module/Module.hpp" +#include "module/World.hpp" #include "Engine.hpp" #include "QueuedEngineInterface.hpp" #include "util.hpp" diff --git a/src/engine/internals/Controller.cpp b/src/engine/internals/Controller.cpp index 44b6a184..4d102bef 100644 --- a/src/engine/internals/Controller.cpp +++ b/src/engine/internals/Controller.cpp @@ -17,6 +17,7 @@ #include #include "raul/midi_events.h" +#include "shared/LV2URIMap.hpp" #include "internals/Controller.hpp" #include "PostProcessor.hpp" #include "events/Learn.hpp" @@ -47,19 +48,20 @@ ControllerNode::ControllerNode(BufferFactory& bufs, : NodeBase(&controller_plugin, path, false, parent, srate, buffer_size) , _learning(false) { + const LV2URIMap& uris = Shared::LV2URIMap::instance(); _ports = new Raul::Array(6); _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom(), _buffer_size); _ports->at(0) = _midi_in_port; _param_port = new InputPort(bufs, this, "controller", 1, 1, PortType::CONTROL, 0.0f, sizeof(Sample)); - _param_port->set_property("lv2:minimum", 0.0f); - _param_port->set_property("lv2:maximum", 127.0f); - _param_port->set_property("lv2:integer", true); + _param_port->set_property(uris.lv2_minimum, 0.0f); + _param_port->set_property(uris.lv2_maximum, 127.0f); + _param_port->set_property(uris.lv2_integer, true); _ports->at(1) = _param_port; _log_port = new InputPort(bufs, this, "logarithmic", 2, 1, PortType::CONTROL, 0.0f, sizeof(Sample)); - _log_port->set_property("lv2:toggled", true); + _log_port->set_property(uris.lv2_toggled, true); _ports->at(2) = _log_port; _min_port = new InputPort(bufs, this, "minimum", 3, 1, PortType::CONTROL, 0.0f, sizeof(Sample)); diff --git a/src/engine/internals/Note.cpp b/src/engine/internals/Note.cpp index 9ed45c96..ecee587f 100644 --- a/src/engine/internals/Note.cpp +++ b/src/engine/internals/Note.cpp @@ -20,6 +20,7 @@ #include "raul/Array.hpp" #include "raul/Maid.hpp" #include "raul/midi_events.h" +#include "shared/LV2URIMap.hpp" #include "internals/Note.hpp" #include "AudioBuffer.hpp" #include "Driver.hpp" @@ -50,6 +51,7 @@ NoteNode::NoteNode(BufferFactory& bufs, const string& path, bool polyphonic, Pat , _prepared_voices(NULL) , _sustain(false) { + const LV2URIMap& uris = Shared::LV2URIMap::instance(); _ports = new Raul::Array(5); _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom(), _buffer_size); @@ -59,16 +61,16 @@ NoteNode::NoteNode(BufferFactory& bufs, const string& path, bool polyphonic, Pat _ports->at(1) = _freq_port; _vel_port = new OutputPort(bufs, this, "velocity", 2, _polyphony, PortType::AUDIO, 0.0f, _buffer_size); - _vel_port->set_property("lv2:minimum", 0.0f); - _vel_port->set_property("lv2:maximum", 1.0f); + _vel_port->set_property(uris.lv2_minimum, 0.0f); + _vel_port->set_property(uris.lv2_maximum, 1.0f); _ports->at(2) = _vel_port; _gate_port = new OutputPort(bufs, this, "gate", 3, _polyphony, PortType::AUDIO, 0.0f, _buffer_size); - _gate_port->set_property("lv2:toggled", true); + _gate_port->set_property(uris.lv2_toggled, true); _ports->at(3) = _gate_port; _trig_port = new OutputPort(bufs, this, "trigger", 4, _polyphony, PortType::AUDIO, 0.0f, _buffer_size); - _trig_port->set_property("lv2:toggled", true); + _trig_port->set_property(uris.lv2_toggled, true); _ports->at(4) = _trig_port; } diff --git a/src/engine/internals/Trigger.cpp b/src/engine/internals/Trigger.cpp index 440e9a63..68d938c0 100644 --- a/src/engine/internals/Trigger.cpp +++ b/src/engine/internals/Trigger.cpp @@ -18,6 +18,7 @@ #include #include "raul/log.hpp" #include "raul/midi_events.h" +#include "shared/LV2URIMap.hpp" #include "internals/Trigger.hpp" #include "AudioBuffer.hpp" #include "EventBuffer.hpp" @@ -44,28 +45,29 @@ TriggerNode::TriggerNode(BufferFactory& bufs, const string& path, bool polyphoni : NodeBase(&trigger_plugin, path, false, parent, srate, buffer_size) , _learning(false) { + const LV2URIMap& uris = LV2URIMap::instance(); _ports = new Raul::Array(5); _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom(), _buffer_size); _ports->at(0) = _midi_in_port; _note_port = new InputPort(bufs, this, "note", 1, 1, PortType::CONTROL, 60.0f, sizeof(Sample)); - _note_port->set_property("lv2:minimum", 0.0f); - _note_port->set_property("lv2:maximum", 127.0f); - _note_port->set_property("lv2:integer", true); + _note_port->set_property(uris.lv2_minimum, 0.0f); + _note_port->set_property(uris.lv2_maximum, 127.0f); + _note_port->set_property(uris.lv2_integer, true); _ports->at(1) = _note_port; _gate_port = new OutputPort(bufs, this, "gate", 2, 1, PortType::AUDIO, 0.0f, _buffer_size); - _gate_port->set_property("lv2:toggled", true); + _gate_port->set_property(uris.lv2_toggled, true); _ports->at(2) = _gate_port; _trig_port = new OutputPort(bufs, this, "trigger", 3, 1, PortType::AUDIO, 0.0f, _buffer_size); - _trig_port->set_property("lv2:toggled", true); + _trig_port->set_property(uris.lv2_toggled, true); _ports->at(3) = _trig_port; _vel_port = new OutputPort(bufs, this, "velocity", 4, 1, PortType::AUDIO, 0.0f, _buffer_size); - _vel_port->set_property("lv2:minimum", 0.0f); - _vel_port->set_property("lv2:maximum", 1.0f); + _vel_port->set_property(uris.lv2_minimum, 0.0f); + _vel_port->set_property(uris.lv2_maximum, 1.0f); _ports->at(4) = _vel_port; } diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index e6cc1b4e..cdf6cc1f 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -229,16 +229,17 @@ LoadPluginWindow::new_plugin(SharedPtr pm) void LoadPluginWindow::add_plugin(SharedPtr plugin) { + const LV2URIMap& uris = App::instance().uris(); Gtk::TreeModel::iterator iter = _plugins_liststore->append(); Gtk::TreeModel::Row row = *iter; _rows.insert(make_pair(plugin->uri(), iter)); - const Atom& name = plugin->get_property("doap:name"); + const Atom& name = plugin->get_property(uris.doap_name); if (name.is_valid()) { if (name.type() == Atom::STRING) row[_plugins_columns._col_name] = name.get_string(); } else if (plugin->type() == Plugin::LADSPA) { - App::instance().engine()->request_property(plugin->uri(), "doap:name"); + App::instance().engine()->request_property(plugin->uri(), uris.doap_name); } switch (plugin->type()) { @@ -388,12 +389,13 @@ LoadPluginWindow::filter_changed() Gtk::TreeModel::Row model_row; Gtk::TreeModel::iterator model_iter; size_t num_visible = 0; + const LV2URIMap& uris = App::instance().uris(); for (ClientStore::Plugins::const_iterator i = App::instance().store()->plugins()->begin(); i != App::instance().store()->plugins()->end(); ++i) { const SharedPtr plugin = (*i).second; - const Atom& name = plugin->get_property("doap:name"); + const Atom& name = plugin->get_property(uris.doap_name); switch (criteria) { case CriteriaColumns::NAME: @@ -401,7 +403,7 @@ LoadPluginWindow::filter_changed() field = name.get_string(); break; case CriteriaColumns::TYPE: - field = plugin->type_uri(); break; + field = plugin->type_uri().str(); break; case CriteriaColumns::URI: field = plugin->uri().str(); break; default: @@ -415,7 +417,7 @@ LoadPluginWindow::filter_changed() model_row = *model_iter; model_row[_plugins_columns._col_name] = name.is_valid() ? name.get_string() : ""; - model_row[_plugins_columns._col_type] = plugin->type_uri(); + model_row[_plugins_columns._col_type] = plugin->type_uri().str(); model_row[_plugins_columns._col_uri] = plugin->uri().str(); model_row[_plugins_columns._col_plugin] = plugin; diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 277a65ad..024e054d 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -185,6 +185,7 @@ NodeModule::plugin_changed() void NodeModule::embed_gui(bool embed) { + const LV2URIMap& uris = App::instance().uris(); if (embed) { if (_gui_window) { @@ -217,7 +218,7 @@ NodeModule::embed_gui(bool embed) for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) if ((*p)->type().is_control() && (*p)->is_output()) - App::instance().engine()->set_property((*p)->path(), "ingen:broadcast", true); + App::instance().engine()->set_property((*p)->path(), uris.ingen_broadcast, true); } } else { // un-embed @@ -227,7 +228,7 @@ NodeModule::embed_gui(bool embed) for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) if ((*p)->type().is_control() && (*p)->is_output()) - App::instance().engine()->set_property((*p)->path(), "ingen:broadcast", false); + App::instance().engine()->set_property((*p)->path(), uris.ingen_broadcast, false); } if (embed && _embed_item) { diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index 45e6ec66..cd2469d1 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -89,22 +89,22 @@ PatchCanvas::PatchCanvas(SharedPtr patch, int width, int height) // Add port menu items _menu_add_audio_input->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "audio_in", "Audio In", "lv2:AudioPort", false)); + "audio_in", "Audio In", "http://lv2plug.in/ns/lv2core#AudioPort", false)); _menu_add_audio_output->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "audio_out", "Audio Out", "lv2:AudioPort", true)); + "audio_out", "Audio Out", "http://lv2plug.in/ns/lv2core#AudioPort", true)); _menu_add_control_input->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "control_in", "Control In", "lv2:ControlPort", false)); + "control_in", "Control In", "http://lv2plug.in/ns/lv2core#ControlPort", false)); _menu_add_control_output->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "control_out", "Control Out", "lv2:ControlPort", true)); + "control_out", "Control Out", "http://lv2plug.in/ns/lv2core#ControlPort", true)); _menu_add_event_input->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "event_in", "Event In", "lv2ev:EventPort", false)); + "event_in", "Event In", "http://lv2plug.in/ns/ext/event#EventPort", false)); _menu_add_event_output->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "event_out", "Event Out", "lv2ev:EventPort", true)); + "event_out", "Event Out", "http://lv2plug.in/ns/ext/event#EventPort", true)); // Connect to model signals to track state _patch->signal_new_node.connect(sigc::mem_fun(this, &PatchCanvas::add_node)); @@ -750,8 +750,7 @@ PatchCanvas::menu_add_port(const string& sym_base, const string& name_base, Resource::Properties props = get_initial_data(); props.insert(make_pair(uris.rdf_type, type)); - props.insert(make_pair(uris.rdf_type, - Atom(Atom::URI, is_output ? "lv2:OutputPort" : "lv2:InputPort"))); + props.insert(make_pair(uris.rdf_type, is_output ? uris.lv2_OutputPort : uris.lv2_InputPort)); props.insert(make_pair(uris.lv2_index, Atom(int32_t(_patch->num_ports())))); props.insert(make_pair(uris.lv2_name, Atom(name.c_str()))); App::instance().engine()->put(path, props); @@ -801,8 +800,9 @@ GraphObject::Properties PatchCanvas::get_initial_data() { GraphObject::Properties result; - result.insert(make_pair("ingenui:canvas-x", Atom((float)_last_click_x))); - result.insert(make_pair("ingenui:canvas-y", Atom((float)_last_click_y))); + const LV2URIMap& uris = App::instance().uris(); + result.insert(make_pair(uris.ingenui_canvas_x, Atom((float)_last_click_x))); + result.insert(make_pair(uris.ingenui_canvas_y, Atom((float)_last_click_y))); return result; } diff --git a/src/gui/PatchWindow.cpp b/src/gui/PatchWindow.cpp index 13c1f2ff..796837e3 100644 --- a/src/gui/PatchWindow.cpp +++ b/src/gui/PatchWindow.cpp @@ -22,6 +22,7 @@ #include #include "raul/AtomRDF.hpp" #include "interface/EngineInterface.hpp" +#include "shared/LV2URIMap.hpp" #include "client/PatchModel.hpp" #include "client/ClientStore.hpp" #include "App.hpp" @@ -93,7 +94,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtrproperty_sensitive() = false; string engine_name = App::instance().engine()->uri().str(); - if (engine_name == "ingen:internal") + if (engine_name == "http://drobilla.net/ns/ingen#internal") engine_name = "internal engine"; _status_bar->push(string("Connected to ") + engine_name, STATUS_CONTEXT_ENGINE); @@ -405,7 +406,7 @@ PatchWindow::event_import_location() void PatchWindow::event_save() { - const Raul::Atom& document = _patch->get_property("ingen:document"); + const Raul::Atom& document = _patch->get_property(App::instance().uris().ingen_document); if (!document.is_valid() || document.type() != Raul::Atom::URI) { event_save_as(); } else { @@ -420,6 +421,7 @@ PatchWindow::event_save() void PatchWindow::event_save_as() { + const Shared::LV2URIMap& uris = App::instance().uris(); while (true) { Gtk::FileChooserDialog dialog(*this, "Save Patch", Gtk::FILE_CHOOSER_ACTION_SAVE); @@ -435,7 +437,7 @@ PatchWindow::event_save_as() dialog.set_filter(filt); // Set current folder to most sensible default - const Raul::Atom& document = _patch->get_property("ingen:document"); + const Raul::Atom& document = _patch->get_property(uris.ingen_document); if (document.type() == Raul::Atom::URI) dialog.set_uri(document.get_uri()); else if (App::instance().configuration()->patch_folder().length() > 0) @@ -468,7 +470,7 @@ PatchWindow::event_save_as() if (!is_bundle && !is_patch) filename += ".ingen.ttl"; - _patch->set_property("lv2:symbol", Atom(base.c_str())); + _patch->set_property(uris.lv2_symbol, Atom(base.c_str())); bool confirm = true; std::fstream fin; @@ -485,7 +487,7 @@ PatchWindow::event_save_as() if (confirm) { const Glib::ustring uri = Glib::filename_to_uri(filename); App::instance().loader()->save_patch(_patch, uri); - _patch->set_property("ingen:document", Atom(Atom::URI, uri.c_str())); + _patch->set_property(uris.ingen_document, Atom(Atom::URI, uri.c_str())); _status_bar->push( (boost::format("Wrote %1% to %2%") % _patch->path() % uri).str(), STATUS_CONTEXT_PATCH); diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index 7367b453..d710f10d 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -50,7 +50,7 @@ Port::create( { Glib::ustring label(human_name ? "" : pm->path().symbol()); if (human_name) { - const Raul::Atom& name = pm->get_property("lv2:name"); + const Raul::Atom& name = pm->get_property(App::instance().uris().lv2_name); if (name.type() == Raul::Atom::STRING) { label = name.get_string(); } else { @@ -205,7 +205,7 @@ Port::set_control(float value, bool signal) } else if (model()->type() == PortType::EVENTS) { app.engine()->set_property(model()->path(), world->uris->ingen_value, - Atom("", 0, NULL)); + Atom("http://example.org/ev#BangEvent", 0, NULL)); } } @@ -238,13 +238,13 @@ Port::property_changed(const URI& key, const Atom& value) ArtVpathDash* Port::dash() { + const LV2URIMap& uris = App::instance().uris(); SharedPtr pm = _port_model.lock(); if (!pm) return NULL; - const Raul::Atom& context = pm->get_property("ctx:context"); - if (!context.is_valid() || context.type() != Atom::URI - || !strcmp(context.get_uri(), "ctx:AudioContext")) + const Raul::Atom& context = pm->get_property(uris.ctx_context); + if (!context.is_valid() || context.type() != Atom::URI || context == uris.ctx_AudioContext) return NULL; if (!_dash) { diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index 51ca4817..8890770a 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -18,6 +18,8 @@ #include #include #include "raul/log.hpp" +#include "module/ingen_module.hpp" +#include "module/World.hpp" #include "client/NodeModel.hpp" #include "client/PluginModel.hpp" #include "App.hpp" @@ -77,6 +79,8 @@ PropertiesWindow::set_object(SharedPtr model) set_title(model->path().chop_scheme() + " Properties - Ingen"); + Shared::World* world = ingen_get_world(); + ostringstream ss; unsigned n_rows = 0; for (ObjectModel::Properties::const_iterator i = model->properties().begin(); @@ -86,7 +90,7 @@ PropertiesWindow::set_object(SharedPtr model) const Raul::Atom& value = i->second; // Column 0: Property - Gtk::Label* lab = manage(new Gtk::Label(i->first.str(), 0.0, 0.5)); + Gtk::Label* lab = manage(new Gtk::Label(world->rdf_world->qualify(i->first.str()), 0.0, 0.5)); _table->attach(*lab, 0, 1, n_rows, n_rows + 1, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK); // Column 1: Type @@ -102,7 +106,8 @@ PropertiesWindow::set_object(SharedPtr model) // Column 2: Value align = manage(new Gtk::Alignment(0.0, 0.5, 1.0, 0.0)); Gtk::Widget* value_widget = create_value_widget(i->first, value); - align->add(*value_widget); + if (value_widget) + align->add(*value_widget); _table->attach(*align, 2, 3, n_rows, n_rows + 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK); _records.insert(make_pair(i->first, Record(value, combo, align, n_rows))); } @@ -161,6 +166,7 @@ PropertiesWindow::create_value_widget(const Raul::URI& uri, const Raul::Atom& va return widget; } + LOG(error) << "Unable to create widget for value " << value << endl; return NULL; } @@ -206,9 +212,11 @@ PropertiesWindow::property_changed(const Raul::URI& predicate, const Raul::Atom& Gtk::Widget* value_widget = create_value_widget(predicate, value); record.value_widget->remove(); - record.value_widget->add(*value_widget); + if (value_widget) { + record.value_widget->add(*value_widget); + value_widget->show(); + } record.value = value; - value_widget->show(); } diff --git a/src/gui/RenameWindow.cpp b/src/gui/RenameWindow.cpp index c50ec213..f7fa86a9 100644 --- a/src/gui/RenameWindow.cpp +++ b/src/gui/RenameWindow.cpp @@ -18,6 +18,7 @@ #include #include #include "interface/EngineInterface.hpp" +#include "shared/LV2URIMap.hpp" #include "client/ObjectModel.hpp" #include "client/ClientStore.hpp" #include "App.hpp" @@ -56,7 +57,7 @@ RenameWindow::set_object(SharedPtr object) { _object = object; _symbol_entry->set_text(object->path().symbol()); - const Atom& name_atom = object->get_property("lv2:name"); + const Atom& name_atom = object->get_property("http://lv2plug.in/ns/lv2core#name"); _label_entry->set_text( (name_atom.type() == Atom::STRING) ? name_atom.get_string() : ""); } @@ -125,10 +126,12 @@ RenameWindow::cancel_clicked() void RenameWindow::ok_clicked() { + const Shared::LV2URIMap& uris = App::instance().uris(); + const string& symbol_str = _symbol_entry->get_text(); const string& label = _label_entry->get_text(); Path path = _object->path(); - const Atom& name_atom = _object->get_property("lv2:name"); + const Atom& name_atom = _object->get_property(uris.lv2_name); if (Symbol::is_valid(symbol_str)) { const Symbol& symbol(symbol_str); @@ -139,8 +142,7 @@ RenameWindow::ok_clicked() } if (label != "" && (!name_atom.is_valid() || label != name_atom.get_string())) { - App::instance().engine()->set_property(path, - "lv2:name", Atom(label)); + App::instance().engine()->set_property(path, uris.lv2_name, Atom(label)); } hide(); diff --git a/src/gui/UploadPatchWindow.cpp b/src/gui/UploadPatchWindow.cpp index 300bcc71..1804ff06 100644 --- a/src/gui/UploadPatchWindow.cpp +++ b/src/gui/UploadPatchWindow.cpp @@ -23,6 +23,7 @@ #include #include "redlandmm/Query.hpp" #include "module/World.hpp" +#include "shared/LV2URIMap.hpp" #include "client/ClientStore.hpp" #include "interface/EngineInterface.hpp" #include "serialisation/Serialiser.hpp" @@ -72,13 +73,14 @@ UploadPatchWindow::present(SharedPtr patch) void UploadPatchWindow::on_show() { + const Shared::LV2URIMap& uris = App::instance().uris(); Gtk::Dialog::on_show(); - Raul::Atom atom = _patch->get_property("lv2:symbol"); + Raul::Atom atom = _patch->get_property(uris.lv2_symbol); if (atom.is_valid()) _symbol_entry->set_text(atom.get_string()); - atom = _patch->get_property("doap:name"); + atom = _patch->get_property(uris.doap_name); if (atom.is_valid()) _short_name_entry->set_text(atom.get_string()); } @@ -234,12 +236,14 @@ UploadPatchWindow::upload_clicked() { assert(!_thread); + const Shared::LV2URIMap& uris = App::instance().uris(); + Glib::ustring symbol = _symbol_entry->get_text(); Glib::ustring short_name = _short_name_entry->get_text(); GraphObject::Properties extra_rdf; - extra_rdf.insert(make_pair("lv2:symbol", symbol)); - extra_rdf.insert(make_pair("doap:name", short_name)); + extra_rdf.insert(make_pair(uris.lv2_symbol, symbol)); + extra_rdf.insert(make_pair(uris.doap_name, short_name)); _response = 0; _progress_pct = 0; diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp index c50298b9..8052ccf2 100644 --- a/src/ingen/main.cpp +++ b/src/ingen/main.cpp @@ -129,7 +129,9 @@ main(int argc, char** argv) world->rdf_world->add_prefix("ingenui", "http://drobilla.net/ns/ingenuity#"); world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#"); world->rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#"); + world->rdf_world->add_prefix("ctx", "http://lv2plug.in/ns/dev/contexts#"); world->rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi#"); + world->rdf_world->add_prefix("midi", "http://drobilla.net/ns/dev/midi#"); world->rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#"); world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); world->rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#"); diff --git a/src/scripts/python/scripts/flatten.py b/src/scripts/python/scripts/flatten.py index 7c311451..6b7ed6ec 100755 --- a/src/scripts/python/scripts/flatten.py +++ b/src/scripts/python/scripts/flatten.py @@ -77,7 +77,7 @@ def cloneNode(om, node, patch): # copy port values for port in node.getPorts(): path = '%s/%s/%s' % (patch.getPath(), name, port.getName()) - om.synth.set_property_slow.async(path, "ingen:value", port.value) + om.synth.set_property_slow.async(path, "http://drobilla.net/ns/ingen#value", port.value) om.metadata.set.async(path, 'user-min', '%f' % port.minvalue) om.metadata.set.async(path, 'user-max', '%f' % port.maxvalue) return name @@ -124,7 +124,7 @@ def flatten(om, patch): conns = port4.getConnections().keys() if len(conns) == 0: portValue = port4.value - om.synth.set_property_slow.async(dst, "ingen:value", portValue) + om.synth.set_property_slow.async(dst, "http://drobilla.net/ns/ingen#value", portValue) else: for port3 in port4.getConnections().keys(): src = port3.getPath() diff --git a/src/scripts/python/scripts/sillysinepatch.py b/src/scripts/python/scripts/sillysinepatch.py index f46c6d46..24bf68e8 100644 --- a/src/scripts/python/scripts/sillysinepatch.py +++ b/src/scripts/python/scripts/sillysinepatch.py @@ -29,8 +29,8 @@ def main(om): om.synth.create_patch("/silly_sine", 1) om.synth.create_node("/silly_sine/output", "Internal", "", "audio_output", 0) om.synth.create_node("/silly_sine/sine", "LADSPA", "cmt.so", "sine_fcac", 0) - om.synth.set_property("/silly_sine/sine/Frequency", "ingen:value", 440.0) - om.synth.set_property("/silly_sine/sine/Amplitude", "ingen:value", 1.0) + om.synth.set_property("/silly_sine/sine/Frequency", "http://drobilla.net/ns/ingen#value", 440.0) + om.synth.set_property("/silly_sine/sine/Amplitude", "http://drobilla.net/ns/ingen#value", 1.0) om.synth.connect("/silly_sine/sine/Output", "/silly_sine/output/out") om.synth.enable_patch("/silly_sine") om.engine.enable() diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 835057bc..bcc45fd1 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -26,6 +26,7 @@ #include "raul/Atom.hpp" #include "raul/AtomRDF.hpp" #include "interface/EngineInterface.hpp" +#include "module/World.hpp" #include "shared/LV2URIMap.hpp" #include "Parser.hpp" @@ -112,7 +113,8 @@ Parser::parse_document( = parse(world, target, model, document_uri, data_path, parent, symbol, data); if (parsed_path) { - target->set_property(*parsed_path, "ingen:document", Atom(Atom::URI, document_uri.c_str())); + target->set_property(*parsed_path, "http://drobilla.net/ns/ingen#document", + Atom(Atom::URI, document_uri.c_str())); } else { LOG(warn) << "Document URI lost" << endl; } @@ -181,9 +183,9 @@ Parser::parse_update( for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); string obj_uri((*i)["s"].to_string()); - const string key(world->rdf_world->qualify((*i)["p"].to_string())); + const string key((*i)["p"].to_string()); const Redland::Node& val_node((*i)["o"]); - const Atom a(AtomRDF::node_to_atom(val_node)); + const Atom a(AtomRDF::node_to_atom(model, val_node)); if (obj_uri.find(":") == string::npos) obj_uri = Path(obj_uri).str(); obj_uri = relative_uri(base_uri, obj_uri, true); @@ -208,7 +210,7 @@ Parser::parse_update( Glib::Mutex::Lock lock(world->rdf_world->mutex()); const string obj_path = (*i)["path"].to_string(); const Redland::Node& val_node = (*i)["value"]; - const Atom a(AtomRDF::node_to_atom(val_node)); + const Atom a(AtomRDF::node_to_atom(model, val_node)); target->set_property(obj_path, world->uris->ingen_value, a); } @@ -236,13 +238,16 @@ Parser::parse( Redland::Query query(*world->rdf_world, query_str); Redland::Query::Results results(query.run(*world->rdf_world, model, document_uri)); - const Redland::Node patch_class (*world->rdf_world, res, "ingen:Patch"); - const Redland::Node node_class (*world->rdf_world, res, "ingen:Node"); - const Redland::Node internal_class (*world->rdf_world, res, "ingen:Internal"); - const Redland::Node ladspa_class (*world->rdf_world, res, "ingen:LADSPAPlugin"); - const Redland::Node in_port_class (*world->rdf_world, res, "lv2:InputPort"); - const Redland::Node out_port_class (*world->rdf_world, res, "lv2:OutputPort"); - const Redland::Node lv2_class (*world->rdf_world, res, "lv2:Plugin"); +#define NS_INGEN "http://drobilla.net/ns/ingen#" +#define NS_LV2 "http://lv2plug.in/ns/lv2core#" + + const Redland::Node patch_class (*world->rdf_world, res, NS_INGEN "Patch"); + const Redland::Node node_class (*world->rdf_world, res, NS_INGEN "Node"); + const Redland::Node internal_class (*world->rdf_world, res, NS_INGEN "Internal"); + const Redland::Node ladspa_class (*world->rdf_world, res, NS_INGEN "LADSPAPlugin"); + const Redland::Node in_port_class (*world->rdf_world, res, NS_LV2 "InputPort"); + const Redland::Node out_port_class (*world->rdf_world, res, NS_LV2 "OutputPort"); + const Redland::Node lv2_class (*world->rdf_world, res, NS_LV2 "Plugin"); const Redland::Node subject_node = (data_path && !data_path->is_root()) ? Redland::Node(*world->rdf_world, res, data_path->chop_start("/")) @@ -329,13 +334,14 @@ Parser::parse_patch( boost::optional a_symbol, boost::optional data) { + const LV2URIMap& uris = *world->uris.get(); uint32_t patch_poly = 0; typedef Redland::Query::Results Results; /* Use parameter overridden polyphony, if given */ if (data) { - GraphObject::Properties::iterator poly_param = data.get().find("ingen:polyphony"); + GraphObject::Properties::iterator poly_param = data.get().find(uris.ingen_polyphony); if (poly_param != data.get().end() && poly_param->second.type() == Atom::INT) patch_poly = poly_param->second.get_int32(); } @@ -383,8 +389,8 @@ Parser::parse_patch( /* Create patch */ Path patch_path(patch_path_str); Resource::Properties props; - props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Patch"))); - props.insert(make_pair("ingen:polyphony", Raul::Atom(int32_t(patch_poly)))); + props.insert(make_pair(uris.rdf_type, Raul::URI(uris.ingen_Patch))); + props.insert(make_pair(uris.ingen_polyphony, Raul::Atom(int32_t(patch_poly)))); target->put(patch_path, props); @@ -451,11 +457,11 @@ Parser::parse_patch( if (node.type() == Redland::Node::RESOURCE && type_i != types.end()) { if (skip_property(predicate)) continue; - const string key = world->rdf_world->qualify(predicate.to_string()); + const string key = predicate.to_string(); if (patch_i != patch_nodes.end()) { - patch_i->second.insert(make_pair(key, AtomRDF::node_to_atom(object))); + patch_i->second.insert(make_pair(key, AtomRDF::node_to_atom(model, object))); } else if (plug_i != plugin_nodes.end()) { - plug_i->second.insert(make_pair(key, AtomRDF::node_to_atom(object))); + plug_i->second.insert(make_pair(key, AtomRDF::node_to_atom(model, object))); } else { LOG(warn) << "Unrecognized node: " << node.to_string() << endl; } @@ -483,8 +489,8 @@ Parser::parse_patch( continue; const Path node_path(relative_uri(base_uri, i->first, true)); Resource::Properties props; - props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Node"))); - props.insert(make_pair("rdf:instanceOf", Raul::Atom(Raul::Atom::URI, type_i->second))); + props.insert(make_pair(uris.rdf_type, Raul::URI(uris.ingen_Node))); + props.insert(make_pair(uris.rdf_instanceOf, Raul::URI(type_i->second))); props.insert(i->second.begin(), i->second.end()); target->put(node_path, props); } @@ -515,8 +521,8 @@ Parser::parse_patch( const Path node_path(relative_uri(base_uri, node_uri, true)); const Symbol port_sym = port_uri.substr(node_uri.length() + 1); const Path port_path = node_path.child(port_sym); - const string key = world->rdf_world->qualify((*i)["key"].to_string()); - p->second.insert(make_pair(key, AtomRDF::node_to_atom((*i)["val"]))); + const string key = (*i)["key"].to_string(); + p->second.insert(make_pair(key, AtomRDF::node_to_atom(model, (*i)["val"]))); } for (Objects::iterator i = node_ports.begin(); i != node_ports.end(); ++i) { @@ -537,8 +543,7 @@ Parser::parse_patch( Redland::Node& port = (*i)["port"]; Redland::Node& type = (*i)["type"]; if (port.type() == Redland::Node::RESOURCE && type.type() == Redland::Node::RESOURCE) { - types.insert(make_pair(port.to_string(), - world->rdf_world->qualify(type.to_string()))); + types.insert(make_pair(port.to_string(), type.to_string())); patch_ports.insert(make_pair(port.to_string(), Properties())); } } @@ -555,18 +560,18 @@ Parser::parse_patch( Glib::Mutex::Lock lock(world->rdf_world->mutex()); const string port_uri = (*i)["port"].to_string(); const Path port_path(Path(relative_uri(base_uri, port_uri, true))); - const string key = world->rdf_world->qualify((*i)["key"].to_string()); + const string key = (*i)["key"].to_string(); Objects::iterator ports_i = patch_ports.find(port_uri); if (ports_i == patch_ports.end()) ports_i = patch_ports.insert(make_pair(port_uri, Properties())).first; - ports_i->second.insert(make_pair(key, AtomRDF::node_to_atom((*i)["val"]))); + ports_i->second.insert(make_pair(key, AtomRDF::node_to_atom(model, (*i)["val"]))); } for (Objects::iterator i = patch_ports.begin(); i != patch_ports.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); const Path port_path(relative_uri(base_uri, i->first, true)); std::pair types_range - = i->second.equal_range("rdf:type"); + = i->second.equal_range(uris.rdf_type); if (types_range.first == i->second.end()) { LOG(warn) << "Patch port has no types" << endl; continue; @@ -577,9 +582,9 @@ Parser::parse_patch( for (Properties::iterator t = types_range.first; t != types_range.second; ++t) { if (t->second.type() != Atom::URI) { continue; - } else if (!strcmp(t->second.get_uri(), "lv2:InputPort")) { + } else if (!strcmp(t->second.get_uri(), uris.lv2_InputPort.c_str())) { is_input = true; - } else if (!strcmp(t->second.get_uri(), "lv2:OutputPort")) { + } else if (!strcmp(t->second.get_uri(), uris.lv2_OutputPort.c_str())) { is_output = true; } else if (!type) { type = &t->second; @@ -611,7 +616,7 @@ Parser::parse_patch( Glib::Mutex::Lock lock(world->rdf_world->mutex()); const Redland::Node& enabled_node = (*i)["enabled"]; if (enabled_node.is_bool() && enabled_node) { - target->set_property(patch_path, "ingen:enabled", (bool)true); + target->set_property(patch_path, uris.ingen_enabled, (bool)true); break; } else { LOG(warn) << "Unknown type for ingen:enabled" << endl; @@ -631,6 +636,8 @@ Parser::parse_node( const Raul::Path& path, boost::optional data) { + const LV2URIMap& uris = *world->uris.get(); + /* Get plugin */ Redland::Query query(*world->rdf_world, Glib::ustring( "SELECT DISTINCT ?plug WHERE {\n") @@ -652,8 +659,8 @@ Parser::parse_node( const string plugin_uri = world->rdf_world->expand_uri(plugin_node.to_c_string()); Resource::Properties props; - props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Node"))); - props.insert(make_pair("rdf:instanceOf", Raul::Atom(Raul::Atom::URI, plugin_uri))); + props.insert(make_pair(uris.rdf_type, Raul::URI(uris.ingen_Node))); + props.insert(make_pair(uris.rdf_instanceOf, Raul::Atom(Raul::Atom::URI, plugin_uri))); target->put(path, props); parse_properties(world, target, model, subject, path, data); @@ -715,12 +722,12 @@ Parser::parse_properties( Redland::Query::Results results = query.run(*world->rdf_world, model); for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); - const string key = world->rdf_world->qualify(string((*i)["key"])); + const string key = string((*i)["key"]); const Redland::Node& val = (*i)["val"]; if (skip_property((*i)["key"])) continue; if (key != "" && val.type() != Redland::Node::BLANK) - properties.insert(make_pair(key, AtomRDF::node_to_atom(val))); + properties.insert(make_pair(key, AtomRDF::node_to_atom(model, val))); } target->put(uri, properties); diff --git a/src/serialisation/Parser.hpp b/src/serialisation/Parser.hpp index 0ce81e37..cd96bd0b 100644 --- a/src/serialisation/Parser.hpp +++ b/src/serialisation/Parser.hpp @@ -22,13 +22,15 @@ #include #include #include "interface/GraphObject.hpp" -#include "module/World.hpp" namespace Raul { class Path; } namespace Redland { class World; class Model; class Node; } namespace Ingen { namespace Shared { class CommonInterface; } } namespace Ingen { + +namespace Shared { class World; } + namespace Serialisation { diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index 86264900..331cf9f2 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -153,7 +153,7 @@ Serialiser::to_string(SharedPtr object, for (GraphObject::Properties::const_iterator v = extra_rdf.begin(); v != extra_rdf.end(); ++v) { if (v->first.find(":") != string::npos) { _model->add_statement(base_rdf_node, v->first.str(), - AtomRDF::atom_to_node(_model->world(), v->second)); + AtomRDF::atom_to_node(*_model, v->second)); } else { LOG(warn) << "Not serialising extra RDF with key '" << v->first << "'" << endl; } @@ -378,7 +378,7 @@ Serialiser::serialise_plugin(const Shared::Plugin& plugin) const Redland::Node plugin_id = Redland::Resource(_model->world(), plugin.uri().str()); _model->add_statement(plugin_id, "rdf:type", - Redland::Resource(_model->world(), plugin.type_uri())); + Redland::Resource(_model->world(), plugin.type_uri().str())); } @@ -416,7 +416,7 @@ Serialiser::serialise_port(const Port* port, const Redland::Node& port_id) Redland::Resource(_model->world(), "lv2:OutputPort")); _model->add_statement(port_id, "rdf:type", - Redland::Resource(_model->world(), port->type().uri())); + Redland::Resource(_model->world(), port->type().uri().str())); if (dynamic_cast(port->graph_parent())) _model->add_statement(port_id, "rdf:instanceOf", @@ -424,7 +424,7 @@ Serialiser::serialise_port(const Port* port, const Redland::Node& port_id) if (port->is_input() && port->type() == PortType::CONTROL) _model->add_statement(port_id, "ingen:value", - AtomRDF::atom_to_node(_model->world(), port->value())); + AtomRDF::atom_to_node(*_model, port->value())); serialise_properties(port_id, &port->meta(), port->properties()); } @@ -442,16 +442,16 @@ Serialiser::serialise_port_meta(const Port* port, const Redland::Node& port_id) Redland::Resource(_model->world(), "lv2:OutputPort")); _model->add_statement(port_id, "rdf:type", - Redland::Resource(_model->world(), port->type().uri())); + Redland::Resource(_model->world(), port->type().uri().str())); _model->add_statement(port_id, "lv2:index", - AtomRDF::atom_to_node(_model->world(), Atom((int)port->index()))); + AtomRDF::atom_to_node(*_model, Atom((int)port->index()))); if (!port->get_property("lv2:default").is_valid()) { if (port->is_input()) { if (port->value().is_valid()) { _model->add_statement(port_id, "lv2:default", - AtomRDF::atom_to_node(_model->world(), Atom(port->value()))); + AtomRDF::atom_to_node(*_model, Atom(port->value()))); } else if (port->type() == PortType::CONTROL) { LOG(warn) << "Port " << port->path() << " has no lv2:default" << endl; } @@ -500,7 +500,7 @@ Serialiser::serialise_properties( if (v->second.is_valid()) { if (!meta || !meta->has_property(v->first.str(), v->second)) { const Redland::Resource key(_model->world(), v->first.str()); - const Redland::Node value(AtomRDF::atom_to_node(_model->world(), v->second)); + const Redland::Node value(AtomRDF::atom_to_node(*_model, v->second)); if (value.is_valid()) { _model->add_statement(subject, key, value); } else { diff --git a/src/shared/Builder.cpp b/src/shared/Builder.cpp index fd94ddd0..542176d0 100644 --- a/src/shared/Builder.cpp +++ b/src/shared/Builder.cpp @@ -22,8 +22,6 @@ #include "common/interface/Port.hpp" #include "common/interface/Connection.hpp" #include "common/interface/Plugin.hpp" -#include "module/ingen_module.hpp" -#include "module/World.hpp" #include "shared/LV2URIMap.hpp" #include "Builder.hpp" @@ -43,7 +41,7 @@ Builder::Builder(CommonInterface& interface) void Builder::build(SharedPtr object) { - const LV2URIMap& uris = *ingen_get_world()->uris.get(); + const LV2URIMap& uris = Shared::LV2URIMap::instance(); SharedPtr patch = PtrCast(object); if (patch) { if (!object->path().is_root()) { diff --git a/src/shared/LV2Object.cpp b/src/shared/LV2Object.cpp index 193e2c1d..252972ff 100644 --- a/src/shared/LV2Object.cpp +++ b/src/shared/LV2Object.cpp @@ -17,7 +17,6 @@ #include "raul/log.hpp" #include "raul/Atom.hpp" -#include "module/World.hpp" #include "uri-map.lv2/uri-map.h" #include "object.lv2/object.h" #include "LV2Features.hpp" @@ -33,20 +32,20 @@ namespace LV2Object { bool -to_atom(World* world, const LV2_Object* object, Raul::Atom& atom) +to_atom(const LV2_Object* object, Raul::Atom& atom) { - SharedPtr uris = world->uris; + const LV2URIMap& uris = Shared::LV2URIMap::instance(); - if (object->type == uris->object_class_string.id) { + if (object->type == uris.object_class_string.id) { atom = Raul::Atom((char*)(object + 1)); return true; - } else if (object->type == uris->object_class_bool.id) { + } else if (object->type == uris.object_class_bool.id) { atom = Raul::Atom((bool)(int32_t*)(object + 1)); return true; - } else if (object->type == uris->object_class_int32.id) { + } else if (object->type == uris.object_class_int32.id) { atom = Raul::Atom((int32_t*)(object + 1)); return true; - } else if (object->type == uris->object_class_float32.id) { + } else if (object->type == uris.object_class_float32.id) { atom = Raul::Atom((float*)(object + 1)); return true; } @@ -58,24 +57,24 @@ to_atom(World* world, const LV2_Object* object, Raul::Atom& atom) * object->size should be the capacity of the object (not including header) */ bool -from_atom(World* world, const Raul::Atom& atom, LV2_Object* object) +from_atom(const Raul::Atom& atom, LV2_Object* object) { - SharedPtr uris = world->uris; + const LV2URIMap& uris = Shared::LV2URIMap::instance(); char* str; switch (atom.type()) { case Raul::Atom::FLOAT: - object->type = uris->object_class_float32.id; + object->type = uris.object_class_float32.id; object->size = sizeof(float); *(float*)(object + 1) = atom.get_float(); break; case Raul::Atom::INT: - object->type = uris->object_class_int32.id; + object->type = uris.object_class_int32.id; object->size = sizeof(int32_t); *(int32_t*)(object + 1) = atom.get_int32(); break; case Raul::Atom::STRING: - object->type = uris->object_class_string.id; + object->type = uris.object_class_string.id; object->size = std::min((uint16_t)object->size, (uint16_t)(strlen(atom.get_string()) + 1)); str = ((char*)(object + 1)); str[object->size - 1] = '\0'; @@ -83,8 +82,8 @@ from_atom(World* world, const Raul::Atom& atom, LV2_Object* object) break; case Raul::Atom::BLOB: error << "TODO: Blob support" << endl; - /*object->type = uris->object_class_string; - *(uint16_t*)(object + 1) = uris->uri_to_id(NULL, atom.get_blob_type()); + /*object->type = uris.object_class_string; + *(uint16_t*)(object + 1) = uris.uri_to_id(NULL, atom.get_blob_type()); memcpy(((char*)(object + 1) + sizeof(uint32_t)), atom.get_blob(), std::min(atom.data_size(), (size_t)object->size));*/ default: diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp index 37856fe6..70ca954f 100644 --- a/src/shared/LV2URIMap.cpp +++ b/src/shared/LV2URIMap.cpp @@ -22,6 +22,8 @@ #include "raul/log.hpp" #include "object.lv2/object.h" #include "LV2URIMap.hpp" +#include "module/ingen_module.hpp" +#include "module/World.hpp" using namespace std; using namespace Raul; @@ -36,41 +38,67 @@ LV2URIMap::Quark::Quark(const char* c_str) { } +#define NS_CTX "http://lv2plug.in/ns/dev/contexts#" +#define NS_INGEN "http://drobilla.net/ns/ingen#" +#define NS_INGENUI "http://drobilla.net/ns/ingenuity#" +#define NS_LV2 "http://lv2plug.in/ns/lv2core#" +#define NS_MIDI "http://drobilla.net/ns/dev/midi#" +#define NS_MIDI "http://drobilla.net/ns/dev/midi#" +#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" LV2URIMap::LV2URIMap() - : ctx_context("ctx:context") - , ctx_AudioContext("ctx:AudioContext") - , ctx_MessageContext("ctx:MessageContext") - , doap_name("doap:name") - , ingen_LADSPAPlugin("ingen:LADSPAPlugin") - , ingen_Internal("ingen:Internal") - , ingen_Node("ingen:Node") - , ingen_Patch("ingen:Patch") - , ingen_Port("ingen:Port") - , ingen_broadcast("ingen:broadcast") - , ingen_enabled("ingen:enabled") - , ingen_polyphonic("ingen:polyphonic") - , ingen_polyphony("ingen:polyphony") - , ingen_selected("ingen:selected") - , ingen_value("ingen:value") - , ingenui_canvas_x("ingenui:canvas-x") - , ingenui_canvas_y("ingenui:canvas-y") - , lv2_Plugin("lv2:Plugin") - , lv2_index("lv2:index") - , lv2_maximum("lv2:maximum") - , lv2_minimum("lv2:minimum") - , lv2_name("lv2:name") - , lv2_symbol("lv2:symbol") - , lv2_toggled("lv2:toggled") + : ctx_AudioContext(NS_CTX "AudioContext") + , ctx_MessageContext(NS_CTX "MessageContext") + , ctx_context(NS_CTX "context") + , doap_name("http://usefulinc.com/ns/doap#name") + , ingen_Internal(NS_INGEN "Internal") + , ingen_LADSPAPlugin(NS_INGEN "LADSPAPlugin") + , ingen_Node(NS_INGEN "Node") + , ingen_Patch(NS_INGEN "Patch") + , ingen_Port(NS_INGEN "Port") + , ingen_broadcast(NS_INGEN "broadcast") + , ingen_controlBinding(NS_INGEN "controlBinding") + , ingen_document(NS_INGEN "document") + , ingen_enabled(NS_INGEN "enabled") + , ingen_nil(NS_INGEN "nil") + , ingen_node(NS_INGEN "node") + , ingen_polyphonic(NS_INGEN "polyphonic") + , ingen_polyphony(NS_INGEN "polyphony") + , ingen_selected(NS_INGEN "selected") + , ingen_value(NS_INGEN "value") + , ingenui_canvas_x(NS_INGENUI "canvas-x") + , ingenui_canvas_y(NS_INGENUI "canvas-y") + , lv2_AudioPort(NS_LV2 "AudioPort") + , lv2_ControlPort(NS_LV2 "ControlPort") + , lv2_InputPort(NS_LV2 "InputPort") + , lv2_OutputPort(NS_LV2 "OutputPort") + , lv2_Plugin(NS_LV2 "Plugin") + , lv2_default(NS_LV2 "default") + , lv2_index(NS_LV2 "index") + , lv2_integer(NS_LV2 "integer") + , lv2_maximum(NS_LV2 "maximum") + , lv2_minimum(NS_LV2 "minimum") + , lv2_name(NS_LV2 "name") + , lv2_symbol(NS_LV2 "symbol") + , lv2_toggled(NS_LV2 "toggled") + , lv2ev_EventPort("http://lv2plug.in/ns/ext/event#EventPort") + , midi_Bender(NS_MIDI "Bender") + , midi_ChannelPressure(NS_MIDI "ChannelPressure") + , midi_Controller(NS_MIDI "Controller") + , midi_controllerNumber(NS_MIDI "controllerNumber") , midi_event("http://lv2plug.in/ns/ext/midi#MidiEvent") + , obj_MessagePort("http://lv2plug.in/ns/dev/objects#MessagePort") + , obj_ValuePort("http://lv2plug.in/ns/dev/objects#ValuePort") , object_class_bool(LV2_OBJECT_URI "#Bool") , object_class_float32(LV2_OBJECT_URI "#Float32") , object_class_int32(LV2_OBJECT_URI "#Int32") , object_class_string(LV2_OBJECT_URI "#String") , object_class_vector(LV2_OBJECT_URI "#Vector") , object_transfer(LV2_OBJECT_URI "#ObjectTransfer") - , rdf_instanceOf("rdf:instanceOf") - , rdf_type("rdf:type") + , rdf_instanceOf(NS_RDF "instanceOf") + , rdf_type(NS_RDF "type") + , rdfs_seeAlso(NS_RDFS "seeAlso") , string_transfer("http://lv2plug.in/ns/dev/string-port#StringTransfer") , ui_format_events("http://lv2plug.in/ns/extensions/ui#Events") { @@ -81,6 +109,13 @@ LV2URIMap::LV2URIMap() } +const LV2URIMap& +LV2URIMap::instance() +{ + return *ingen_get_world()->uris; +} + + uint32_t LV2URIMap::uri_to_id(const char* map, const char* uri) diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp index df9a1358..d773591f 100644 --- a/src/shared/LV2URIMap.hpp +++ b/src/shared/LV2URIMap.hpp @@ -40,6 +40,8 @@ public: uint32_t uri_to_id(const char* map, const char* uri); + static const LV2URIMap& instance(); + private: static uint32_t uri_map_uri_to_id(LV2_URI_Map_Callback_Data callback_data, const char* map, @@ -54,31 +56,48 @@ public: uint32_t id; }; - const Quark ctx_context; const Quark ctx_AudioContext; const Quark ctx_MessageContext; + const Quark ctx_context; const Quark doap_name; - const Quark ingen_LADSPAPlugin; const Quark ingen_Internal; + const Quark ingen_LADSPAPlugin; const Quark ingen_Node; const Quark ingen_Patch; const Quark ingen_Port; const Quark ingen_broadcast; + const Quark ingen_controlBinding; + const Quark ingen_document; const Quark ingen_enabled; + const Quark ingen_nil; + const Quark ingen_node; const Quark ingen_polyphonic; const Quark ingen_polyphony; const Quark ingen_selected; const Quark ingen_value; const Quark ingenui_canvas_x; const Quark ingenui_canvas_y; + const Quark lv2_AudioPort; + const Quark lv2_ControlPort; + const Quark lv2_InputPort; + const Quark lv2_OutputPort; const Quark lv2_Plugin; + const Quark lv2_default; const Quark lv2_index; + const Quark lv2_integer; const Quark lv2_maximum; const Quark lv2_minimum; const Quark lv2_name; const Quark lv2_symbol; const Quark lv2_toggled; + const Quark lv2ev_EventPort; + const Quark midi_Bender; + const Quark midi_ChannelPressure; + const Quark midi_Controller; + const Quark midi_controllerNumber; const Quark midi_event; + const Quark obj_MessagePort; + const Quark obj_ValuePort; const Quark object_class_bool; const Quark object_class_float32; const Quark object_class_int32; @@ -87,6 +106,7 @@ public: const Quark object_transfer; const Quark rdf_instanceOf; const Quark rdf_type; + const Quark rdfs_seeAlso; const Quark string_transfer; const Quark ui_format_events; }; diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index 625e8c17..ea64a5d7 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -15,7 +15,9 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "raul/log.hpp" #include "raul/Atom.hpp" +#include "shared/LV2URIMap.hpp" #include "ResourceImpl.hpp" using namespace std; @@ -99,46 +101,45 @@ ResourceImpl::type( bool& port, bool& is_output, PortType& data_type) { typedef Resource::Properties::const_iterator iterator; - const std::pair types_range = properties.equal_range("rdf:type"); + const LV2URIMap& uris = Shared::LV2URIMap::instance(); + const std::pair types_range = properties.equal_range(uris.rdf_type); patch = node = port = is_output = false; data_type = PortType::UNKNOWN; for (iterator i = types_range.first; i != types_range.second; ++i) { const Atom& atom = i->second; - if (atom.type() == Atom::URI) { - if (!strncmp(atom.get_uri(), "ingen:", 6)) { - const char* suffix = atom.get_uri() + 6; - if (!strcmp(suffix, "Patch")) { - patch = true; - } else if (!strcmp(suffix, "Node")) { - node = true; - } - } else if (!strncmp(atom.get_uri(), "lv2:", 4)) { - const char* suffix = atom.get_uri() + 4; - port = true; - if (!strcmp(suffix, "InputPort")) { - is_output = false; - port = true; - } else if (!strcmp(suffix, "OutputPort")) { - is_output = true; - port = true; - } else if (!strcmp(suffix, "AudioPort")) { - data_type = PortType::AUDIO; - port = true; - } else if (!strcmp(suffix, "ControlPort")) { - data_type = PortType::CONTROL; - port = true; - } - } else if (!strcmp(atom.get_uri(), "lv2ev:EventPort")) { - data_type = PortType::EVENTS; - port = true; - } else if (!strcmp(atom.get_uri(), "obj:ValuePort")) { - data_type = PortType::VALUE; - port = true; - } else if (!strcmp(atom.get_uri(), "obj:MessagePort")) { - data_type = PortType::MESSAGE; - port = true; - } + if (atom.type() != Atom::URI) { + warn << "[ResourceImpl] Non-URI type " << atom << endl; + continue; + } + + if (atom == uris.ingen_Patch) { + patch = true; + } else if (atom == uris.ingen_Node) { + node = true; + } else if (atom == uris.lv2_InputPort) { + port = true; + is_output = false; + } else if (atom == uris.lv2_OutputPort) { + port = true; + is_output = true; + } else if (atom == uris.lv2_AudioPort) { + port = true; + data_type = PortType::AUDIO; + } else if (atom == uris.lv2_ControlPort) { + port = true; + data_type = PortType::CONTROL; + } else if (atom == uris.lv2ev_EventPort) { + data_type = PortType::EVENTS; + port = true; + } else if (atom == uris.obj_ValuePort) { + data_type = PortType::VALUE; + port = true; + } else if (atom == uris.obj_MessagePort) { + data_type = PortType::MESSAGE; + port = true; + } else { + warn << "[ResourceImpl] Unrecognized type " << atom << endl; } } -- cgit v1.2.1