diff options
author | Len Ovens <len@ovenwerks.net> | 2015-07-20 12:37:53 -0700 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2015-07-27 16:17:38 -0400 |
commit | 6ab04a27c314c75d0ff84357c01f98f2f285f12a (patch) | |
tree | 2a22a95b9ba2f2d2467b7c8dc5af95c2540ddbef | |
parent | fee54fb1552db2a5df110b285d5a7489be99ba21 (diff) |
Allow any one midi event to control only one thing.
-rw-r--r-- | libs/surfaces/generic_midi/generic_midi_control_protocol.cc | 63 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/generic_midi_control_protocol.h | 2 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/midicontrollable.cc | 1 |
3 files changed, 64 insertions, 2 deletions
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 44d04e532d..8d1952d5f2 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -299,6 +299,7 @@ GenericMidiControlProtocol::start_learning (Controllable* c) } Glib::Threads::Mutex::Lock lm2 (controllables_lock); + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Learn binding: Controlable number: %1\n", c)); MIDIControllables::iterator tmp; for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) { @@ -350,7 +351,6 @@ GenericMidiControlProtocol::start_learning (Controllable* c) pending_controllables.push_back (element); } - mc->learn_about_external_control (); return true; } @@ -425,6 +425,7 @@ GenericMidiControlProtocol::delete_binding (PBD::Controllable* control) } } +// This next function seems unused void GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number) { @@ -462,6 +463,65 @@ GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, } } +void +GenericMidiControlProtocol::check_used_event (int pos, int control_number) +{ + Glib::Threads::Mutex::Lock lm2 (controllables_lock); + + MIDI::channel_t channel = (pos & 0xf); + MIDI::byte value = control_number; + + DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("checking for used event: Channel: %1 Controller: %2 value: %3\n", (int) channel, (pos & 0xf0), (int) value)); + + // Remove any old binding for this midi channel/type/value pair + // Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information + for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) { + MIDIControllable* existingBinding = (*iter); + if ( (existingBinding->get_control_type() & 0xf0 ) == (pos & 0xf0) && (existingBinding->get_control_channel() & 0xf ) == channel ) { + if ( ((int) existingBinding->get_control_additional() == (int) value) || ((pos & 0xf0) == MIDI::pitchbend)) { + DEBUG_TRACE (DEBUG::GenericMidi, "checking: found match, delete old binding.\n"); + delete existingBinding; + iter = controllables.erase (iter); + } else { + ++iter; + } + } else { + ++iter; + } + } + + for (MIDIFunctions::iterator iter = functions.begin(); iter != functions.end();) { + MIDIFunction* existingBinding = (*iter); + if ( (existingBinding->get_control_type() & 0xf0 ) == (pos & 0xf0) && (existingBinding->get_control_channel() & 0xf ) == channel ) { + if ( ((int) existingBinding->get_control_additional() == (int) value) || ((pos & 0xf0) == MIDI::pitchbend)) { + DEBUG_TRACE (DEBUG::GenericMidi, "checking: found match, delete old binding.\n"); + delete existingBinding; + iter = functions.erase (iter); + } else { + ++iter; + } + } else { + ++iter; + } + } + + for (MIDIActions::iterator iter = actions.begin(); iter != actions.end();) { + MIDIAction* existingBinding = (*iter); + if ( (existingBinding->get_control_type() & 0xf0 ) == (pos & 0xf0) && (existingBinding->get_control_channel() & 0xf ) == channel ) { + if ( ((int) existingBinding->get_control_additional() == (int) value) || ((pos & 0xf0) == MIDI::pitchbend)) { + DEBUG_TRACE (DEBUG::GenericMidi, "checking: found match, delete old binding.\n"); + delete existingBinding; + iter = actions.erase (iter); + } else { + ++iter; + } + } else { + ++iter; + } + } + +} + XMLNode& GenericMidiControlProtocol::get_state () { @@ -550,7 +610,6 @@ GenericMidiControlProtocol::set_state (const XMLNode& node, int version) { Glib::Threads::Mutex::Lock lm2 (controllables_lock); - controllables.clear (); nlist = node.children(); // "Controls" if (!nlist.empty()) { diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h index a4a51b7f99..bb38a48401 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h @@ -71,6 +71,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol { int load_bindings (const std::string&); void drop_bindings (); + + void check_used_event (int, int); std::string current_binding() const { return _current_binding; } diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc index f03a113cfe..81f2a5141d 100644 --- a/libs/surfaces/generic_midi/midicontrollable.cc +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -394,6 +394,7 @@ MIDIControllable::midi_receiver (Parser &, MIDI::byte *msg, size_t /*len*/) return; } + _surface->check_used_event(msg[0], msg[1]); bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]); if (controllable) { |