add button time and explicit bank switching to MCP support
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 7 Oct 2015 19:12:09 +0000 (15:12 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 7 Oct 2015 19:13:03 +0000 (15:13 -0400)
libs/surfaces/mackie/button.cc
libs/surfaces/mackie/button.h
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/mcp_buttons.cc
libs/surfaces/mackie/surface.cc
libs/surfaces/mackie/surface.h

index 53a43de5baae33ba4a1d07b06acd74bc2ede9dc4..ab1e198874555809a2a2ff7ef450a2941f2a8751 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <glib.h>
 
+#include "ardour/ardour.h"
+
 #include "button.h"
 #include "surface.h"
 #include "control_group.h"
@@ -29,7 +31,7 @@ using namespace Mackie;
 Control*
 Button::factory (Surface& surface, Button::ID bid, int id, const std::string& name, Group& group)
 {
-       Button* b = new Button (bid, id, name, group);
+       Button* b = new Button (surface, bid, id, name, group);
        /* store button with the device-specific ID */
        surface.buttons[id] = b;
        surface.controls.push_back (b);
@@ -37,6 +39,35 @@ Button::factory (Surface& surface, Button::ID bid, int id, const std::string& na
        return b;
 }
 
+void
+Button::pressed ()
+{
+       press_time = ARDOUR::get_microseconds ();
+}
+
+void
+Button::released ()
+{
+       press_time = 0;
+}
+
+int32_t
+Button::long_press_count ()
+{
+       if (press_time == 0) {
+               return -1; /* button is not pressed */
+       }
+
+       const ARDOUR::microseconds_t delta = ARDOUR::get_microseconds () - press_time;
+
+       if (delta < 500000) {
+               return 0;
+       } else if (delta < 1000000) {
+               return 1;
+       }
+
+       return 2;
+}
 int
 Button::name_to_id (const std::string& name)
 {
index 42d2ec45b1a9563d3d7bea5038d9d87c7c288954..e9cbdd7b4be517765425e4ffb8080856c8248681 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __ardour_mackie_control_protocol_button_h__
 #define __ardour_mackie_control_protocol_button_h__
 
+#include "ardour/types.h"
+
 #include "controls.h"
 #include "led.h"
 
@@ -125,10 +127,12 @@ public:
        };
 
 
-       Button (ID bid, int did, std::string name, Group & group)
+       Button (Surface& s, ID bid, int did, std::string name, Group & group)
                : Control (did, name, group)
+               , _surface (s)
                , _bid (bid)
-               , _led  (did, name + "_led", group) {}
+               , _led  (did, name + "_led", group)
+               , press_time (0) {}
 
        MidiByteArray zero() { return _led.zero (); }
        MidiByteArray set_state (LedState ls) { return _led.set_state (ls); }
@@ -139,9 +143,18 @@ public:
        static int name_to_id (const std::string& name);
        static std::string id_to_name (Button::ID);
 
+       Surface& surface() const { return _surface; }
+
+       void pressed ();
+       void released ();
+
+       int32_t long_press_count ();
+
 private:
+       Surface& _surface;
        ID  _bid; /* device independent button ID */
        Led _led;
+       ARDOUR::microseconds_t press_time;
 };
 
 } // Mackie namespace
index 93e917b1b5eb9f2860b96e8314bead942ed8d17d..344a1e9ecb00fb4e93feebaf3ed5872499479e11 100644 (file)
@@ -486,6 +486,8 @@ class MackieControlProtocol
        Mackie::LedState click_release (Mackie::Button&);
        Mackie::LedState view_press (Mackie::Button&);
        Mackie::LedState view_release (Mackie::Button&);
+
+       Mackie::LedState bank_release (Mackie::Button&, uint32_t bank_num);
 };
 
 } // namespace
index 5bf52ce4c4cf771c140a13ba771dade1db764328..fb6fbd3e5ad4469be945e13dc4b39d1270dcec50 100644 (file)
@@ -559,24 +559,38 @@ MackieControlProtocol::enter_release (Button &)
 }
 
 LedState
-MackieControlProtocol::F1_press (Button &)
+MackieControlProtocol::bank_release (Button& b, uint32_t basic_bank_num)
 {
-       return off;
+       uint32_t bank_num = basic_bank_num;
+
+       if (b.long_press_count() > 0) {
+               bank_num = 8 + basic_bank_num;
+       }
+
+       switch_banks (n_strips() * bank_num);
+
+       return on;
 }
+
 LedState
-MackieControlProtocol::F1_release (Button &)
+MackieControlProtocol::F1_press (Button &b)
 {
        return off;
 }
 LedState
+MackieControlProtocol::F1_release (Button &b)
+{
+       return bank_release (b, 0);
+}
+LedState
 MackieControlProtocol::F2_press (Button &)
 {
        return off;
 }
 LedState
-MackieControlProtocol::F2_release (Button &)
+MackieControlProtocol::F2_release (Button &b)
 {
-       return off;
+       return bank_release (b, 1);
 }
 LedState
 MackieControlProtocol::F3_press (Button &)
@@ -584,9 +598,9 @@ MackieControlProtocol::F3_press (Button &)
        return off;
 }
 LedState
-MackieControlProtocol::F3_release (Button &)
+MackieControlProtocol::F3_release (Button &b)
 {
-       return off;
+       return bank_release (b, 2);
 }
 LedState
 MackieControlProtocol::F4_press (Button &)
@@ -594,9 +608,9 @@ MackieControlProtocol::F4_press (Button &)
        return off;
 }
 LedState
-MackieControlProtocol::F4_release (Button &)
+MackieControlProtocol::F4_release (Button &b)
 {
-       return off;
+       return bank_release (b, 3);
 }
 LedState
 MackieControlProtocol::F5_press (Button &)
index 65bb25e01c8dfae92f3f455bf188009dadd3c3d8..8ace15a7ad2945f5c31f9a78fe782bf690df1a32 100644 (file)
@@ -532,6 +532,11 @@ Surface::handle_midi_note_on_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
        Button* button = buttons[ev->note_number];
 
        if (button) {
+
+               if (ev->velocity > 64) {
+                       button->pressed ();
+               }
+
                Strip* strip = dynamic_cast<Strip*> (&button->group());
 
                if (strip) {
@@ -543,9 +548,16 @@ Surface::handle_midi_note_on_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
                        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("global button %1\n", button->id()));
                        _mcp.handle_button_event (*this, *button, ev->velocity > 64 ? press : release);
                }
+
+               if (ev->velocity <= 64) {
+                       button->released ();
+               }
+
        } else {
                DEBUG_TRACE (DEBUG::MackieControl, string_compose ("no button found for %1\n", (int) ev->note_number));
        }
+
+       /* button release should reset timer AFTER handler(s) have run */
 }
 
 void
index 1afa1c0de7483e4c27c575660a2e0c607314cc0e..17b515e3d7d42086c340a4687e1a4d18a917a1f5 100644 (file)
@@ -7,6 +7,8 @@
 #include "pbd/xml++.h"
 #include "midi++/types.h"
 
+#include "ardour/types.h"
+
 #include "control_protocol/types.h"
 
 #include "controls.h"
@@ -177,7 +179,7 @@ public:
        Fader*                 _master_fader;
        float                  _last_master_gain_written;
        PBD::ScopedConnection   port_connection;
-       
+
        void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
        MidiByteArray host_connection_query (MidiByteArray& bytes);
        MidiByteArray host_connection_confirmation (const MidiByteArray& bytes);
@@ -195,6 +197,12 @@ public:
        };
 
        int connection_state;
+
+       /* this times the duration between press+release events for all
+          possible 127 buttons on THIS surface (not all surfaces).
+       */
+
+       ARDOUR::microseconds_t button_timer[127];
 };
 
 }