summaryrefslogtreecommitdiffstats
path: root/src/engine/ControlBindings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/ControlBindings.cpp')
-rw-r--r--src/engine/ControlBindings.cpp106
1 files changed, 86 insertions, 20 deletions
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();