diff --git a/libs/surfaces/push2/push2.cc b/libs/surfaces/push2/push2.cc index d1bf24f87b..c8ea3ceb4f 100644 --- a/libs/surfaces/push2/push2.cc +++ b/libs/surfaces/push2/push2.cc @@ -145,7 +145,7 @@ Push2::open () _input_port = boost::dynamic_pointer_cast(_async_in).get(); _output_port = boost::dynamic_pointer_cast(_async_out).get(); - boost::dynamic_pointer_cast (_async_in)->add_shadow_port (string_compose (_("%1 Pads"), X_("Push 2"))); + boost::dynamic_pointer_cast (_async_in)->add_shadow_port (string_compose (_("%1 Pads"), X_("Push 2")), boost::bind (&Push2::pad_filter, this, _1, _2)); connect_to_parser (); @@ -247,6 +247,13 @@ Push2::init_buttons (bool startup) } } + for (NNPadMap::iterator pi = nn_pad_map.begin(); pi != nn_pad_map.end(); ++pi) { + Pad* pad = pi->second; + + pad->set_color (LED::Black); + pad->set_state (LED::OneShot24th); + write (pad->state_msg()); + } } bool @@ -726,10 +733,15 @@ Push2::handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes* ev) } void -Push2::handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes* ev) +Push2::handle_midi_note_on_message (MIDI::Parser& parser, MIDI::EventTwoBytes* ev) { DEBUG_TRACE (DEBUG::Push2, string_compose ("Note On %1 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity)); + if (ev->velocity == 0) { + handle_midi_note_off_message (parser, ev); + return; + } + switch (ev->note_number) { case 0: strip_vpot_touch (0, ev->velocity > 64); @@ -776,12 +788,51 @@ Push2::handle_midi_note_on_message (MIDI::Parser&, MIDI::EventTwoBytes* ev) } break; } + + if (ev->note_number < 11) { + return; + } + + /* Pad */ + + NNPadMap::iterator pi = nn_pad_map.find (ev->note_number); + + if (pi == nn_pad_map.end()) { + return; + } + + Pad* pad = pi->second; + + pad->set_color (LED::White); + pad->set_state (LED::OneShot24th); + write (pad->state_msg()); } void Push2::handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes* ev) { DEBUG_TRACE (DEBUG::Push2, string_compose ("Note Off %1 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity)); + + if (ev->note_number < 11) { + /* theoretically related to encoder touch start/end, but + * actually they send note on with two different velocity + * values (127 & 64). + */ + return; + } + + NNPadMap::iterator pi = nn_pad_map.find (ev->note_number); + + if (pi == nn_pad_map.end()) { + return; + } + + Pad* pad = pi->second; + + pad->set_color (LED::Black); + pad->set_state (LED::OneShot24th); + write (pad->state_msg()); + } void @@ -1370,3 +1421,25 @@ Push2::splash () splash_start = get_microseconds (); blit_to_device_frame_buffer (); } + +bool +Push2::pad_filter (MidiBuffer& in, MidiBuffer& out) const +{ + /* This filter is called asynchronously from a realtime process + context. It must use atomics to check state, and must not block. + */ + + bool matched = false; + + for (MidiBuffer::iterator ev = in.begin(); ev != in.end(); ++ev) { + if ((*ev).is_note_on() || (*ev).is_note_off()) { + /* encoder touch start/touch end use note 0-10 */ + if ((*ev).note() > 10) { + out.push_back (*ev); + matched = true; + } + } + } + + return matched; +} diff --git a/libs/surfaces/push2/push2.h b/libs/surfaces/push2/push2.h index 2d130b9d66..cc2ff018c4 100644 --- a/libs/surfaces/push2/push2.h +++ b/libs/surfaces/push2/push2.h @@ -53,6 +53,7 @@ namespace MIDI { namespace ARDOUR { class AsyncMIDIPort; class Port; + class MidiBuffer; } namespace ArdourSurface { @@ -447,6 +448,8 @@ class Push2 : public ARDOUR::ControlProtocol void stripable_property_change (PBD::PropertyChange const& what_changed, int which); void switch_bank (uint32_t base); + + bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const; };