leave a comment about port reconnection
[ardour.git] / libs / surfaces / push2 / push2.cc
index 22b9ade39899f9c8fbaf4054438b4f7a3469991d..ec234be7128b4c7cf92fb756c36804a5a3e41e9d 100644 (file)
@@ -42,6 +42,8 @@
 #include "gtkmm2ext/gui_thread.h"
 #include "gtkmm2ext/rgb_macros.h"
 
+#include "canvas/colors.h"
+
 #include "canvas.h"
 #include "gui.h"
 #include "layout.h"
@@ -300,6 +302,7 @@ int
 Push2::close ()
 {
        init_buttons (false);
+       strip_buttons_off ();
 
        /* wait for button data to be flushed */
        AsyncMIDIPort* asp;
@@ -378,12 +381,6 @@ Push2::init_buttons (bool startup)
                write (b->state_msg());
        }
 
-       /* Strip buttons should all be off (black) by default. They will change
-        * color to reflect various conditions
-        */
-
-       strip_buttons_off ();
-
        if (startup) {
 
                /* all other buttons are off (black) */
@@ -625,18 +622,30 @@ void
 Push2::handle_midi_sysex (MIDI::Parser&, MIDI::byte* raw_bytes, size_t sz)
 {
        DEBUG_TRACE (DEBUG::Push2, string_compose ("Sysex, %1 bytes\n", sz));
+
+       if (sz < 8) {
+               return;
+       }
+
        MidiByteArray msg (sz, raw_bytes);
-       MidiByteArray aftertouch_mode_response (9, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x1F, 0x0, 0xF7);
-       MidiByteArray polypress_mode_response (9, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x1F, 0x1, 0xF7);
-
-       if (msg == aftertouch_mode_response) {
-               _pressure_mode = AfterTouch;
-               PressureModeChange (AfterTouch);
-               cerr << "Pressure mod eis after\n";
-       } else if (msg == polypress_mode_response) {
-               _pressure_mode = PolyPressure;
-               PressureModeChange (PolyPressure);
-               cerr << "Pressure mod eis poly\n";
+       MidiByteArray push2_sysex_header (6, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01);
+
+       if (!push2_sysex_header.compare_n (msg, 6)) {
+               return;
+       }
+
+       switch (msg[6]) {
+       case 0x1f: /* pressure mode */
+               if (msg[7] == 0x0) {
+                       _pressure_mode = AfterTouch;
+                       PressureModeChange (AfterTouch);
+                       cerr << "Pressure mode is after\n";
+               } else {
+                       _pressure_mode = PolyPressure;
+                       PressureModeChange (PolyPressure);
+                       cerr << "Pressure mode is poly\n";
+               }
+               break;
        }
 }
 
@@ -813,15 +822,9 @@ Push2::handle_midi_note_on_message (MIDI::Parser& parser, MIDI::EventTwoBytes* e
        for (FNPadMap::iterator pi = pads_with_note.first; pi != pads_with_note.second; ++pi) {
                Pad* pad = pi->second;
 
-               if (pad->do_when_pressed == Pad::FlashOn) {
-                       pad->set_color (LED::White);
-                       pad->set_state (LED::OneShot24th);
-                       write (pad->state_msg());
-               } else if (pad->do_when_pressed == Pad::FlashOff) {
-                       pad->set_color (contrast_color);
-                       pad->set_state (LED::OneShot24th);
-                       write (pad->state_msg());
-               }
+               pad->set_color (contrast_color);
+               pad->set_state (LED::OneShot24th);
+               write (pad->state_msg());
        }
 }
 
@@ -1271,6 +1274,21 @@ Push2::pad_note (int row, int col) const
        return 0;
 }
 
+void
+Push2::update_selection_color ()
+{
+       boost::shared_ptr<MidiTrack> current_midi_track = current_pad_target.lock();
+
+       if (!current_midi_track) {
+               return;
+       }
+
+       selection_color = get_color_index (current_midi_track->presentation_info().color());
+       contrast_color = get_color_index (ArdourCanvas::HSV (current_midi_track->presentation_info().color()).opposite().color());
+
+       reset_pad_colors ();
+}
+
 void
 Push2::reset_pad_colors ()
 {
@@ -1452,6 +1470,8 @@ Push2::set_percussive_mode (bool yn)
 
        int drum_note = 36;
 
+       fn_pad_map.clear ();
+
        for (int row = 0; row < 8; ++row) {
 
                for (int col = 0; col < 4; ++col) {
@@ -1517,6 +1537,14 @@ Push2::stripable_selection_change (StripableNotificationListPtr selected)
        /* disconnect from pad port, if appropriate */
 
        if (current_midi_track && pad_port) {
+
+               /* XXX this could possibly leave dangling MIDI notes.
+                *
+                * A general libardour fix is required. It isn't obvious
+                * how note resolution can be done unless disconnecting
+                * becomes "slow" (i.e. deferred for as long as it takes
+                * to resolve notes).
+                */
                current_midi_track->input()->disconnect (current_midi_track->input()->nth(0), pad_port->name(), this);
        }
 
@@ -1553,9 +1581,15 @@ Push2::get_color_index (ArdourCanvas::Color rgba)
                return i->second;
        }
 
-       int r, g, b, a;
-       UINT_TO_RGBA (rgba, &r, &g, &b, &a);
-       int w = 204; /* not sure where/when we should get this value */
+       double dr, dg, db, da;
+       int r, g, b;
+       ArdourCanvas::color_to_rgba (rgba, dr, dg, db, da);
+       int w = 126; /* not sure where/when we should get this value */
+
+
+       r = (int) floor (255.0 * dr);
+       g = (int) floor (255.0 * dg);
+       b = (int) floor (255.0 * db);
 
        /* get a free index */
 
@@ -1571,20 +1605,28 @@ Push2::get_color_index (ArdourCanvas::Color rgba)
                color_map_free_list.pop();
        }
 
-       MidiByteArray palette_msg (17, 0xf0, 0x00 , 0x21, 0x1d, 0x01, 0x01, 0x03, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x01, 0x7E, 0x00, 0xF7);
-       MidiByteArray update_pallette_msg (8, 0xf0, 0x00, 0x21, 0x1d, 0x01, 0x01, 0x05, 0xF7);
-
+       MidiByteArray palette_msg (17,
+                                  0xf0,
+                                  0x00 , 0x21, 0x1d, 0x01, 0x01, 0x03, /* reset palette header */
+                                  0x00, /* index = 7 */
+                                  0x00, 0x00, /* r = 8 & 9 */
+                                  0x00, 0x00, /* g = 10 & 11 */
+                                  0x00, 0x00, /* b = 12 & 13 */
+                                  0x00, 0x00, /* w (a?) = 14 & 15*/
+                                  0xf7);
        palette_msg[7] = index;
        palette_msg[8] = r & 0x7f;
-       palette_msg[9] = r & 0x1;
+       palette_msg[9] = (r & 0x80) >> 7;
        palette_msg[10] = g & 0x7f;
-       palette_msg[11] = g & 0x1;
+       palette_msg[11] = (g & 0x80) >> 7;
        palette_msg[12] = b & 0x7f;
-       palette_msg[13] = b & 0x1;
+       palette_msg[13] = (b & 0x80) >> 7;
        palette_msg[14] = w & 0x7f;
-       palette_msg[15] = w & 0x1;
+       palette_msg[15] = w & 0x80;
 
        write (palette_msg);
+
+       MidiByteArray update_pallette_msg (8, 0xf0, 0x00, 0x21, 0x1d, 0x01, 0x01, 0x05, 0xF7);
        write (update_pallette_msg);
 
        color_map[rgba] = index;
@@ -1655,12 +1697,6 @@ Push2::set_current_layout (Push2Layout* layout)
                _previous_layout = _current_layout;
        }
 
-       /* turn off all strip buttons - let new layout set them if it
-        * wants/needs to
-        */
-
-       strip_buttons_off ();
-
        _current_layout = layout;
 
        if (_current_layout) {