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