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/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 +- 8 files changed, 70 insertions(+), 20 deletions(-) (limited to 'src/engine/events') 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()); -- cgit v1.2.1