From 96be7732bb4d93813eb4ed27790535620a417c5a Mon Sep 17 00:00:00 2001 From: Loki Davison Date: Thu, 8 Sep 2022 18:13:16 +1000 Subject: Make learned MIDI bindings channel specific --- src/URIs.cpp | 1 + src/server/ControlBindings.cpp | 44 +++++++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'src') 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(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(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(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(buf[1])}; + return {Type::MIDI_CC, + static_cast(((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((buf[0] & 0x0FU))}; case LV2_MIDI_MSG_CHANNEL_PRESSURE: value = buf[1]; - return {Type::MIDI_CHANNEL_PRESSURE}; + return {Type::MIDI_CHANNEL_PRESSURE, + static_cast((buf[0] & 0x0FU))}; case LV2_MIDI_MSG_NOTE_ON: value = 1; - return {Type::MIDI_NOTE, buf[1]}; + return {Type::MIDI_NOTE, + static_cast(((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(((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); -- cgit v1.2.1