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