use modified add_shadow_port API(); make pads flash when pressed
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 20 Jun 2016 12:31:33 +0000 (08:31 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 27 Sep 2016 19:59:30 +0000 (14:59 -0500)
libs/surfaces/push2/push2.cc
libs/surfaces/push2/push2.h

index d1bf24f87bcc2447c76224344193c30f353b8e81..c8ea3ceb4fa0e26fb8ecf8f57c588bf2ab6e6944 100644 (file)
@@ -145,7 +145,7 @@ Push2::open ()
        _input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_in).get();
        _output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_out).get();
 
-       boost::dynamic_pointer_cast<AsyncMIDIPort> (_async_in)->add_shadow_port (string_compose (_("%1 Pads"), X_("Push 2")));
+       boost::dynamic_pointer_cast<AsyncMIDIPort> (_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;
+}
index 2d130b9d66eed6b034cff83276830e8e3ef2c3d7..cc2ff018c4e800b441bdef61d1c4517ee2e00b31 100644 (file)
@@ -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;
 };