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