diff options
author | David Robillard <d@drobilla.net> | 2010-02-03 04:46:56 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-02-03 04:46:56 +0000 |
commit | 87597f85c5a69a9accd3ce2ed88f2a006173e885 (patch) | |
tree | a3ffa393e9aecbc55dae64bad3bd45ee317e6d26 /src/engine | |
parent | a645d2b8be4d7d31f6eef1649156b166a01e0c31 (diff) | |
download | ingen-87597f85c5a69a9accd3ce2ed88f2a006173e885.tar.gz ingen-87597f85c5a69a9accd3ce2ed88f2a006173e885.tar.bz2 ingen-87597f85c5a69a9accd3ce2ed88f2a006173e885.zip |
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
Diffstat (limited to 'src/engine')
34 files changed, 241 insertions, 126 deletions
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<Raul::URI, Shared::ClientInterface*> 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" @@ -34,6 +35,29 @@ 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) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); @@ -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>(((float)cc_value / 127.0) * (max - min) + min)); - port->set_value(value); + Raul::Atom atom(static_cast<float>(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<const int8_t>(buf[1]); - bind(context, controller); - break; + if (type == _map->midi_event.id) { + switch (buf[0] & 0xF0) { + case MIDI_CMD_CONTROL: + num = static_cast<const int8_t>(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<const int8_t>(buf[1]); - const int8_t value = static_cast<const int8_t>(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<const int8_t>(buf[1]); + Bindings::const_iterator i = bindings->find(Key(MIDI_CC, controller)); + if (i != bindings->end()) { + const int8_t value = static_cast<const int8_t>(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<const int8_t>(buf[1]); + const int8_t msb = static_cast<const int8_t>(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<const int8_t>(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<int8_t, PortImpl*> 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<Key, PortImpl*> Bindings; ControlBindings(Engine& engine, SharedPtr<Shared::LV2URIMap> 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<Shared::LV2URIMap> _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> _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<Responder>(), 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 <set> #include <boost/utility.hpp> #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: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\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 } @@ -132,13 +134,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) { string msg = string( 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 <cstdlib> #include <cassert> #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<Patch*>(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 <cassert> -#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 <jack/midiport.h> #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 <map> #include <stdint.h> #include <boost/optional.hpp> +#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<PortImpl*>(_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 <cassert> #include <ladspa.h> #include <raul/Symbol.hpp> -#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<LV2Info> 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 <cassert> #include <glibmm.h> #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<LV2Info> 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 - * <h2>/ingen/binding</h2> - * \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, * <h2>/ingen/set_property</h2> * \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<Patch*>(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 <sstream> #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<Responder>(), 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<PortImpl*>(_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<PortImpl*>(_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<SetPortValue*> 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 <math.h> #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<PortImpl*>(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<PortImpl*>(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 <cmath> #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<PortImpl*>(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; } |