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