d5e3461057fca9639f5c47b467e7e1d8abc5ef0d
[ardour.git] / libs / surfaces / push2 / push2.cc
1 /*
2   Copyright (C) 2016 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <stdlib.h>
20
21 #include "pbd/compose.h"
22 #include "pbd/convert.h"
23 #include "pbd/debug.h"
24 #include "pbd/failed_constructor.h"
25 #include "pbd/file_utils.h"
26 #include "pbd/search_path.h"
27 #include "pbd/enumwriter.h"
28
29 #include "midi++/parser.h"
30 #include "timecode/time.h"
31 #include "timecode/bbt_time.h"
32
33 #include "ardour/async_midi_port.h"
34 #include "ardour/audioengine.h"
35 #include "ardour/debug.h"
36 #include "ardour/midiport_manager.h"
37 #include "ardour/midi_track.h"
38 #include "ardour/midi_port.h"
39 #include "ardour/session.h"
40 #include "ardour/tempo.h"
41
42 #include "gtkmm2ext/gui_thread.h"
43 #include "gtkmm2ext/rgb_macros.h"
44
45 #include "canvas/colors.h"
46
47 #include "canvas.h"
48 #include "gui.h"
49 #include "layout.h"
50 #include "menu.h"
51 #include "mix.h"
52 #include "push2.h"
53 #include "scale.h"
54 #include "splash.h"
55 #include "track_mix.h"
56
57 #include "pbd/i18n.h"
58
59 using namespace ARDOUR;
60 using namespace std;
61 using namespace PBD;
62 using namespace Glib;
63 using namespace ArdourSurface;
64
65 #include "pbd/abstract_ui.cc" // instantiate template
66
67 #define ABLETON 0x2982
68 #define PUSH2   0x1967
69
70 __attribute__((constructor)) static void
71 register_enums ()
72 {
73         EnumWriter& enum_writer (EnumWriter::instance());
74         vector<int> i;
75         vector<string> s;
76
77         MusicalMode::Type mode;
78
79 #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
80 #define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e)
81
82         REGISTER_CLASS_ENUM (MusicalMode,Dorian);
83         REGISTER_CLASS_ENUM (MusicalMode, IonianMajor);
84         REGISTER_CLASS_ENUM (MusicalMode, Minor);
85         REGISTER_CLASS_ENUM (MusicalMode, HarmonicMinor);
86         REGISTER_CLASS_ENUM (MusicalMode, MelodicMinorAscending);
87         REGISTER_CLASS_ENUM (MusicalMode, MelodicMinorDescending);
88         REGISTER_CLASS_ENUM (MusicalMode, Phrygian);
89         REGISTER_CLASS_ENUM (MusicalMode, Lydian);
90         REGISTER_CLASS_ENUM (MusicalMode, Mixolydian);
91         REGISTER_CLASS_ENUM (MusicalMode, Aeolian);
92         REGISTER_CLASS_ENUM (MusicalMode, Locrian);
93         REGISTER_CLASS_ENUM (MusicalMode, PentatonicMajor);
94         REGISTER_CLASS_ENUM (MusicalMode, PentatonicMinor);
95         REGISTER_CLASS_ENUM (MusicalMode, Chromatic);
96         REGISTER_CLASS_ENUM (MusicalMode, BluesScale);
97         REGISTER_CLASS_ENUM (MusicalMode, NeapolitanMinor);
98         REGISTER_CLASS_ENUM (MusicalMode, NeapolitanMajor);
99         REGISTER_CLASS_ENUM (MusicalMode, Oriental);
100         REGISTER_CLASS_ENUM (MusicalMode, DoubleHarmonic);
101         REGISTER_CLASS_ENUM (MusicalMode, Enigmatic);
102         REGISTER_CLASS_ENUM (MusicalMode, Hirajoshi);
103         REGISTER_CLASS_ENUM (MusicalMode, HungarianMinor);
104         REGISTER_CLASS_ENUM (MusicalMode, HungarianMajor);
105         REGISTER_CLASS_ENUM (MusicalMode, Kumoi);
106         REGISTER_CLASS_ENUM (MusicalMode, Iwato);
107         REGISTER_CLASS_ENUM (MusicalMode, Hindu);
108         REGISTER_CLASS_ENUM (MusicalMode, Spanish8Tone);
109         REGISTER_CLASS_ENUM (MusicalMode, Pelog);
110         REGISTER_CLASS_ENUM (MusicalMode, HungarianGypsy);
111         REGISTER_CLASS_ENUM (MusicalMode, Overtone);
112         REGISTER_CLASS_ENUM (MusicalMode, LeadingWholeTone);
113         REGISTER_CLASS_ENUM (MusicalMode, Arabian);
114         REGISTER_CLASS_ENUM (MusicalMode, Balinese);
115         REGISTER_CLASS_ENUM (MusicalMode, Gypsy);
116         REGISTER_CLASS_ENUM (MusicalMode, Mohammedan);
117         REGISTER_CLASS_ENUM (MusicalMode, Javanese);
118         REGISTER_CLASS_ENUM (MusicalMode, Persian);
119         REGISTER_CLASS_ENUM (MusicalMode, Algerian);
120         REGISTER (mode);
121 }
122
123 Push2::Push2 (ARDOUR::Session& s)
124         : ControlProtocol (s, string (X_("Ableton Push 2")))
125         , AbstractUI<Push2Request> (name())
126         , handle (0)
127         , _modifier_state (None)
128         , splash_start (0)
129         , _current_layout (0)
130         , _previous_layout (0)
131         , connection_state (ConnectionState (0))
132         , gui (0)
133         , _mode (MusicalMode::IonianMajor)
134         , _scale_root (0)
135         , _root_octave (3)
136         , _in_key (true)
137         , octave_shift (0)
138         , percussion (false)
139         , _pressure_mode (AfterTouch)
140 {
141
142         build_maps ();
143         build_color_map ();
144         fill_color_table ();
145
146         /* master cannot be removed, so no need to connect to going-away signal */
147         master = session->master_out ();
148
149         if (open ()) {
150                 throw failed_constructor ();
151         }
152
153         ControlProtocol::StripableSelectionChanged.connect (selection_connection, MISSING_INVALIDATOR, boost::bind (&Push2::stripable_selection_change, this, _1), this);
154
155         /* catch current selection, if any */
156         {
157                 StripableNotificationListPtr sp (new StripableNotificationList (ControlProtocol::last_selected()));
158                 stripable_selection_change (sp);
159         }
160
161         /* catch arrival and departure of Push2 itself */
162         ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, MISSING_INVALIDATOR, boost::bind (&Push2::port_registration_handler, this), this);
163
164         /* Catch port connections and disconnections */
165         ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&Push2::connection_handler, this, _1, _2, _3, _4, _5), this);
166
167         /* ports might already be there */
168         port_registration_handler ();
169 }
170
171 Push2::~Push2 ()
172 {
173         stop ();
174
175         delete track_mix_layout;
176         delete mix_layout;
177         delete scale_layout;
178 }
179
180 void
181 Push2::port_registration_handler ()
182 {
183         if (!_async_in && !_async_out) {
184                 /* ports not registered yet */
185                 return;
186         }
187
188         if (_async_in->connected() && _async_out->connected()) {
189                 /* don't waste cycles here */
190                 return;
191         }
192
193         string input_port_name = X_("Ableton Push 2 MIDI 1 in");
194         string output_port_name = X_("Ableton Push 2 MIDI 1 out");
195         vector<string> in;
196         vector<string> out;
197
198         AudioEngine::instance()->get_ports (string_compose (".*%1", input_port_name), DataType::MIDI, PortFlags (IsPhysical|IsOutput), in);
199         AudioEngine::instance()->get_ports (string_compose (".*%1", output_port_name), DataType::MIDI, PortFlags (IsPhysical|IsInput), out);
200
201         if (!in.empty() && !out.empty()) {
202                 cerr << "Push2: both ports found\n";
203                 cerr << "\tconnecting to " << in.front() <<  " + " << out.front() << endl;
204                 if (!_async_in->connected()) {
205                         AudioEngine::instance()->connect (_async_in->name(), in.front());
206                 }
207                 if (!_async_out->connected()) {
208                         AudioEngine::instance()->connect (_async_out->name(), out.front());
209                 }
210         }
211 }
212
213 int
214 Push2::open ()
215 {
216         int err;
217
218         if (handle) {
219                 /* already open */
220                 return 0;
221         }
222
223         if ((handle = libusb_open_device_with_vid_pid (NULL, ABLETON, PUSH2)) == 0) {
224                 return -1;
225         }
226
227         if ((err = libusb_claim_interface (handle, 0x00))) {
228                 return -1;
229         }
230
231         try {
232                 _canvas = new Push2Canvas (*this, 960, 160);
233                 mix_layout = new MixLayout (*this, *session);
234                 scale_layout = new ScaleLayout (*this, *session);
235                 track_mix_layout = new TrackMixLayout (*this, *session);
236                 splash_layout = new SplashLayout (*this, *session);
237         } catch (...) {
238                 error << _("Cannot construct Canvas for display") << endmsg;
239                 libusb_release_interface (handle, 0x00);
240                 libusb_close (handle);
241                 return -1;
242         }
243
244         /* setup ports */
245
246         _async_in  = AudioEngine::instance()->register_input_port (DataType::MIDI, X_("Push 2 in"), true);
247         _async_out = AudioEngine::instance()->register_output_port (DataType::MIDI, X_("Push 2 out"), true);
248
249         if (_async_in == 0 || _async_out == 0) {
250                 return -1;
251         }
252
253         /* We do not add our ports to the input/output bundles because we don't
254          * want users wiring them by hand. They could use JACK tools if they
255          * really insist on that.
256          */
257
258         _input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_in).get();
259         _output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_out).get();
260
261         /* Create a shadow port where, depending on the state of the surface,
262          * we will make pad note on/off events appear. The surface code will
263          * automatically this port to the first selected MIDI track.
264          */
265
266         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));
267         boost::shared_ptr<MidiPort> shadow_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_in)->shadow_port();
268
269         if (shadow_port) {
270
271                 _output_bundle.reset (new ARDOUR::Bundle (_("Push 2 Pads"), false));
272
273                 _output_bundle->add_channel (
274                         shadow_port->name(),
275                         ARDOUR::DataType::MIDI,
276                         session->engine().make_port_name_non_relative (shadow_port->name())
277                         );
278         }
279
280         session->BundleAddedOrRemoved ();
281
282         connect_to_parser ();
283
284         return 0;
285 }
286
287 list<boost::shared_ptr<ARDOUR::Bundle> >
288 Push2::bundles ()
289 {
290         list<boost::shared_ptr<ARDOUR::Bundle> > b;
291
292         if (_output_bundle) {
293                 b.push_back (_output_bundle);
294         }
295
296         return b;
297 }
298
299 int
300 Push2::close ()
301 {
302         init_buttons (false);
303
304         /* wait for button data to be flushed */
305         AsyncMIDIPort* asp;
306         asp = dynamic_cast<AsyncMIDIPort*> (_output_port);
307         asp->drain (10000, 500000);
308
309         AudioEngine::instance()->unregister_port (_async_in);
310         AudioEngine::instance()->unregister_port (_async_out);
311
312         _async_in.reset ((ARDOUR::Port*) 0);
313         _async_out.reset ((ARDOUR::Port*) 0);
314         _input_port = 0;
315         _output_port = 0;
316
317         periodic_connection.disconnect ();
318         session_connections.drop_connections ();
319
320         if (_current_layout) {
321                 _canvas->root()->remove (_current_layout);
322                 _current_layout = 0;
323         }
324
325         delete mix_layout;
326         mix_layout = 0;
327         delete scale_layout;
328         scale_layout = 0;
329         delete splash_layout;
330         splash_layout = 0;
331
332         if (handle) {
333                 libusb_release_interface (handle, 0x00);
334                 libusb_close (handle);
335                 handle = 0;
336         }
337
338         return 0;
339 }
340
341 void
342 Push2::strip_buttons_off ()
343 {
344         ButtonID strip_buttons[] = { Upper1, Upper2, Upper3, Upper4, Upper5, Upper6, Upper7, Upper8,
345                                      Lower1, Lower2, Lower3, Lower4, Lower5, Lower6, Lower7, Lower8, };
346
347         for (size_t n = 0; n < sizeof (strip_buttons) / sizeof (strip_buttons[0]); ++n) {
348                 Button* b = id_button_map[strip_buttons[n]];
349
350                 b->set_color (LED::Black);
351                 b->set_state (LED::OneShot24th);
352                 write (b->state_msg());
353         }
354 }
355
356
357 void
358 Push2::init_buttons (bool startup)
359 {
360         /* This is a list of buttons that we want lit because they do something
361            in ardour related (loosely, sometimes) to their illuminated label.
362         */
363
364         ButtonID buttons[] = { Mute, Solo, Master, Up, Right, Left, Down, Note, Session, Mix, AddTrack, Delete, Undo,
365                                Metronome, Shift, Select, Play, RecordEnable, Automate, Repeat, Note, Session, DoubleLoop,
366                                Quantize, Duplicate, Browse, PageRight, PageLeft, OctaveUp, OctaveDown, Layout, Scale
367         };
368
369         for (size_t n = 0; n < sizeof (buttons) / sizeof (buttons[0]); ++n) {
370                 Button* b = id_button_map[buttons[n]];
371
372                 if (startup) {
373                         b->set_color (LED::White);
374                 } else {
375                         b->set_color (LED::Black);
376                 }
377                 b->set_state (LED::OneShot24th);
378                 write (b->state_msg());
379         }
380
381         /* Strip buttons should all be off (black) by default. They will change
382          * color to reflect various conditions
383          */
384
385         strip_buttons_off ();
386
387         if (startup) {
388
389                 /* all other buttons are off (black) */
390
391                 ButtonID off_buttons[] = { TapTempo, Setup, User, Stop, Convert, New, FixedLength,
392                                            Fwd32ndT, Fwd32nd, Fwd16thT, Fwd16th, Fwd8thT, Fwd8th, Fwd4trT, Fwd4tr,
393                                            Accent, Note, Session,  };
394
395                 for (size_t n = 0; n < sizeof (off_buttons) / sizeof (off_buttons[0]); ++n) {
396                         Button* b = id_button_map[off_buttons[n]];
397
398                         b->set_color (LED::Black);
399                         b->set_state (LED::OneShot24th);
400                         write (b->state_msg());
401                 }
402         }
403
404         if (!startup) {
405                 for (NNPadMap::iterator pi = nn_pad_map.begin(); pi != nn_pad_map.end(); ++pi) {
406                         Pad* pad = pi->second;
407
408                         pad->set_color (LED::Black);
409                         pad->set_state (LED::OneShot24th);
410                         write (pad->state_msg());
411                 }
412         }
413 }
414
415 bool
416 Push2::probe ()
417 {
418         libusb_device_handle *h;
419         libusb_init (NULL);
420
421         if ((h = libusb_open_device_with_vid_pid (NULL, ABLETON, PUSH2)) == 0) {
422                 DEBUG_TRACE (DEBUG::Push2, "no Push2 device found\n");
423                 return false;
424         }
425
426         libusb_close (h);
427         DEBUG_TRACE (DEBUG::Push2, "Push2 device located\n");
428         return true;
429 }
430
431 void*
432 Push2::request_factory (uint32_t num_requests)
433 {
434         /* AbstractUI<T>::request_buffer_factory() is a template method only
435            instantiated in this source module. To provide something visible for
436            use in the interface/descriptor, we have this static method that is
437            template-free.
438         */
439         return request_buffer_factory (num_requests);
440 }
441
442 void
443 Push2::do_request (Push2Request * req)
444 {
445         if (req->type == CallSlot) {
446
447                 call_slot (MISSING_INVALIDATOR, req->the_slot);
448
449         } else if (req->type == Quit) {
450
451                 stop ();
452         }
453 }
454
455 int
456 Push2::stop ()
457 {
458         BaseUI::quit ();
459         close ();
460         return 0;
461 }
462
463
464 void
465 Push2::splash ()
466 {
467         set_current_layout (splash_layout);
468         splash_start = get_microseconds ();
469 }
470
471 bool
472 Push2::vblank ()
473 {
474         if (splash_start) {
475
476                 /* display splash for 2 seconds */
477
478                 if (get_microseconds() - splash_start > 2000000) {
479                         splash_start = 0;
480                         DEBUG_TRACE (DEBUG::Push2, "splash interval ended, switch to mix layout\n");
481                         set_current_layout (mix_layout);
482                 }
483         }
484
485         _canvas->vblank();
486
487         return true;
488 }
489
490 int
491 Push2::set_active (bool yn)
492 {
493         DEBUG_TRACE (DEBUG::Push2, string_compose("Push2Protocol::set_active init with yn: '%1'\n", yn));
494
495         if (yn == active()) {
496                 return 0;
497         }
498
499         if (yn) {
500
501                 /* start event loop */
502
503                 BaseUI::run ();
504
505                 if (open ()) {
506                         DEBUG_TRACE (DEBUG::Push2, "device open failed\n");
507                         close ();
508                         return -1;
509                 }
510
511                 /* Connect input port to event loop */
512
513                 AsyncMIDIPort* asp;
514
515                 asp = dynamic_cast<AsyncMIDIPort*> (_input_port);
516                 asp->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &Push2::midi_input_handler), _input_port));
517                 asp->xthread().attach (main_loop()->get_context());
518
519                 connect_session_signals ();
520
521                 /* set up periodic task used to push a frame buffer to the
522                  * device (25fps). The device can handle 60fps, but we don't
523                  * need that frame rate.
524                  */
525
526                 Glib::RefPtr<Glib::TimeoutSource> vblank_timeout = Glib::TimeoutSource::create (40); // milliseconds
527                 vblank_connection = vblank_timeout->connect (sigc::mem_fun (*this, &Push2::vblank));
528                 vblank_timeout->attach (main_loop()->get_context());
529
530
531                 Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (1000); // milliseconds
532                 periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &Push2::periodic));
533                 periodic_timeout->attach (main_loop()->get_context());
534
535                 init_buttons (true);
536                 init_touch_strip ();
537                 set_pad_scale (_scale_root, _root_octave, _mode, _in_key);
538                 splash ();
539
540         } else {
541
542                 stop ();
543
544         }
545
546         ControlProtocol::set_active (yn);
547
548         DEBUG_TRACE (DEBUG::Push2, string_compose("Push2Protocol::set_active done with yn: '%1'\n", yn));
549
550         return 0;
551 }
552
553 void
554 Push2::init_touch_strip ()
555 {
556         MidiByteArray msg (9, 0xf0, 0x00, 0x21, 0x1d, 0x01, 0x01, 0x17, 0x00, 0xf7);
557         /* flags are the final byte (ignore end-of-sysex */
558
559         /* show bar, not point
560            autoreturn to center
561            bar starts at center
562         */
563         msg[7] = (1<<4) | (1<<5) | (1<<6);
564         write (msg);
565 }
566
567 void
568 Push2::write (const MidiByteArray& data)
569 {
570         /* immediate delivery */
571         _output_port->write (&data[0], data.size(), 0);
572 }
573
574 bool
575 Push2::midi_input_handler (IOCondition ioc, MIDI::Port* port)
576 {
577         if (ioc & ~IO_IN) {
578                 DEBUG_TRACE (DEBUG::Push2, "MIDI port closed\n");
579                 return false;
580         }
581
582         if (ioc & IO_IN) {
583
584                 // DEBUG_TRACE (DEBUG::Push2, string_compose ("something happend on  %1\n", port->name()));
585
586                 AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*>(port);
587                 if (asp) {
588                         asp->clear ();
589                 }
590
591                 //DEBUG_TRACE (DEBUG::Push2, string_compose ("data available on %1\n", port->name()));
592                 framepos_t now = AudioEngine::instance()->sample_time();
593                 port->parse (now);
594         }
595
596         return true;
597 }
598
599 bool
600 Push2::periodic ()
601 {
602         return true;
603 }
604
605 void
606 Push2::connect_to_parser ()
607 {
608         DEBUG_TRACE (DEBUG::Push2, string_compose ("Connecting to signals on port %2\n", _input_port->name()));
609
610         MIDI::Parser* p = _input_port->parser();
611
612         /* Incoming sysex */
613         p->sysex.connect_same_thread (*this, boost::bind (&Push2::handle_midi_sysex, this, _1, _2, _3));
614         /* V-Pot messages are Controller */
615         p->controller.connect_same_thread (*this, boost::bind (&Push2::handle_midi_controller_message, this, _1, _2));
616         /* Button messages are NoteOn */
617         p->note_on.connect_same_thread (*this, boost::bind (&Push2::handle_midi_note_on_message, this, _1, _2));
618         /* Button messages are NoteOn but libmidi++ sends note-on w/velocity = 0 as note-off so catch them too */
619         p->note_off.connect_same_thread (*this, boost::bind (&Push2::handle_midi_note_on_message, this, _1, _2));
620         /* Fader messages are Pitchbend */
621         p->channel_pitchbend[0].connect_same_thread (*this, boost::bind (&Push2::handle_midi_pitchbend_message, this, _1, _2));
622 }
623
624 void
625 Push2::handle_midi_sysex (MIDI::Parser&, MIDI::byte* raw_bytes, size_t sz)
626 {
627         DEBUG_TRACE (DEBUG::Push2, string_compose ("Sysex, %1 bytes\n", sz));
628         MidiByteArray msg (sz, raw_bytes);
629         MidiByteArray aftertouch_mode_response (9, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x1F, 0x0, 0xF7);
630         MidiByteArray polypress_mode_response (9, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x1F, 0x1, 0xF7);
631
632         if (msg == aftertouch_mode_response) {
633                 _pressure_mode = AfterTouch;
634                 PressureModeChange (AfterTouch);
635                 cerr << "Pressure mod eis after\n";
636         } else if (msg == polypress_mode_response) {
637                 _pressure_mode = PolyPressure;
638                 PressureModeChange (PolyPressure);
639                 cerr << "Pressure mod eis poly\n";
640         }
641 }
642
643 void
644 Push2::handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes* ev)
645 {
646         DEBUG_TRACE (DEBUG::Push2, string_compose ("CC %1 (value %2)\n", (int) ev->controller_number, (int) ev->value));
647
648         CCButtonMap::iterator b = cc_button_map.find (ev->controller_number);
649
650         if (ev->value) {
651                 /* any press cancels any pending long press timeouts */
652                 for (set<ButtonID>::iterator x = buttons_down.begin(); x != buttons_down.end(); ++x) {
653                         Button* bb = id_button_map[*x];
654                         bb->timeout_connection.disconnect ();
655                 }
656         }
657
658         if (b != cc_button_map.end()) {
659
660                 Button* button = b->second;
661
662                 if (ev->value) {
663                         buttons_down.insert (button->id);
664                         start_press_timeout (*button, button->id);
665                 } else {
666                         buttons_down.erase (button->id);
667                         button->timeout_connection.disconnect ();
668                 }
669
670
671                 set<ButtonID>::iterator c = consumed.find (button->id);
672
673                 if (c == consumed.end()) {
674                         if (ev->value == 0) {
675                                 (this->*button->release_method)();
676                         } else {
677                                 (this->*button->press_method)();
678                         }
679                 } else {
680                         DEBUG_TRACE (DEBUG::Push2, "button was consumed, ignored\n");
681                         consumed.erase (c);
682                 }
683
684         } else {
685
686                 /* encoder/vpot */
687
688                 int delta = ev->value;
689
690                 if (delta > 63) {
691                         delta = -(128 - delta);
692                 }
693
694                 switch (ev->controller_number) {
695                 case 71:
696                         _current_layout->strip_vpot (0, delta);
697                         break;
698                 case 72:
699                         _current_layout->strip_vpot (1, delta);
700                         break;
701                 case 73:
702                         _current_layout->strip_vpot (2, delta);
703                         break;
704                 case 74:
705                         _current_layout->strip_vpot (3, delta);
706                         break;
707                 case 75:
708                         _current_layout->strip_vpot (4, delta);
709                         break;
710                 case 76:
711                         _current_layout->strip_vpot (5, delta);
712                         break;
713                 case 77:
714                         _current_layout->strip_vpot (6, delta);
715                         break;
716                 case 78:
717                         _current_layout->strip_vpot (7, delta);
718                         break;
719
720                         /* left side pair */
721                 case 14:
722                         other_vpot (8, delta);
723                         break;
724                 case 15:
725                         other_vpot (1, delta);
726                         break;
727
728                         /* right side */
729                 case 79:
730                         other_vpot (2, delta);
731                         break;
732                 }
733         }
734 }
735
736 void
737 Push2::handle_midi_note_on_message (MIDI::Parser& parser, MIDI::EventTwoBytes* ev)
738 {
739         // DEBUG_TRACE (DEBUG::Push2, string_compose ("Note On %1 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity));
740
741         if (ev->velocity == 0) {
742                 handle_midi_note_off_message (parser, ev);
743                 return;
744         }
745
746         switch (ev->note_number) {
747         case 0:
748                 _current_layout->strip_vpot_touch (0, ev->velocity > 64);
749                 break;
750         case 1:
751                 _current_layout->strip_vpot_touch (1, ev->velocity > 64);
752                 break;
753         case 2:
754                 _current_layout->strip_vpot_touch (2, ev->velocity > 64);
755                 break;
756         case 3:
757                 _current_layout->strip_vpot_touch (3, ev->velocity > 64);
758                 break;
759         case 4:
760                 _current_layout->strip_vpot_touch (4, ev->velocity > 64);
761                 break;
762         case 5:
763                 _current_layout->strip_vpot_touch (5, ev->velocity > 64);
764                 break;
765         case 6:
766                 _current_layout->strip_vpot_touch (6, ev->velocity > 64);
767                 break;
768         case 7:
769                 _current_layout->strip_vpot_touch (7, ev->velocity > 64);
770                 break;
771
772                 /* left side */
773         case 10:
774                 other_vpot_touch (0, ev->velocity > 64);
775                 break;
776         case 9:
777                 other_vpot_touch (1, ev->velocity > 64);
778                 break;
779
780                 /* right side */
781         case 8:
782                 other_vpot_touch (3, ev->velocity > 64);
783                 break;
784
785                 /* touch strip */
786         case 12:
787                 if (ev->velocity < 64) {
788                         transport_stop ();
789                 }
790                 break;
791         }
792
793         if (ev->note_number < 11) {
794                 return;
795         }
796
797         /* Pad */
798
799         NNPadMap::iterator pi = nn_pad_map.find (ev->note_number);
800
801         if (pi == nn_pad_map.end()) {
802                 return;
803         }
804
805         Pad* pad = pi->second;
806
807         if (pad->do_when_pressed == Pad::FlashOn) {
808                 pad->set_color (LED::White);
809                 pad->set_state (LED::OneShot24th);
810                 write (pad->state_msg());
811         } else if (pad->do_when_pressed == Pad::FlashOff) {
812                 pad->set_color (LED::Black);
813                 pad->set_state (LED::OneShot24th);
814                 write (pad->state_msg());
815         }
816 }
817
818 void
819 Push2::handle_midi_note_off_message (MIDI::Parser&, MIDI::EventTwoBytes* ev)
820 {
821         // DEBUG_TRACE (DEBUG::Push2, string_compose ("Note Off %1 (velocity %2)\n", (int) ev->note_number, (int) ev->velocity));
822
823         if (ev->note_number < 11) {
824                 /* theoretically related to encoder touch start/end, but
825                  * actually they send note on with two different velocity
826                  * values (127 & 64).
827                  */
828                 return;
829         }
830
831         NNPadMap::iterator pi = nn_pad_map.find (ev->note_number);
832
833         if (pi == nn_pad_map.end()) {
834                 return;
835         }
836
837         Pad* pad = pi->second;
838
839         if (pad->do_when_pressed == Pad::FlashOn) {
840                 pad->set_color (LED::Black);
841                 pad->set_state (LED::OneShot24th);
842                 write (pad->state_msg());
843         } else if (pad->do_when_pressed == Pad::FlashOff) {
844                 pad->set_color (pad->perma_color);
845                 pad->set_state (LED::OneShot24th);
846                 write (pad->state_msg());
847         }
848 }
849
850 void
851 Push2::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb)
852 {
853 }
854
855 void
856 Push2::thread_init ()
857 {
858         struct sched_param rtparam;
859
860         pthread_set_name (event_loop_name().c_str());
861
862         PBD::notify_event_loops_about_thread_creation (pthread_self(), event_loop_name(), 2048);
863         ARDOUR::SessionEvent::create_per_thread_pool (event_loop_name(), 128);
864
865         memset (&rtparam, 0, sizeof (rtparam));
866         rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
867
868         if (pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam) != 0) {
869                 // do we care? not particularly.
870         }
871 }
872
873 void
874 Push2::connect_session_signals()
875 {
876         // receive routes added
877         //session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_routes_added, this, _1), this);
878         // receive VCAs added
879         //session->vca_manager().VCAAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_vca_added, this, _1), this);
880
881         // receive record state toggled
882         session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_record_state_changed, this), this);
883         // receive transport state changed
884         session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_transport_state_changed, this), this);
885         session->TransportLooped.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_loop_state_changed, this), this);
886         // receive punch-in and punch-out
887         Config->ParameterChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_parameter_changed, this, _1), this);
888         session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_parameter_changed, this, _1), this);
889         // receive rude solo changed
890         session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&Push2::notify_solo_active_changed, this, _1), this);
891 }
892
893 void
894 Push2::notify_record_state_changed ()
895 {
896         IDButtonMap::iterator b = id_button_map.find (RecordEnable);
897
898         if (b == id_button_map.end()) {
899                 return;
900         }
901
902         switch (session->record_status ()) {
903         case Session::Disabled:
904                 b->second->set_color (LED::White);
905                 b->second->set_state (LED::NoTransition);
906                 break;
907         case Session::Enabled:
908                 b->second->set_color (LED::Red);
909                 b->second->set_state (LED::Blinking4th);
910                 break;
911         case Session::Recording:
912                 b->second->set_color (LED::Red);
913                 b->second->set_state (LED::OneShot24th);
914                 break;
915         }
916
917         write (b->second->state_msg());
918 }
919
920 void
921 Push2::notify_transport_state_changed ()
922 {
923         Button* b = id_button_map[Play];
924
925         if (session->transport_rolling()) {
926                 b->set_state (LED::OneShot24th);
927                 b->set_color (LED::Green);
928         } else {
929
930                 /* disable any blink on FixedLength from pending edit range op */
931                 Button* fl = id_button_map[FixedLength];
932
933                 fl->set_color (LED::Black);
934                 fl->set_state (LED::NoTransition);
935                 write (fl->state_msg());
936
937                 b->set_color (LED::White);
938                 b->set_state (LED::NoTransition);
939         }
940
941         write (b->state_msg());
942 }
943
944 void
945 Push2::notify_loop_state_changed ()
946 {
947 }
948
949 void
950 Push2::notify_parameter_changed (std::string param)
951 {
952         IDButtonMap::iterator b;
953
954         if (param == "clicking") {
955                 if ((b = id_button_map.find (Metronome)) == id_button_map.end()) {
956                         return;
957                 }
958                 if (Config->get_clicking()) {
959                         b->second->set_state (LED::Blinking4th);
960                         b->second->set_color (LED::White);
961                 } else {
962                         b->second->set_color (LED::White);
963                         b->second->set_state (LED::NoTransition);
964                 }
965                 write (b->second->state_msg ());
966         }
967 }
968
969 void
970 Push2::notify_solo_active_changed (bool yn)
971 {
972         IDButtonMap::iterator b = id_button_map.find (Solo);
973
974         if (b == id_button_map.end()) {
975                 return;
976         }
977
978         if (yn) {
979                 b->second->set_state (LED::Blinking4th);
980                 b->second->set_color (LED::Red);
981         } else {
982                 b->second->set_state (LED::NoTransition);
983                 b->second->set_color (LED::White);
984         }
985
986         write (b->second->state_msg());
987 }
988
989 XMLNode&
990 Push2::get_state()
991 {
992         XMLNode& node (ControlProtocol::get_state());
993         XMLNode* child;
994
995         child = new XMLNode (X_("Input"));
996         child->add_child_nocopy (_async_in->get_state());
997         node.add_child_nocopy (*child);
998         child = new XMLNode (X_("Output"));
999         child->add_child_nocopy (_async_out->get_state());
1000         node.add_child_nocopy (*child);
1001
1002         node.add_property (X_("root"), to_string (_scale_root, std::dec));
1003         node.add_property (X_("root_octave"), to_string (_root_octave, std::dec));
1004         node.add_property (X_("in_key"), _in_key ? X_("yes") : X_("no"));
1005         node.add_property (X_("mode"), enum_2_string (_mode));
1006
1007         return node;
1008 }
1009
1010 int
1011 Push2::set_state (const XMLNode & node, int version)
1012 {
1013         DEBUG_TRACE (DEBUG::Push2, string_compose ("Push2::set_state: active %1\n", active()));
1014
1015         int retval = 0;
1016
1017         if (ControlProtocol::set_state (node, version)) {
1018                 return -1;
1019         }
1020
1021         XMLNode* child;
1022
1023         if ((child = node.child (X_("Input"))) != 0) {
1024                 XMLNode* portnode = child->child (Port::state_node_name.c_str());
1025                 if (portnode) {
1026                         _async_in->set_state (*portnode, version);
1027                 }
1028         }
1029
1030         if ((child = node.child (X_("Output"))) != 0) {
1031                 XMLNode* portnode = child->child (Port::state_node_name.c_str());
1032                 if (portnode) {
1033                         _async_out->set_state (*portnode, version);
1034                 }
1035         }
1036
1037         XMLProperty const* prop;
1038
1039         if ((prop = node.property (X_("root"))) != 0) {
1040                 _scale_root = atoi (prop->value());
1041         }
1042
1043         if ((prop = node.property (X_("root_octave"))) != 0) {
1044                 _root_octave = atoi (prop->value());
1045         }
1046
1047         if ((prop = node.property (X_("in_key"))) != 0) {
1048                 _in_key = string_is_affirmative (prop->value());
1049         }
1050
1051         if ((prop = node.property (X_("mode"))) != 0) {
1052                 _mode = (MusicalMode::Type) string_2_enum (prop->value(), _mode);
1053         }
1054
1055         return retval;
1056 }
1057
1058 void
1059 Push2::other_vpot (int n, int delta)
1060 {
1061         switch (n) {
1062         case 0:
1063                 break;
1064         case 1:
1065                 break;
1066         case 2:
1067                 /* master gain control */
1068                 if (master) {
1069                         boost::shared_ptr<AutomationControl> ac = master->gain_control();
1070                         if (ac) {
1071                                 ac->set_value (ac->get_value() + ((2.0/64.0) * delta), PBD::Controllable::UseGroup);
1072                         }
1073                 }
1074                 break;
1075         }
1076 }
1077
1078 void
1079 Push2::other_vpot_touch (int n, bool touching)
1080 {
1081         switch (n) {
1082         case 0:
1083                 break;
1084         case 1:
1085                 break;
1086         case 2:
1087                 if (master) {
1088                         boost::shared_ptr<AutomationControl> ac = master->gain_control();
1089                         if (ac) {
1090                                 if (touching) {
1091                                         ac->start_touch (session->audible_frame());
1092                                 } else {
1093                                         ac->stop_touch (true, session->audible_frame());
1094                                 }
1095                         }
1096                 }
1097         }
1098 }
1099
1100 void
1101 Push2::start_shift ()
1102 {
1103         cerr << "start shift\n";
1104         _modifier_state = ModifierState (_modifier_state | ModShift);
1105         Button* b = id_button_map[Shift];
1106         b->set_color (LED::White);
1107         b->set_state (LED::Blinking16th);
1108         write (b->state_msg());
1109 }
1110
1111 void
1112 Push2::end_shift ()
1113 {
1114         if (_modifier_state & ModShift) {
1115                 cerr << "end shift\n";
1116                 _modifier_state = ModifierState (_modifier_state & ~(ModShift));
1117                 Button* b = id_button_map[Shift];
1118                 b->timeout_connection.disconnect ();
1119                 b->set_color (LED::White);
1120                 b->set_state (LED::OneShot24th);
1121                 write (b->state_msg());
1122         }
1123 }
1124
1125 bool
1126 Push2::pad_filter (MidiBuffer& in, MidiBuffer& out) const
1127 {
1128         /* This filter is called asynchronously from a realtime process
1129            context. It must use atomics to check state, and must not block.
1130         */
1131
1132         bool matched = false;
1133
1134         for (MidiBuffer::iterator ev = in.begin(); ev != in.end(); ++ev) {
1135                 if ((*ev).is_note_on() || (*ev).is_note_off()) {
1136
1137                         /* encoder touch start/touch end use note
1138                          * 0-10. touchstrip uses note 12
1139                          */
1140
1141                         if ((*ev).note() > 10 && (*ev).note() != 12) {
1142
1143                                 const int n = (*ev).note ();
1144                                 NNPadMap::const_iterator nni = nn_pad_map.find (n);
1145
1146                                 if (nni != nn_pad_map.end()) {
1147                                         Pad const * pad = nni->second;
1148                                         /* shift for output to the shadow port */
1149                                         if (pad->filtered >= 0) {
1150                                                 (*ev).set_note (pad->filtered + (octave_shift*12));
1151                                                 out.push_back (*ev);
1152                                                 /* shift back so that the pads light correctly  */
1153                                                 (*ev).set_note (n);
1154                                         } else {
1155                                                 /* no mapping, don't send event */
1156                                         }
1157                                 } else {
1158                                         out.push_back (*ev);
1159                                 }
1160
1161                                 matched = true;
1162                         }
1163                 } else if ((*ev).is_pitch_bender() || (*ev).is_poly_pressure() || (*ev).is_channel_pressure()) {
1164                         out.push_back (*ev);
1165                 }
1166         }
1167
1168         return matched;
1169 }
1170
1171 bool
1172 Push2::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
1173 {
1174         DEBUG_TRACE (DEBUG::FaderPort, "FaderPort::connection_handler  start\n");
1175         if (!_input_port || !_output_port) {
1176                 return false;
1177         }
1178
1179         string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_async_in)->name());
1180         string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_async_out)->name());
1181
1182         if (ni == name1 || ni == name2) {
1183                 if (yn) {
1184                         connection_state |= InputConnected;
1185                 } else {
1186                         connection_state &= ~InputConnected;
1187                 }
1188         } else if (no == name1 || no == name2) {
1189                 if (yn) {
1190                         connection_state |= OutputConnected;
1191                 } else {
1192                         connection_state &= ~OutputConnected;
1193                 }
1194         } else {
1195                 DEBUG_TRACE (DEBUG::FaderPort, string_compose ("Connections between %1 and %2 changed, but I ignored it\n", name1, name2));
1196                 /* not our ports */
1197                 return false;
1198         }
1199
1200         if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
1201
1202                 /* XXX this is a horrible hack. Without a short sleep here,
1203                    something prevents the device wakeup messages from being
1204                    sent and/or the responses from being received.
1205                 */
1206
1207                 g_usleep (100000);
1208                 DEBUG_TRACE (DEBUG::FaderPort, "device now connected for both input and output\n");
1209                 connected ();
1210
1211         } else {
1212                 DEBUG_TRACE (DEBUG::FaderPort, "Device disconnected (input or output or both) or not yet fully connected\n");
1213         }
1214
1215         ConnectionChange (); /* emit signal for our GUI */
1216
1217         DEBUG_TRACE (DEBUG::FaderPort, "FaderPort::connection_handler  end\n");
1218
1219         return true; /* connection status changed */
1220 }
1221
1222 void
1223 Push2::connected ()
1224 {
1225         request_pressure_mode ();
1226 }
1227
1228 boost::shared_ptr<Port>
1229 Push2::output_port()
1230 {
1231         return _async_out;
1232 }
1233
1234 boost::shared_ptr<Port>
1235 Push2::input_port()
1236 {
1237         return _async_in;
1238 }
1239
1240 int
1241 Push2::pad_note (int row, int col) const
1242 {
1243         NNPadMap::const_iterator nni = nn_pad_map.find (36+(row*8)+col);
1244
1245         if (nni != nn_pad_map.end()) {
1246                 return nni->second->filtered;
1247         }
1248
1249         return 0;
1250 }
1251
1252 void
1253 Push2::set_pad_scale (int root, int octave, MusicalMode::Type mode, bool inkey)
1254 {
1255         MusicalMode m (mode);
1256         vector<float>::iterator interval;
1257         int note;
1258         const int original_root = root;
1259
1260         interval = m.steps.begin();
1261         root += (octave*12);
1262         note = root;
1263
1264         const int root_start = root;
1265
1266         set<int> mode_map; /* contains only notes in mode, O(logN) lookup */
1267         vector<int> mode_vector; /* sorted in note order */
1268
1269         mode_map.insert (note);
1270         mode_vector.push_back (note);
1271
1272         /* build a map of all notes in the mode, from the root to 127 */
1273
1274         while (note < 128) {
1275
1276                 if (interval == m.steps.end()) {
1277
1278                         /* last distance was the end of the scale,
1279                            so wrap, adding the next note at one
1280                            octave above the last root.
1281                         */
1282
1283                         interval = m.steps.begin();
1284                         root += 12;
1285                         mode_map.insert (root);
1286                         mode_vector.push_back (root);
1287
1288                 } else {
1289                         note = (int) floor (root + (2.0 * (*interval)));
1290                         interval++;
1291                         mode_map.insert (note);
1292                         mode_vector.push_back (note);
1293                 }
1294         }
1295
1296         if (inkey) {
1297
1298                 vector<int>::iterator notei;
1299                 int row_offset = 0;
1300                 for (int row = 0; row < 8; ++row) {
1301
1302                         /* Ableton's grid layout wraps the available notes in the scale
1303                          * by offsetting 3 notes per row (from the bottom)
1304                          */
1305
1306                         notei = mode_vector.begin();
1307                         notei += row_offset;
1308                         row_offset += 3;
1309
1310                         for (int col = 0; col < 8; ++col) {
1311                                 int index = 36 + (row*8) + col;
1312                                 Pad* pad = nn_pad_map[index];
1313                                 int notenum;
1314                                 if (notei != mode_vector.end()) {
1315
1316                                         notenum = *notei;
1317                                         pad->filtered = notenum;
1318
1319                                         if ((notenum % 12) == original_root) {
1320                                                 pad->set_color (LED::Green);
1321                                                 pad->perma_color = LED::Green;
1322                                         } else {
1323                                                 pad->set_color (LED::White);
1324                                                 pad->perma_color = LED::White;
1325                                         }
1326
1327                                         pad->do_when_pressed = Pad::FlashOff;
1328                                         notei++;
1329
1330                                 } else {
1331
1332                                         pad->set_color (LED::Black);
1333                                         pad->do_when_pressed = Pad::Nothing;
1334                                         pad->filtered = -1;
1335                                 }
1336
1337                                 write (pad->state_msg());
1338                         }
1339                 }
1340
1341         } else {
1342
1343                 /* chromatic: all notes available, but highlight those in the scale */
1344
1345                 for (note = 36; note < 100; ++note) {
1346
1347                         Pad* pad = nn_pad_map[note];
1348
1349                         /* Chromatic: all pads play, half-tone steps. Light
1350                          * those in the scale, and highlight root notes
1351                          */
1352
1353                         pad->filtered = root_start + (note - 36);
1354
1355                         if (mode_map.find (note) != mode_map.end()) {
1356
1357                                 if ((note % 12) == original_root) {
1358                                         pad->set_color (LED::Green);
1359                                         pad->perma_color = LED::Green;
1360                                 } else {
1361                                         pad->set_color (LED::White);
1362                                         pad->perma_color = LED::White;
1363                                 }
1364
1365                                 pad->do_when_pressed = Pad::FlashOff;
1366
1367                         } else {
1368
1369                                 /* note is not in mode, turn it off */
1370
1371                                 pad->do_when_pressed = Pad::FlashOn;
1372                                 pad->set_color (LED::Black);
1373
1374                         }
1375
1376                         write (pad->state_msg());
1377                 }
1378         }
1379
1380         /* store state */
1381
1382         _scale_root = original_root;
1383         _root_octave = octave;
1384         _in_key = inkey;
1385         _mode = mode;
1386
1387         ScaleChange (); /* EMIT SIGNAL */
1388 }
1389
1390 void
1391 Push2::set_percussive_mode (bool yn)
1392 {
1393         if (!yn) {
1394                 cerr << "back to scale\n";
1395                 set_pad_scale (_scale_root, _root_octave, _mode, _in_key);
1396                 percussion = false;
1397                 return;
1398         }
1399
1400         int drum_note = 36;
1401
1402         for (int row = 0; row < 8; ++row) {
1403
1404                 for (int col = 0; col < 4; ++col) {
1405
1406                         int index = 36 + (row*8) + col;
1407                         Pad* pad = nn_pad_map[index];
1408
1409                         pad->filtered = drum_note;
1410                         drum_note++;
1411                 }
1412         }
1413
1414         for (int row = 0; row < 8; ++row) {
1415
1416                 for (int col = 4; col < 8; ++col) {
1417
1418                         int index = 36 + (row*8) + col;
1419                         Pad* pad = nn_pad_map[index];
1420
1421                         pad->filtered = drum_note;
1422                         drum_note++;
1423                 }
1424         }
1425
1426         percussion = true;
1427 }
1428
1429 Push2Layout*
1430 Push2::current_layout () const
1431 {
1432         Glib::Threads::Mutex::Lock lm (layout_lock);
1433         return _current_layout;
1434 }
1435
1436 void
1437 Push2::stripable_selection_change (StripableNotificationListPtr selected)
1438 {
1439         boost::shared_ptr<MidiPort> pad_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_async_in)->shadow_port();
1440         boost::shared_ptr<MidiTrack> current_midi_track = current_pad_target.lock();
1441         boost::shared_ptr<MidiTrack> new_pad_target;
1442
1443         /* See if there's a MIDI track selected */
1444
1445         for (StripableNotificationList::iterator si = selected->begin(); si != selected->end(); ++si) {
1446
1447                 new_pad_target = boost::dynamic_pointer_cast<MidiTrack> ((*si).lock());
1448
1449                 if (new_pad_target) {
1450                         break;
1451                 }
1452         }
1453
1454         if (current_midi_track == new_pad_target) {
1455                 /* nothing to do */
1456                 return;
1457         }
1458
1459         if (!new_pad_target) {
1460                 /* leave existing connection alone */
1461                 return;
1462         }
1463
1464         /* disconnect from pad port, if appropriate */
1465
1466         if (current_midi_track && pad_port) {
1467                 current_midi_track->input()->disconnect (current_midi_track->input()->nth(0), pad_port->name(), this);
1468         }
1469
1470         /* now connect the pad port to this (newly) selected midi
1471          * track, if indeed there is one.
1472          */
1473
1474         if (new_pad_target && pad_port) {
1475                 new_pad_target->input()->connect (new_pad_target->input()->nth (0), pad_port->name(), this);
1476                 current_pad_target = new_pad_target;
1477         } else {
1478                 current_pad_target.reset ();
1479         }
1480 }
1481
1482 Push2::Button*
1483 Push2::button_by_id (ButtonID bid)
1484 {
1485         return id_button_map[bid];
1486 }
1487
1488 uint8_t
1489 Push2::get_color_index (uint32_t rgb)
1490 {
1491         ColorMap::iterator i = color_map.find (rgb);
1492
1493         if (i != color_map.end()) {
1494                 return i->second;
1495         }
1496
1497         int r, g, b, a;
1498         UINT_TO_RGBA (rgb, &r, &g, &b, &a);
1499         int w = 204; /* not sure where/when we should get this value */
1500
1501         /* get a free index */
1502
1503         uint8_t index;
1504
1505         if (color_map_free_list.empty()) {
1506                 /* random replacement of any entry above zero and below 122 (where the
1507                  * Ableton standard colors live)
1508                  */
1509                 index = 1 + (random() % 121);
1510         } else {
1511                 index = color_map_free_list.top();
1512                 color_map_free_list.pop();
1513         }
1514
1515         MidiByteArray palette_msg (17, 0xf0, 0x00 , 0x21, 0x1d, 0x01, 0x01, 0x03, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x01, 0x7E, 0x00, 0xF7);
1516         MidiByteArray update_pallette_msg (8, 0xf0, 0x00, 0x21, 0x1d, 0x01, 0x01, 0x05, 0xF7);
1517
1518         palette_msg[7] = index;
1519         palette_msg[8] = r & 0x7f;
1520         palette_msg[9] = r & 0x1;
1521         palette_msg[10] = g & 0x7f;
1522         palette_msg[11] = g & 0x1;
1523         palette_msg[12] = b & 0x7f;
1524         palette_msg[13] = b & 0x1;
1525         palette_msg[14] = w & 0x7f;
1526         palette_msg[15] = w & 0x1;
1527
1528         write (palette_msg);
1529         write (update_pallette_msg);
1530
1531         color_map[index] = rgb;
1532
1533         return index;
1534 }
1535
1536 void
1537 Push2::build_color_map ()
1538 {
1539         /* These are "standard" colors that Ableton docs suggest will always be
1540            there. Put them in our color map so that when we look up these
1541            colors, we will use the Ableton indices for them.
1542         */
1543
1544         color_map.insert (make_pair (RGB_TO_UINT (0,0,0), 0));
1545         color_map.insert (make_pair (RGB_TO_UINT (204,204,204), 122));
1546         color_map.insert (make_pair (RGB_TO_UINT (64,64,64), 123));
1547         color_map.insert (make_pair (RGB_TO_UINT (20,20,20), 124));
1548         color_map.insert (make_pair (RGB_TO_UINT (0,0,255), 125));
1549         color_map.insert (make_pair (RGB_TO_UINT (0,255,0), 126));
1550         color_map.insert (make_pair (RGB_TO_UINT (255,0,0), 127));
1551
1552         for (uint8_t n = 1; n < 122; ++n) {
1553                 color_map_free_list.push (n);
1554         }
1555 }
1556
1557 void
1558 Push2::fill_color_table ()
1559 {
1560         colors.insert (make_pair (DarkBackground, ArdourCanvas::rgba_to_color (0, 0, 0, 1)));
1561         colors.insert (make_pair (LightBackground, ArdourCanvas::rgba_to_color (0.98, 0.98, 0.98, 1)));
1562
1563         colors.insert (make_pair (ParameterName, ArdourCanvas::rgba_to_color (0.98, 0.98, 0.98, 1)));
1564
1565         colors.insert (make_pair (KnobArcBackground, ArdourCanvas::rgba_to_color (0.3, 0.3, 0.3, 1.0)));
1566         colors.insert (make_pair (KnobArcStart, ArdourCanvas::rgba_to_color (1.0, 0.0, 0.0, 1.0)));
1567         colors.insert (make_pair (KnobArcEnd, ArdourCanvas::rgba_to_color (0.0, 1.0, 0.0, 1.0)));
1568
1569         colors.insert (make_pair (KnobLineShadow, ArdourCanvas::rgba_to_color  (0, 0, 0, 0.3)));
1570         colors.insert (make_pair (KnobLine, ArdourCanvas::rgba_to_color (1, 1, 1, 1)));
1571
1572         colors.insert (make_pair (KnobForeground, ArdourCanvas::rgba_to_color (0.2, 0.2, 0.2, 1)));
1573         colors.insert (make_pair (KnobBackground, ArdourCanvas::rgba_to_color (0.2, 0.2, 0.2, 1)));
1574         colors.insert (make_pair (KnobShadow, ArdourCanvas::rgba_to_color (0, 0, 0, 0.1)));
1575         colors.insert (make_pair (KnobBorder, ArdourCanvas::rgba_to_color (0, 0, 0, 1)));
1576
1577 }
1578
1579 ArdourCanvas::Color
1580 Push2::get_color (ColorName name)
1581 {
1582         Colors::iterator c = colors.find (name);
1583         if (c != colors.end()) {
1584                 return c->second;
1585         }
1586
1587         return random();
1588 }
1589
1590 void
1591 Push2::set_current_layout (Push2Layout* layout)
1592 {
1593         if (_current_layout) {
1594                 _current_layout->hide ();
1595                 _canvas->root()->remove (_current_layout);
1596                 _previous_layout = _current_layout;
1597         }
1598
1599         /* turn off all strip buttons - let new layout set them if it
1600          * wants/needs to
1601          */
1602
1603         strip_buttons_off ();
1604
1605         _current_layout = layout;
1606
1607         if (_current_layout) {
1608                 _canvas->root()->add (_current_layout);
1609                 _current_layout->show ();
1610         }
1611
1612         _canvas->request_redraw ();
1613 }
1614
1615 void
1616 Push2::use_previous_layout ()
1617 {
1618         if (_previous_layout) {
1619                 set_current_layout (_previous_layout);
1620         }
1621 }
1622
1623 void
1624 Push2::request_pressure_mode ()
1625 {
1626         MidiByteArray msg (8, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x1F, 0xF7);
1627         write (msg);
1628 }
1629
1630 void
1631 Push2::set_pressure_mode (PressureMode pm)
1632 {
1633         MidiByteArray msg (9, 0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x1E, 0x0, 0xF7);
1634
1635         switch (pm) {
1636         case AfterTouch:
1637                 /* nothing to do, message is correct */
1638                 break;
1639         case PolyPressure:
1640                 msg[7] = 0x1;
1641                 break;
1642         default:
1643                 return;
1644         }
1645
1646         write (msg);
1647         cerr << "Sent PM message " << msg << endl;
1648 }