summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLoki Davison <loki.davison@gmail.com>2022-09-08 18:13:16 +1000
committerDavid Robillard <d@drobilla.net>2022-09-08 08:51:53 -0400
commit96be7732bb4d93813eb4ed27790535620a417c5a (patch)
treeca83607a4ec408064d99dde564a70f5ee06bc424 /src
parent1c83dccf62f0bf39a8f772e8d6056220a6ce0a7f (diff)
downloadingen-96be7732bb4d93813eb4ed27790535620a417c5a.tar.gz
ingen-96be7732bb4d93813eb4ed27790535620a417c5a.tar.bz2
ingen-96be7732bb4d93813eb4ed27790535620a417c5a.zip
Make learned MIDI bindings channel specific
Diffstat (limited to 'src')
-rw-r--r--src/URIs.cpp1
-rw-r--r--src/server/ControlBindings.cpp44
2 files changed, 38 insertions, 7 deletions
diff --git a/src/URIs.cpp b/src/URIs.cpp
index a2ad6819..41706868 100644
--- a/src/URIs.cpp
+++ b/src/URIs.cpp
@@ -155,6 +155,7 @@ URIs::URIs(Forge& ingen_forge, URIMap* map, LilvWorld* lworld)
, midi_binding (forge, map, lworld, LV2_MIDI__binding)
, midi_controllerNumber (forge, map, lworld, LV2_MIDI__controllerNumber)
, midi_noteNumber (forge, map, lworld, LV2_MIDI__noteNumber)
+ , midi_channel (forge, map, lworld, LV2_MIDI__channel)
, morph_AutoMorphPort (forge, map, lworld, LV2_MORPH__AutoMorphPort)
, morph_MorphPort (forge, map, lworld, LV2_MORPH__MorphPort)
, morph_currentType (forge, map, lworld, LV2_MORPH__currentType)
diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp
index aefc8608..e4f7e104 100644
--- a/src/server/ControlBindings.cpp
+++ b/src/server/ControlBindings.cpp
@@ -83,9 +83,31 @@ ControlBindings::binding_key(const Atom& binding) const
if (binding.type() == uris.atom_Object) {
const auto* obj = static_cast<const LV2_Atom_Object_Body*>(binding.get_body());
if (obj->otype == uris.midi_Bender) {
- key = Key(Type::MIDI_BENDER);
+ lv2_atom_object_body_get(binding.size(),
+ obj,
+ uris.midi_channel.urid(),
+ &num,
+ nullptr);
+ if (!num) {
+ _engine.log().rt_error("Bender binding missing channel\n");
+ } else if (num->type != uris.atom_Int) {
+ _engine.log().rt_error("Bender channel not an integer\n");
+ } else {
+ key = Key(Type::MIDI_BENDER, reinterpret_cast<LV2_Atom_Int*>(num)->body);
+ }
} else if (obj->otype == uris.midi_ChannelPressure) {
- key = Key(Type::MIDI_CHANNEL_PRESSURE);
+ lv2_atom_object_body_get(binding.size(),
+ obj,
+ uris.midi_channel.urid(),
+ &num,
+ nullptr);
+ if (!num) {
+ _engine.log().rt_error("Pressure binding missing channel\n");
+ } else if (num->type != uris.atom_Int) {
+ _engine.log().rt_error("Pressure channel not an integer\n");
+ } else {
+ key = Key(Type::MIDI_CHANNEL_PRESSURE, reinterpret_cast<LV2_Atom_Int*>(num)->body);
+ }
} else if (obj->otype == uris.midi_Controller) {
lv2_atom_object_body_get(binding.size(),
obj,
@@ -125,19 +147,23 @@ ControlBindings::midi_event_key(uint16_t, const uint8_t* buf, uint16_t& value)
switch (lv2_midi_message_type(buf)) {
case LV2_MIDI_MSG_CONTROLLER:
value = buf[2];
- return {Type::MIDI_CC, static_cast<int8_t>(buf[1])};
+ return {Type::MIDI_CC,
+ static_cast<int16_t>(((buf[0] & 0x0FU) << 8U) | buf[1])};
case LV2_MIDI_MSG_BENDER:
value = (buf[2] << 7U) + buf[1];
- return {Type::MIDI_BENDER};
+ return {Type::MIDI_BENDER, static_cast<int16_t>((buf[0] & 0x0FU))};
case LV2_MIDI_MSG_CHANNEL_PRESSURE:
value = buf[1];
- return {Type::MIDI_CHANNEL_PRESSURE};
+ return {Type::MIDI_CHANNEL_PRESSURE,
+ static_cast<int16_t>((buf[0] & 0x0FU))};
case LV2_MIDI_MSG_NOTE_ON:
value = 1;
- return {Type::MIDI_NOTE, buf[1]};
+ return {Type::MIDI_NOTE,
+ static_cast<int16_t>(((buf[0] & 0x0FU) << 8U) | buf[1])};
case LV2_MIDI_MSG_NOTE_OFF:
value = 0;
- return {Type::MIDI_NOTE, buf[1]};
+ return {Type::MIDI_NOTE,
+ static_cast<int16_t>(((buf[0] & 0x0FU) << 8U) | buf[1])};
default:
return {};
}
@@ -325,9 +351,13 @@ forge_binding(const URIs& uris,
break;
case ControlBindings::Type::MIDI_BENDER:
lv2_atom_forge_object(forge, &frame, 0, uris.midi_Bender);
+ lv2_atom_forge_key(forge, uris.midi_channel);
+ lv2_atom_forge_int(forge, value);
break;
case ControlBindings::Type::MIDI_CHANNEL_PRESSURE:
lv2_atom_forge_object(forge, &frame, 0, uris.midi_ChannelPressure);
+ lv2_atom_forge_key(forge, uris.midi_channel);
+ lv2_atom_forge_int(forge, value);
break;
case ControlBindings::Type::MIDI_NOTE:
lv2_atom_forge_object(forge, &frame, 0, uris.midi_NoteOn);