summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ControlBindings.cpp64
-rw-r--r--src/server/ControlBindings.hpp15
-rw-r--r--src/server/LV2Info.cpp1
-rw-r--r--src/server/LV2Info.hpp1
-rw-r--r--src/server/LV2Node.cpp2
-rw-r--r--src/server/PortImpl.cpp14
-rw-r--r--src/server/PortImpl.hpp12
7 files changed, 75 insertions, 34 deletions
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<BufferRef>* 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