From 8d02ef7f4f1b938881ec3e78bcc9d79d569d53ec Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 25 Jul 2012 22:40:33 +0000 Subject: Fix control bindings for logarithmic and sample rate control ports. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4551 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/ControlBindings.cpp | 64 ++++++++++++++++++++++++++---------------- src/server/ControlBindings.hpp | 15 +++++----- src/server/LV2Info.cpp | 1 + src/server/LV2Info.hpp | 1 + src/server/LV2Node.cpp | 2 ++ src/server/PortImpl.cpp | 14 +++++++++ src/server/PortImpl.hpp | 12 ++++++-- src/shared/URIs.cpp | 2 ++ 8 files changed, 77 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp index 32d99c52..ab018fbc 100644 --- a/src/server/ControlBindings.cpp +++ b/src/server/ControlBindings.cpp @@ -29,6 +29,7 @@ #include "PortImpl.hpp" #include "ProcessContext.hpp" #include "ThreadManager.hpp" +#include "Driver.hpp" #define LOG(s) s << "[ControlBindings] " @@ -143,8 +144,8 @@ ControlBindings::port_value_changed(ProcessContext& context, Ingen::Shared::World* world = context.engine().world(); const Ingen::Shared::URIs& uris = world->uris(); if (key) { - int16_t value = port_value_to_control( - port, key.type, value_atom, port->minimum(), port->maximum()); + int16_t value = port_value_to_control( + context, port, key.type, value_atom); uint16_t size = 0; uint8_t buf[4]; switch (key.type) { @@ -190,16 +191,23 @@ ControlBindings::learn(PortImpl* port) _learn_port = port; } -Raul::Atom -ControlBindings::control_to_port_value(Type type, - int16_t value, - const Raul::Atom& min_atom, - const Raul::Atom& max_atom) const +static void +get_range(ProcessContext& context, const PortImpl* port, float* min, float* max) { - float min = min_atom.get_float(); - float max = max_atom.get_float(); - //bool toggled = port->has_property(uris.lv2_portProperty, uris.lv2_toggled); + *min = port->minimum().get_float(); + *max = port->maximum().get_float(); + if (port->is_sample_rate()) { + *min *= context.engine().driver()->sample_rate(); + *max *= context.engine().driver()->sample_rate(); + } +} +Raul::Atom +ControlBindings::control_to_port_value(ProcessContext& context, + const PortImpl* port, + Type type, + int16_t value) const +{ float normal = 0.0f; switch (type) { case MIDI_CC: @@ -216,25 +224,28 @@ ControlBindings::control_to_port_value(Type type, break; } - float scaled_value = normal * (max - min) + min; - //if (toggled) - // scaled_value = (scaled_value < 0.5) ? 0.0 : 1.0; + if (port->is_logarithmic()) { + normal = (expf(normal) - 1.0f) / ((float)M_E - 1.0f); + } + + float min, max; + get_range(context, port, &min, &max); - return _engine.world()->forge().make(scaled_value); + return _engine.world()->forge().make(normal * (max - min) + min); } int16_t -ControlBindings::port_value_to_control(PortImpl* port, +ControlBindings::port_value_to_control(ProcessContext& context, + PortImpl* port, Type type, - const Raul::Atom& value_atom, - const Raul::Atom& min_atom, - const Raul::Atom& max_atom) const + const Raul::Atom& value_atom) const { if (value_atom.type() != port->bufs().forge().Float) return 0; - const float min = min_atom.get_float(); - const float max = max_atom.get_float(); + float min, max; + get_range(context, port, &min, &max); + const float value = value_atom.get_float(); float normal = (value - min) / (max - min); @@ -250,6 +261,10 @@ ControlBindings::port_value_to_control(PortImpl* port, normal = 1.0f; } + if (port->is_logarithmic()) { + normal = logf(normal * ((float)M_E - 1.0f) + 1.0); + } + switch (type) { case MIDI_CC: case MIDI_CHANNEL_PRESSURE: @@ -300,8 +315,10 @@ ControlBindings::set_port_value(ProcessContext& context, Type type, int16_t value) { - const Raul::Atom port_value( - control_to_port_value(type, value, port->minimum(), port->maximum())); + float min, max; + get_range(context, port, &min, &max); + + const Raul::Atom port_value(control_to_port_value(context, port, type, value)); port->set_value(port_value); @@ -323,8 +340,7 @@ ControlBindings::bind(ProcessContext& context, Key key) const Ingen::Shared::URIs& uris = context.engine().world()->uris(); assert(_learn_port); if (key.type == MIDI_NOTE) { - bool toggled = _learn_port->has_property(uris.lv2_portProperty, uris.lv2_toggled); - if (!toggled) + if (!_learn_port->is_toggled()) return false; } diff --git a/src/server/ControlBindings.hpp b/src/server/ControlBindings.hpp index c98175ab..286dde15 100644 --- a/src/server/ControlBindings.hpp +++ b/src/server/ControlBindings.hpp @@ -96,16 +96,15 @@ private: void set_port_value(ProcessContext& context, PortImpl* port, Type type, int16_t value); bool bind(ProcessContext& context, Key key); - Raul::Atom control_to_port_value(Type type, - int16_t value, - const Raul::Atom& min, - const Raul::Atom& max) const; + Raul::Atom control_to_port_value(ProcessContext& context, + const PortImpl* port, + Type type, + int16_t value) const; - int16_t port_value_to_control(PortImpl* port, + int16_t port_value_to_control(ProcessContext& context, + PortImpl* port, Type type, - const Raul::Atom& value, - const Raul::Atom& min, - const Raul::Atom& max) const; + const Raul::Atom& value) const; Engine& _engine; PortImpl* _learn_port; diff --git a/src/server/LV2Info.cpp b/src/server/LV2Info.cpp index 085036c1..b2554dfe 100644 --- a/src/server/LV2Info.cpp +++ b/src/server/LV2Info.cpp @@ -43,6 +43,7 @@ LV2Info::LV2Info(Ingen::Shared::World* world) , lv2_OutputPort(lilv_new_uri(world->lilv_world(), LV2_CORE__OutputPort)) , lv2_default(lilv_new_uri(world->lilv_world(), LV2_CORE__default)) , lv2_portProperty(lilv_new_uri(world->lilv_world(), LV2_CORE__portProperty)) + , lv2_sampleRate(lilv_new_uri(world->lilv_world(), LV2_CORE__sampleRate)) , morph_AutoMorphPort(lilv_new_uri(world->lilv_world(), LV2_MORPH__AutoMorphPort)) , morph_MorphPort(lilv_new_uri(world->lilv_world(), LV2_MORPH__MorphPort)) , morph_supportsType(lilv_new_uri(world->lilv_world(), LV2_MORPH__supportsType)) diff --git a/src/server/LV2Info.hpp b/src/server/LV2Info.hpp index f9bc80e3..321561e7 100644 --- a/src/server/LV2Info.hpp +++ b/src/server/LV2Info.hpp @@ -43,6 +43,7 @@ public: LilvNode* lv2_OutputPort; LilvNode* lv2_default; LilvNode* lv2_portProperty; + LilvNode* lv2_sampleRate; LilvNode* morph_AutoMorphPort; LilvNode* morph_MorphPort; LilvNode* morph_supportsType; diff --git a/src/server/LV2Node.cpp b/src/server/LV2Node.cpp index b68fd1e3..23e64df6 100644 --- a/src/server/LV2Node.cpp +++ b/src/server/LV2Node.cpp @@ -352,6 +352,8 @@ LV2Node::instantiate(BufferFactory& bufs) lilv_nodes_free(values); } + port->cache_properties(); + _ports->at(j) = port; } diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 6920198c..671c8ae2 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -58,6 +58,9 @@ PortImpl::PortImpl(BufferFactory& bufs, , _set_by_user(false) , _is_morph(false) , _is_auto_morph(false) + , _is_logarithmic(false) + , _is_sample_rate(false) + , _is_toggled(false) { assert(node != NULL); assert(_poly > 0); @@ -118,6 +121,17 @@ PortImpl::set_buffers(ProcessContext& context, Raul::Array* buffers) return ret; } +void +PortImpl::cache_properties() +{ + _is_logarithmic = has_property(_bufs.uris().lv2_portProperty, + _bufs.uris().pprops_logarithmic); + _is_sample_rate = has_property(_bufs.uris().lv2_portProperty, + _bufs.uris().lv2_sampleRate); + _is_toggled = has_property(_bufs.uris().lv2_portProperty, + _bufs.uris().lv2_toggled); +} + bool PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) { diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp index 69cd1a96..690461cc 100644 --- a/src/server/PortImpl.hpp +++ b/src/server/PortImpl.hpp @@ -156,8 +156,13 @@ public: void set_type(PortType port_type, LV2_URID buffer_type); - bool is_morph() const { return _is_morph; } - bool is_auto_morph() const { return _is_auto_morph; } + void cache_properties(); + + bool is_morph() const { return _is_morph; } + bool is_auto_morph() const { return _is_auto_morph; } + bool is_logarithmic() const { return _is_logarithmic; } + bool is_sample_rate() const { return _is_sample_rate; } + bool is_toggled() const { return _is_toggled; } protected: PortImpl(BufferFactory& bufs, @@ -186,6 +191,9 @@ protected: bool _set_by_user; bool _is_morph; bool _is_auto_morph; + bool _is_logarithmic; + bool _is_sample_rate; + bool _is_toggled; }; } // namespace Server diff --git a/src/shared/URIs.cpp b/src/shared/URIs.cpp index 347a7a4a..b41a0db3 100644 --- a/src/shared/URIs.cpp +++ b/src/shared/URIs.cpp @@ -19,6 +19,7 @@ #include "lv2/lv2plug.in/ns/ext/atom/atom.h" #include "lv2/lv2plug.in/ns/ext/midi/midi.h" #include "lv2/lv2plug.in/ns/ext/patch/patch.h" +#include "lv2/lv2plug.in/ns/ext/port-props/port-props.h" #include "lv2/lv2plug.in/ns/lv2core/lv2.h" namespace Ingen { @@ -115,6 +116,7 @@ URIs::URIs(Shared::Forge& f, URIMap* map) , patch_remove (forge, map, LV2_PATCH__remove) , patch_request (forge, map, LV2_PATCH__request) , patch_subject (forge, map, LV2_PATCH__subject) + , pprops_logarithmic (forge, map, LV2_PORT_PROPS__logarithmic) , rdf_type (forge, map, NS_RDF "type") , rdfs_seeAlso (forge, map, NS_RDFS "seeAlso") , wildcard (forge, map, NS_INGEN "wildcard") -- cgit v1.2.1