Mackie Control: Moved encoder fine modifier from Control to Shift (Shift will be...
[ardour.git] / libs / surfaces / mackie / surface.cc
1 /*
2     Copyright (C) 2012 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
20 #include <sstream>
21 #include <iomanip>
22 #include <iostream>
23 #include <cstdio>
24 #include <cmath>
25
26 #include <glibmm/convert.h>
27
28 #include "pbd/stacktrace.h"
29
30 #include "midi++/port.h"
31
32 #include "ardour/audioengine.h"
33 #include "ardour/automation_control.h"
34 #include "ardour/debug.h"
35 #include "ardour/route.h"
36 #include "ardour/panner.h"
37 #include "ardour/panner_shell.h"
38 #include "ardour/profile.h"
39 #include "ardour/rc_configuration.h"
40 #include "ardour/session.h"
41 #include "ardour/utils.h"
42
43 #include <gtkmm2ext/gui_thread.h>
44
45 #include "control_group.h"
46 #include "surface_port.h"
47 #include "surface.h"
48 #include "strip.h"
49 #include "mackie_control_protocol.h"
50 #include "jog_wheel.h"
51
52 #include "strip.h"
53 #include "button.h"
54 #include "led.h"
55 #include "pot.h"
56 #include "fader.h"
57 #include "jog.h"
58 #include "meter.h"
59
60 #include "i18n.h"
61
62 #ifdef PLATFORM_WINDOWS
63 #define random() rand()
64 #endif
65
66 using namespace std;
67 using namespace PBD;
68 using ARDOUR::Route;
69 using ARDOUR::Panner;
70 using ARDOUR::Profile;
71 using ARDOUR::AutomationControl;
72 using namespace ArdourSurface;
73 using namespace Mackie;
74
75 #define ui_context() MackieControlProtocol::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
76
77 // The MCU sysex header.4th byte Will be overwritten
78 // when we get an incoming sysex that identifies
79 // the device type
80 static MidiByteArray mackie_sysex_hdr  (5, MIDI::sysex, 0x0, 0x0, 0x66, 0x14);
81
82 // The MCU extender sysex header.4th byte Will be overwritten
83 // when we get an incoming sysex that identifies
84 // the device type
85 static MidiByteArray mackie_sysex_hdr_xt  (5, MIDI::sysex, 0x0, 0x0, 0x66, 0x15);
86
87 static MidiByteArray empty_midi_byte_array;
88
89 Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, uint32_t number, surface_type_t stype)
90         : _mcp (mcp)
91         , _stype (stype)
92         , _number (number)
93         , _name (device_name)
94         , _active (false)
95         , _connected (false)
96         , _jog_wheel (0)
97         , _master_fader (0)
98         , _last_master_gain_written (-0.0f)
99         , connection_state (0)
100         , input_source (0)
101 {
102         DEBUG_TRACE (DEBUG::MackieControl, "Surface::Surface init\n");
103
104         try {
105                 _port = new SurfacePort (*this);
106         } catch (...) {
107                 throw failed_constructor ();
108         }
109
110         /* only the first Surface object has global controls */
111         /* lets use master_position instead */
112         uint32_t mp = _mcp.device_info().master_position();
113         if (_number == mp) {
114                 DEBUG_TRACE (DEBUG::MackieControl, "Surface matches MasterPosition. Might have global controls.\n");
115                 if (_mcp.device_info().has_global_controls()) {
116                         init_controls ();
117                         DEBUG_TRACE (DEBUG::MackieControl, "init_controls done\n");
118                 }
119
120                 if (_mcp.device_info().has_master_fader()) {
121                         setup_master ();
122                         DEBUG_TRACE (DEBUG::MackieControl, "setup_master done\n");
123                 }
124         }
125
126         uint32_t n = _mcp.device_info().strip_cnt();
127
128         if (n) {
129                 init_strips (n);
130                 DEBUG_TRACE (DEBUG::MackieControl, "init_strips done\n");
131         }
132
133         if (_mcp.device_info().uses_ipmidi()) {
134                 /* ipMIDI port already exists, we can just assume that we're
135                  * connected.
136                  *
137                  * If the user still hasn't connected the ipMIDI surface and/or
138                  * turned it on, then they have to press "Discover Mackie
139                  * Devices" in the GUI at the right time.
140                  */
141
142                 connection_state |= (InputConnected|OutputConnected);
143                 connected ();
144         }
145
146         connect_to_signals ();
147
148         DEBUG_TRACE (DEBUG::MackieControl, "Surface::Surface done\n");
149 }
150
151 Surface::~Surface ()
152 {
153         DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface init\n");
154
155         if (input_source) {
156                 g_source_destroy (input_source);
157                 input_source = 0;
158         }
159
160         // delete groups (strips)
161         for (Groups::iterator it = groups.begin(); it != groups.end(); ++it) {
162                 delete it->second;
163         }
164
165         // delete controls (global buttons, master fader etc)
166         for (Controls::iterator it = controls.begin(); it != controls.end(); ++it) {
167                 delete *it;
168         }
169
170         delete _jog_wheel;
171         delete _port;
172         // the ports take time to release and we may be rebuilding right away
173         // in the case of changing devices.
174         g_usleep (10000);
175         DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface done\n");
176 }
177
178 bool
179 Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
180 {
181         if (!_port) {
182                 return false;
183         }
184
185         string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->input_name());
186         string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->output_name());
187
188         if (ni == name1 || ni == name2) {
189                 if (yn) {
190                         connection_state |= InputConnected;
191                 } else {
192                         connection_state &= ~InputConnected;
193                 }
194         } else if (no == name1 || no == name2) {
195                 if (yn) {
196                         connection_state |= OutputConnected;
197                 } else {
198                         connection_state &= ~OutputConnected;
199                 }
200         } else {
201                 /* not our ports */
202                 return false;
203         }
204
205         if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
206
207                 /* this will send a device query message, which should
208                    result in a response that will kick off device type
209                    discovery and activation of the surface(s).
210
211                    The intended order of events is:
212
213                    - each surface sends a device query message
214                    - devices respond with either MCP or LCP response (sysex in both
215                    cases)
216                    - sysex message causes Surface::turn_it_on() which tells the
217                    MCP object that the surface is ready, and sets up strip
218                    displays and binds faders and buttons for that surface
219
220                    In the case of LCP, where this is a handshake process that could
221                    fail, the response process to the initial sysex after a device query
222                    will mark the surface inactive, which won't shut anything down
223                    but will stop any writes to the device.
224
225                    Note: there are no known cases of the handshake process failing.
226
227                    We actually can't initiate this in this callback, so we have
228                    to queue it with the MCP event loop.
229                 */
230
231                 /* XXX this is a horrible hack. Without a short sleep here,
232                    something prevents the device wakeup messages from being
233                    sent and/or the responses from being received.
234                 */
235
236                 g_usleep (100000);
237                 connected ();
238
239         } else {
240                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 disconnected (input or output or both)\n", _name));
241                 _active = false;
242         }
243
244         return true; /* connection status changed */
245 }
246
247 XMLNode&
248 Surface::get_state()
249 {
250         XMLNode* node = new XMLNode (X_("Surface"));
251         node->add_property (X_("name"), _name);
252         node->add_child_nocopy (_port->get_state());
253         return *node;
254 }
255
256 int
257 Surface::set_state (const XMLNode& node, int version)
258 {
259         /* Look for a node named after the device we're part of */
260
261         XMLNodeList const& children = node.children();
262         XMLNode* mynode = 0;
263
264         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
265                 XMLProperty const* prop = (*c)->property (X_("name"));
266                 if (prop) {
267                         if (prop->value() == _name) {
268                                 mynode = *c;
269                                 break;
270                         }
271                 }
272         }
273
274         if (!mynode) {
275                 return 0;
276         }
277
278         XMLNode* portnode = mynode->child (X_("Port"));
279         if (portnode) {
280                 if (_port->set_state (*portnode, version)) {
281                         return -1;
282                 }
283         }
284
285         return 0;
286 }
287
288 const MidiByteArray&
289 Surface::sysex_hdr() const
290 {
291         switch  (_stype) {
292         case mcu: return mackie_sysex_hdr;
293         case ext: return mackie_sysex_hdr_xt;
294         }
295         cout << "SurfacePort::sysex_hdr _port_type not known" << endl;
296         return mackie_sysex_hdr;
297 }
298
299 static GlobalControlDefinition mackie_global_controls[] = {
300         { "external", Pot::External, Pot::factory, "none" },
301         { "fader_touch", Led::FaderTouch, Led::factory, "master" },
302         { "timecode", Led::Timecode, Led::factory, "none" },
303         { "beats", Led::Beats, Led::factory, "none" },
304         { "solo", Led::RudeSolo, Led::factory, "none" },
305         { "relay_click", Led::RelayClick, Led::factory, "none" },
306         { "", 0, Led::factory, "" }
307 };
308
309 void
310 Surface::init_controls()
311 {
312         Group* group;
313
314         DEBUG_TRACE (DEBUG::MackieControl, "Surface::init_controls: creating groups\n");
315         groups["assignment"] = new Group  ("assignment");
316         groups["automation"] = new Group  ("automation");
317         groups["bank"] = new Group  ("bank");
318         groups["cursor"] = new Group  ("cursor");
319         groups["display"] = new Group  ("display");
320         groups["function select"] = new Group  ("function select");
321         groups["global view"] = new Group ("global view");
322         groups["master"] = new Group ("master");
323         groups["modifiers"] = new Group  ("modifiers");
324         groups["none"] = new Group  ("none");
325         groups["transport"] = new Group  ("transport");
326         groups["user"] = new Group  ("user");
327         groups["utilities"] = new Group  ("utilities");
328
329         DEBUG_TRACE (DEBUG::MackieControl, "Surface::init_controls: creating jog wheel\n");
330         if (_mcp.device_info().has_jog_wheel()) {
331                 _jog_wheel = new Mackie::JogWheel (_mcp);
332         }
333
334         DEBUG_TRACE (DEBUG::MackieControl, "Surface::init_controls: creating global controls\n");
335         for (uint32_t n = 0; mackie_global_controls[n].name[0]; ++n) {
336                 group = groups[mackie_global_controls[n].group_name];
337                 Control* control = mackie_global_controls[n].factory (*this, mackie_global_controls[n].id, mackie_global_controls[n].name, *group);
338                 controls_by_device_independent_id[mackie_global_controls[n].id] = control;
339         }
340
341         /* add global buttons */
342         DEBUG_TRACE (DEBUG::MackieControl, "Surface::init_controls: adding global buttons\n");
343         const map<Button::ID,GlobalButtonInfo>& global_buttons (_mcp.device_info().global_buttons());
344
345         for (map<Button::ID,GlobalButtonInfo>::const_iterator b = global_buttons.begin(); b != global_buttons.end(); ++b){
346                 group = groups[b->second.group];
347                 controls_by_device_independent_id[b->first] = Button::factory (*this, b->first, b->second.id, b->second.label, *group);
348         }
349 }
350
351 void
352 Surface::init_strips (uint32_t n)
353 {
354         const map<Button::ID,StripButtonInfo>& strip_buttons (_mcp.device_info().strip_buttons());
355
356         for (uint32_t i = 0; i < n; ++i) {
357
358                 char name[32];
359
360                 snprintf (name, sizeof (name), "strip_%d", (8* _number) + i);
361
362                 Strip* strip = new Strip (*this, name, i, strip_buttons);
363
364                 groups[name] = strip;
365                 strips.push_back (strip);
366         }
367 }
368
369 void
370 Surface::master_monitor_may_have_changed ()
371 {
372         if (_number == _mcp.device_info().master_position()) {
373                 setup_master ();
374         }
375 }
376
377 void
378 Surface::setup_master ()
379 {
380         boost::shared_ptr<Route> m;
381
382         if ((m = _mcp.get_session().monitor_out()) == 0) {
383                 m = _mcp.get_session().master_out();
384         }
385
386         if (!m) {
387                 _master_fader->set_control (boost::shared_ptr<AutomationControl>());
388                 master_connection.disconnect ();
389                 return;
390         }
391
392         if (!_master_fader) {
393                 _master_fader = dynamic_cast<Fader*> (Fader::factory (*this, _mcp.device_info().strip_cnt(), "master", *groups["master"]));
394
395                 Groups::iterator group_it;
396                 group_it = groups.find("master");
397
398                 DeviceInfo device_info = _mcp.device_info();
399                 GlobalButtonInfo master_button = device_info.get_global_button(Button::MasterFaderTouch);
400                 Button* bb = dynamic_cast<Button*> (Button::factory (
401                                                             *this,
402                                                             Button::MasterFaderTouch,
403                                                             master_button.id,
404                                                             master_button.label,
405                                                             *(group_it->second)
406                                                             ));
407
408                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface %1 Master Fader new button BID %2 id %3\n",
409                                                                    number(), Button::MasterFaderTouch, bb->id()));
410         } else {
411                 master_connection.disconnect ();
412         }
413
414         _master_fader->set_control (m->gain_control());
415         m->gain_control()->Changed.connect (master_connection, MISSING_INVALIDATOR, boost::bind (&Surface::master_gain_changed, this), ui_context());
416         _last_master_gain_written = FLT_MAX; /* some essentially impossible value */
417         master_gain_changed ();
418 }
419
420 void
421 Surface::master_gain_changed ()
422 {
423         if (!_master_fader) {
424                 return;
425         }
426
427         boost::shared_ptr<AutomationControl> ac = _master_fader->control();
428         if (!ac) {
429                 return;
430         }
431
432         float normalized_position = ac->internal_to_interface (ac->get_value());
433         if (normalized_position == _last_master_gain_written) {
434                 return;
435         }
436
437         DEBUG_TRACE (DEBUG::MackieControl, "Surface::master_gain_changed: updating surface master fader\n");
438
439         _port->write (_master_fader->set_position (normalized_position));
440         _last_master_gain_written = normalized_position;
441 }
442
443 float
444 Surface::scaled_delta (float delta, float current_speed)
445 {
446         /* XXX needs work before use */
447         const float sign = delta < 0.0 ? -1.0 : 1.0;
448
449         return ((sign * std::pow (delta + 1.0, 2.0)) + current_speed) / 100.0;
450 }
451
452 void
453 Surface::display_bank_start (uint32_t current_bank)
454 {
455         if  (current_bank == 0) {
456                 // send Ar. to 2-char display on the master
457                 show_two_char_display ("Ar", "..");
458         } else {
459                 // write the current first remote_id to the 2-char display
460                 show_two_char_display (current_bank);
461         }
462 }
463
464 void
465 Surface::blank_jog_ring ()
466 {
467         Control* control = controls_by_device_independent_id[Jog::ID];
468
469         if (control) {
470                 Pot* pot = dynamic_cast<Pot*> (control);
471                 if (pot) {
472                         _port->write (pot->set (0.0, false, Pot::spread));
473                 }
474         }
475 }
476
477 float
478 Surface::scrub_scaling_factor () const
479 {
480         return 100.0;
481 }
482
483 void
484 Surface::connect_to_signals ()
485 {
486         if (!_connected) {
487
488
489                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 connecting to signals on port %2\n",
490                                                                    number(), _port->input_port().name()));
491
492                 MIDI::Parser* p = _port->input_port().parser();
493
494                 /* Incoming sysex */
495                 p->sysex.connect_same_thread (*this, boost::bind (&Surface::handle_midi_sysex, this, _1, _2, _3));
496                 /* V-Pot messages are Controller */
497                 p->controller.connect_same_thread (*this, boost::bind (&Surface::handle_midi_controller_message, this, _1, _2));
498                 /* Button messages are NoteOn */
499                 p->note_on.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
500                 /* Button messages are NoteOn but libmidi++ sends note-on w/velocity = 0 as note-off so catch them too */
501                 p->note_off.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
502                 /* Fader messages are Pitchbend */
503                 uint32_t i;
504                 for (i = 0; i < _mcp.device_info().strip_cnt(); i++) {
505                         p->channel_pitchbend[i].connect_same_thread (*this, boost::bind (&Surface::handle_midi_pitchbend_message, this, _1, _2, i));
506                 }
507                 // Master fader
508                 p->channel_pitchbend[_mcp.device_info().strip_cnt()].connect_same_thread (*this, boost::bind (&Surface::handle_midi_pitchbend_message, this, _1, _2, _mcp.device_info().strip_cnt()));
509
510                 _connected = true;
511         }
512 }
513
514 void
515 Surface::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uint32_t fader_id)
516 {
517         /* Pitchbend messages are fader position messages. Nothing in the data we get
518          * from the MIDI::Parser conveys the fader ID, which was given by the
519          * channel ID in the status byte.
520          *
521          * Instead, we have used bind() to supply the fader-within-strip ID
522          * when we connected to the per-channel pitchbend events.
523          */
524
525         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface::handle_midi_pitchbend_message on port %3, fader = %1 value = %2 (%4)\n",
526                                                            fader_id, pb, _number, pb/16384.0));
527
528         if (_mcp.device_info().no_handshake()) {
529                 turn_it_on ();
530         }
531
532         Fader* fader = faders[fader_id];
533
534         if (fader) {
535                 Strip* strip = dynamic_cast<Strip*> (&fader->group());
536                 float pos = pb / 16384.0;
537                 if (strip) {
538                         strip->handle_fader (*fader, pos);
539                 } else {
540                         DEBUG_TRACE (DEBUG::MackieControl, "Handling master fader\n");
541                         /* master fader */
542                         fader->set_value (pos); // alter master gain
543                         _port->write (fader->set_position (pos)); // write back value (required for servo)
544                 }
545         } else {
546                 DEBUG_TRACE (DEBUG::MackieControl, "fader not found\n");
547         }
548 }
549
550 void
551 Surface::handle_midi_note_on_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
552 {
553         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface::handle_midi_note_on_message %1 = %2\n", (int) ev->note_number, (int) ev->velocity));
554
555         if (_mcp.device_info().no_handshake()) {
556                 turn_it_on ();
557         }
558
559         if (_mcp.device_info().device_type() == DeviceInfo::HUI && ev->note_number == 0 && ev->velocity == 127) {
560                 turn_it_on ();
561         }
562
563         /* fader touch sense is given by "buttons" 0xe..0xe7 and 0xe8 for the
564          * master.
565          */
566
567         if (ev->note_number >= 0xE0 && ev->note_number <= 0xE8) {
568                 Fader* fader = faders[ev->note_number];
569
570                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface: fader touch message, fader = %1\n", fader));
571
572                 if (fader) {
573
574                         Strip* strip = dynamic_cast<Strip*> (&fader->group());
575
576                         if (ev->velocity > 64) {
577                                 strip->handle_fader_touch (*fader, true);
578                         } else {
579                                 strip->handle_fader_touch (*fader, false);
580                         }
581                 }
582                 return;
583         }
584
585         Button* button = buttons[ev->note_number];
586
587         if (button) {
588
589                 if (ev->velocity > 64) {
590                         button->pressed ();
591                 }
592
593                 Strip* strip = dynamic_cast<Strip*> (&button->group());
594
595                 if (strip) {
596                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 button %2 pressed ? %3\n",
597                                                                            strip->index(), button->name(), (ev->velocity > 64)));
598                         strip->handle_button (*button, ev->velocity > 64 ? press : release);
599                 } else {
600                         /* global button */
601                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("global button %1\n", button->id()));
602                         _mcp.handle_button_event (*this, *button, ev->velocity > 64 ? press : release);
603                 }
604
605                 if (ev->velocity <= 64) {
606                         button->released ();
607                 }
608
609         } else {
610                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("no button found for %1\n", (int) ev->note_number));
611         }
612
613         /* button release should reset timer AFTER handler(s) have run */
614 }
615
616 void
617 Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
618 {
619         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("SurfacePort::handle_midi_controller %1 = %2\n", (int) ev->controller_number, (int) ev->value));
620
621         if (_mcp.device_info().no_handshake()) {
622                 turn_it_on ();
623         }
624
625         Pot* pot = pots[ev->controller_number];
626
627         // bit 6 gives the sign
628         float sign = (ev->value & 0x40) == 0 ? 1.0 : -1.0;
629         // bits 0..5 give the velocity. we interpret this as "ticks
630         // moved before this message was sent"
631         float ticks = (ev->value & 0x3f);
632         if (ticks == 0) {
633                 /* euphonix and perhaps other devices send zero
634                    when they mean 1, we think.
635                 */
636                 ticks = 1;
637         }
638
639         float delta = 0;
640         if (mcp().main_modifier_state() == MackieControlProtocol::MODIFIER_SHIFT) {
641                 delta = sign * (ticks / (float) 0xff);
642         } else {
643                 delta = sign * (ticks / (float) 0x3f);
644         }
645
646         if (!pot) {
647                 if (ev->controller_number == Jog::ID && _jog_wheel) {
648
649                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Jog wheel moved %1\n", ticks));
650                         _jog_wheel->jog_event (delta);
651                         return;
652                 }
653                 // add external (pedal?) control here
654
655                 return;
656         }
657
658         Strip* strip = dynamic_cast<Strip*> (&pot->group());
659         if (strip) {
660                 strip->handle_pot (*pot, delta);
661         }
662 }
663
664 void
665 Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count)
666 {
667         MidiByteArray bytes (count, raw_bytes);
668
669         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handle_midi_sysex: %1\n", bytes));
670
671         if (_mcp.device_info().no_handshake()) {
672                 turn_it_on ();
673         }
674
675         /* always save the device type ID so that our outgoing sysex messages
676          * are correct
677          */
678
679         if (_stype == mcu) {
680                 mackie_sysex_hdr[4] = bytes[4];
681         } else {
682                 mackie_sysex_hdr_xt[4] = bytes[4];
683         }
684
685         switch (bytes[5]) {
686         case 0x01:
687                 /* MCP: Device Ready
688                    LCP: Connection Challenge
689                 */
690                 if (bytes[4] == 0x10 || bytes[4] == 0x11) {
691                         DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device connection challenge\n");
692                         write_sysex (host_connection_query (bytes));
693                 } else {
694                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mackie Control Device ready, current status = %1\n", _active));
695                         turn_it_on ();
696                 }
697                 break;
698
699         case 0x03: /* LCP Connection Confirmation */
700                 DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device confirms connection, ardour replies\n");
701                 if (bytes[4] == 0x10 || bytes[4] == 0x11) {
702                         write_sysex (host_connection_confirmation (bytes));
703                         turn_it_on ();
704                 }
705                 break;
706
707         case 0x04: /* LCP: Confirmation Denied */
708                 DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device denies connection\n");
709                 _active = false;
710                 break;
711         default:
712                 error << "MCP: unknown sysex: " << bytes << endmsg;
713         }
714 }
715
716 static MidiByteArray
717 calculate_challenge_response (MidiByteArray::iterator begin, MidiByteArray::iterator end)
718 {
719         MidiByteArray l;
720         back_insert_iterator<MidiByteArray> back  (l);
721         copy (begin, end, back);
722
723         MidiByteArray retval;
724
725         // this is how to calculate the response to the challenge.
726         // from the Logic docs.
727         retval <<  (0x7f &  (l[0] +  (l[1] ^ 0xa) - l[3]));
728         retval <<  (0x7f &  ( (l[2] >> l[3]) ^  (l[0] + l[3])));
729         retval <<  (0x7f &  ((l[3] -  (l[2] << 2)) ^  (l[0] | l[1])));
730         retval <<  (0x7f &  (l[1] - l[2] +  (0xf0 ^  (l[3] << 4))));
731
732         return retval;
733 }
734
735 MidiByteArray
736 Surface::host_connection_query (MidiByteArray & bytes)
737 {
738         MidiByteArray response;
739
740         if (bytes[4] != 0x10 && bytes[4] != 0x11) {
741                 /* not a Logic Control device - no response required */
742                 return response;
743         }
744
745         // handle host connection query
746         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host connection query: %1\n", bytes));
747
748         if  (bytes.size() != 18) {
749                 cerr << "expecting 18 bytes, read " << bytes << " from " << _port->input_port().name() << endl;
750                 return response;
751         }
752
753         // build and send host connection reply
754         response << 0x02;
755         copy (bytes.begin() + 6, bytes.begin() + 6 + 7, back_inserter (response));
756         response << calculate_challenge_response (bytes.begin() + 6 + 7, bytes.begin() + 6 + 7 + 4);
757         return response;
758 }
759
760 MidiByteArray
761 Surface::host_connection_confirmation (const MidiByteArray & bytes)
762 {
763         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host_connection_confirmation: %1\n", bytes));
764
765         // decode host connection confirmation
766         if  (bytes.size() != 14) {
767                 ostringstream os;
768                 os << "expecting 14 bytes, read " << bytes << " from " << _port->input_port().name();
769                 throw MackieControlException (os.str());
770         }
771
772         // send version request
773         return MidiByteArray (2, 0x13, 0x00);
774 }
775
776 void
777 Surface::turn_it_on ()
778 {
779         if (_active) {
780                 return;
781         }
782
783         _active = true;
784
785         _mcp.device_ready ();
786
787         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
788                 (*s)->notify_all ();
789         }
790
791         update_view_mode_display (false);
792
793 //      if (_mcp.device_info ().has_global_controls ()) {
794 //              _mcp.update_global_button (Button::Read, _mcp.metering_active ());
795 //      }
796 }
797
798 void
799 Surface::write_sysex (const MidiByteArray & mba)
800 {
801         if (mba.empty()) {
802                 return;
803         }
804
805         MidiByteArray buf;
806         buf << sysex_hdr() << mba << MIDI::eox;
807         _port->write (buf);
808 }
809
810 void
811 Surface::write_sysex (MIDI::byte msg)
812 {
813         MidiByteArray buf;
814         buf << sysex_hdr() << msg << MIDI::eox;
815         _port->write (buf);
816 }
817
818 uint32_t
819 Surface::n_strips (bool with_locked_strips) const
820 {
821         if (with_locked_strips) {
822                 return strips.size();
823         }
824
825         uint32_t n = 0;
826
827         for (Strips::const_iterator it = strips.begin(); it != strips.end(); ++it) {
828                 if (!(*it)->locked()) {
829                         ++n;
830                 }
831         }
832         return n;
833 }
834
835 Strip*
836 Surface::nth_strip (uint32_t n) const
837 {
838         if (n > n_strips()) {
839                 return 0;
840         }
841         return strips[n];
842 }
843
844 void
845 Surface::zero_all ()
846 {
847         if (_mcp.device_info().has_timecode_display ()) {
848                 display_timecode (string (10, '0'), string (10, ' '));
849         }
850
851         if (_mcp.device_info().has_two_character_display()) {
852                 show_two_char_display (string (2, '0'), string (2, ' '));
853         }
854
855         if (_mcp.device_info().has_master_fader () && _master_fader) {
856                 _port->write (_master_fader->zero ());
857         }
858
859         // zero all strips
860         for (Strips::iterator it = strips.begin(); it != strips.end(); ++it) {
861                 (*it)->zero();
862         }
863
864         zero_controls ();
865 }
866
867 void
868 Surface::zero_controls ()
869 {
870         if (!_mcp.device_info().has_global_controls()) {
871                 return;
872         }
873
874         // turn off global buttons and leds
875
876         for (Controls::iterator it = controls.begin(); it != controls.end(); ++it) {
877                 Control & control = **it;
878                 if (!control.group().is_strip()) {
879                         _port->write (control.zero());
880                 }
881         }
882
883         // and the led ring for the master strip
884         blank_jog_ring ();
885
886         _last_master_gain_written = 0.0f;
887 }
888
889 void
890 Surface::periodic (uint64_t now_usecs)
891 {
892         master_gain_changed();
893         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
894                 (*s)->periodic (now_usecs);
895         }
896 }
897
898 void
899 Surface::redisplay (ARDOUR::microseconds_t now, bool force)
900 {
901         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
902                 (*s)->redisplay (now, force);
903         }
904 }
905
906 void
907 Surface::write (const MidiByteArray& data)
908 {
909         if (_active) {
910                 _port->write (data);
911         } else {
912                 DEBUG_TRACE (DEBUG::MackieControl, "surface not active, write ignored\n");
913         }
914 }
915
916 void
917 Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
918 {
919         vector<boost::shared_ptr<Route> >::const_iterator r;
920         Strips::iterator s = strips.begin();
921
922         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mapping %1 routes\n", routes.size()));
923
924         for (r = routes.begin(); r != routes.end() && s != strips.end(); ++s) {
925
926                 /* don't try to assign routes to a locked strip. it won't
927                    use it anyway, but if we do, then we get out of sync
928                    with the proposed mapping.
929                 */
930
931                 if (!(*s)->locked()) {
932                         (*s)->set_route (*r);
933                         ++r;
934                 }
935         }
936
937         for (; s != strips.end(); ++s) {
938                 (*s)->set_route (boost::shared_ptr<Route>());
939         }
940 }
941
942 static char
943 translate_seven_segment (char achar)
944 {
945         achar = toupper (achar);
946
947         if  (achar >= 0x40 && achar <= 0x60) {
948                 return achar - 0x40;
949         } else if  (achar >= 0x21 && achar <= 0x3f) {
950                 return achar;
951         } else {
952                 return 0x00;
953         }
954 }
955
956 void
957 Surface::show_two_char_display (const std::string & msg, const std::string & dots)
958 {
959         if (_stype != mcu || !_mcp.device_info().has_two_character_display() || msg.length() != 2 || dots.length() != 2) {
960                 return;
961         }
962
963         MidiByteArray right (3, 0xb0, 0x4b, 0x00);
964         MidiByteArray left (3, 0xb0, 0x4a, 0x00);
965
966         right[2] = translate_seven_segment (msg[0]) +  (dots[0] == '.' ? 0x40 : 0x00);
967         left[2] = translate_seven_segment (msg[1]) +  (dots[1] == '.' ? 0x40 : 0x00);
968
969         _port->write (right);
970         _port->write (left);
971 }
972
973 void
974 Surface::show_two_char_display (unsigned int value, const std::string & /*dots*/)
975 {
976         ostringstream os;
977         os << setfill('0') << setw(2) << value % 100;
978         show_two_char_display (os.str());
979 }
980
981 void
982 Surface::display_timecode (const std::string & timecode, const std::string & last_timecode)
983 {
984         if (!_active || !_mcp.device_info().has_timecode_display()) {
985                 return;
986         }
987         // if there's no change, send nothing, not even sysex header
988         if  (timecode == last_timecode) return;
989
990         // length sanity checking
991         string local_timecode = timecode;
992
993         // truncate to 10 characters
994         if  (local_timecode.length() > 10) {
995                 local_timecode = local_timecode.substr (0, 10);
996         }
997
998         // pad to 10 characters
999         while  (local_timecode.length() < 10) {
1000                 local_timecode += " ";
1001         }
1002
1003         // translate characters.
1004         // Only the characters that actually changed are sent.
1005         int position = 0x3f;
1006         int i;
1007         for (i = local_timecode.length () - 1; i >= 0; i--) {
1008                 position++;
1009                 if (local_timecode[i] == last_timecode[i]) {
1010                         continue;
1011                 }
1012                 MidiByteArray retval (2, 0xb0, position);
1013                 retval << translate_seven_segment (local_timecode[i]);
1014                 _port->write (retval);
1015         }
1016 }
1017
1018 void
1019 Surface::update_flip_mode_display ()
1020 {
1021         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1022                 (*s)->flip_mode_changed ();
1023         }
1024 }
1025
1026 void
1027 Surface::subview_mode_changed ()
1028 {
1029         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1030                 (*s)->subview_mode_changed ();
1031         }
1032 }
1033
1034 void
1035 Surface::update_view_mode_display (bool with_helpful_text)
1036 {
1037         string text;
1038         int id = -1;
1039
1040         if (!_active) {
1041                 return;
1042         }
1043
1044         switch (_mcp.view_mode()) {
1045         case MackieControlProtocol::Mixer:
1046                 show_two_char_display ("Mx");
1047                 id = Button::View;
1048                 text = _("Mixer View");
1049                 break;
1050         case MackieControlProtocol::AudioTracks:
1051                 show_two_char_display ("AT");
1052                 id = Button::AudioTracks;
1053                 text = _("Audio Tracks");
1054                 break;
1055         case MackieControlProtocol::MidiTracks:
1056                 show_two_char_display ("MT");
1057                 id = Button::MidiTracks;
1058                 text = _("MIDI Tracks");
1059                 break;
1060         case MackieControlProtocol::Plugins:
1061                 show_two_char_display ("PL");
1062                 id = Button::Plugin;
1063                 text = _("Plugins");
1064                 break;
1065         case MackieControlProtocol::Busses:
1066                 show_two_char_display ("BS");
1067                 id = Button::Busses;
1068                 if (Profile->get_mixbus()) {
1069                         text = _("Mixbusses");
1070                 } else {
1071                         text = _("Busses");
1072                 }
1073                 break;
1074         case MackieControlProtocol::Auxes:
1075                 show_two_char_display ("Au");
1076                 id = Button::Aux;
1077                 text = _("Auxes");
1078                 break;
1079         case MackieControlProtocol::Hidden:
1080                 show_two_char_display ("HI");
1081                 id = Button::Outputs;
1082                 text = _("Hidden Tracks");
1083                 break;
1084         case MackieControlProtocol::Selected:
1085                 show_two_char_display ("SE");
1086                 id = Button::User;
1087                 text = _("Selected Tracks");
1088                 break;
1089         default:
1090                 break;
1091         }
1092
1093         vector<int> view_mode_buttons;
1094         view_mode_buttons.push_back (Button::View);
1095         view_mode_buttons.push_back (Button::Busses);
1096         view_mode_buttons.push_back (Button::Plugin);
1097         view_mode_buttons.push_back (Button::AudioTracks);
1098         view_mode_buttons.push_back (Button::MidiTracks);
1099         view_mode_buttons.push_back (Button::Aux);
1100         view_mode_buttons.push_back (Button::Outputs);
1101         view_mode_buttons.push_back (Button::User);
1102
1103         if (id >= 0) {
1104
1105                 for (vector<int>::iterator i = view_mode_buttons.begin(); i != view_mode_buttons.end(); ++i) {
1106                         map<int,Control*>::iterator x = controls_by_device_independent_id.find (id);
1107
1108                         if (x != controls_by_device_independent_id.end()) {
1109                                 Button* button = dynamic_cast<Button*> (x->second);
1110                                 if (button) {
1111                                         bool onoff;
1112                                         onoff = (*i) == id;
1113
1114                                         _port->write (button->set_state (onoff));
1115                                 }
1116                         }
1117                 }
1118         }
1119
1120         if (with_helpful_text && !text.empty()) {
1121                 display_message_for (text, 1000);
1122         }
1123 }
1124
1125 void
1126 Surface::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& routes)
1127 {
1128         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1129                 (*s)->gui_selection_changed (routes);
1130         }
1131 }
1132
1133 void
1134 Surface::say_hello ()
1135 {
1136         /* wakeup for Mackie Control */
1137         MidiByteArray wakeup (7, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x00, MIDI::eox);
1138         _port->write (wakeup);
1139         wakeup[4] = 0x15; /* wakup Mackie XT */
1140         _port->write (wakeup);
1141         wakeup[4] = 0x10; /* wakeup Logic Control */
1142         _port->write (wakeup);
1143         wakeup[4] = 0x11; /* wakeup Logic Control XT */
1144         _port->write (wakeup);
1145 }
1146
1147 void
1148 Surface::next_jog_mode ()
1149 {
1150 }
1151
1152 void
1153 Surface::set_jog_mode (JogWheel::Mode)
1154 {
1155 }
1156
1157 bool
1158 Surface::route_is_locked_to_strip (boost::shared_ptr<Route> r) const
1159 {
1160         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1161                 if ((*s)->route() == r && (*s)->locked()) {
1162                         return true;
1163                 }
1164         }
1165         return false;
1166 }
1167
1168 bool
1169 Surface::route_is_mapped (boost::shared_ptr<Route> r) const
1170 {
1171         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1172                 if ((*s)->route() == r) {
1173                         return true;
1174                 }
1175         }
1176
1177         return false;
1178 }
1179
1180 void
1181 Surface::notify_metering_state_changed()
1182 {
1183         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1184                 (*s)->notify_metering_state_changed ();
1185         }
1186 }
1187
1188 void
1189 Surface::reset ()
1190 {
1191         if (_port) {
1192                 /* reset msg for Mackie Control */
1193                 MidiByteArray msg;
1194                 msg << sysex_hdr();
1195                 msg << 0x08;
1196                 msg << 0x00;
1197                 msg << MIDI::eox;
1198                 _port->write (msg);
1199         }
1200 }
1201
1202 void
1203 Surface::toggle_backlight ()
1204 {
1205         if (_port) {
1206                 int onoff = random() %2;
1207                 MidiByteArray msg;
1208                 msg << sysex_hdr ();
1209                 msg << 0xa;
1210                 msg << (onoff ? 0x1 : 0x0);
1211                 msg << MIDI::eox;
1212                 _port->write (msg);
1213         }
1214 }
1215
1216 void
1217 Surface::recalibrate_faders ()
1218 {
1219         if (_port) {
1220                 MidiByteArray msg;
1221                 msg << sysex_hdr ();
1222                 msg << 0x09;
1223                 msg << 0x00;
1224                 msg << MIDI::eox;
1225                 _port->write (msg);
1226         }
1227 }
1228
1229 void
1230 Surface::set_touch_sensitivity (int sensitivity)
1231 {
1232         /* NOTE: assumed called from GUI code, hence sleep() */
1233
1234         /* sensitivity already clamped by caller */
1235
1236         if (_port) {
1237                 MidiByteArray msg;
1238
1239                 msg << sysex_hdr ();
1240                 msg << 0x0e;
1241                 msg << 0xff; /* overwritten for each fader below */
1242                 msg << (sensitivity & 0x7f);
1243                 msg << MIDI::eox;
1244
1245                 for (int fader = 0; fader < 9; ++fader) {
1246                         msg[6] = fader;
1247                         _port->write (msg);
1248                 }
1249         }
1250 }
1251
1252 void
1253 Surface::hui_heartbeat ()
1254 {
1255         if (!_port) {
1256                 return;
1257         }
1258
1259         MidiByteArray msg (3, MIDI::on, 0x0, 0x0);
1260         _port->write (msg);
1261 }
1262
1263 void
1264 Surface::connected ()
1265 {
1266         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 now connected, trying to ping device...\n", _name));
1267
1268         say_hello ();
1269
1270         if (_mcp.device_info().no_handshake()) {
1271                 turn_it_on ();
1272         }
1273 }
1274
1275 MidiByteArray
1276 Surface::display_line (string const& msg, int line_num)
1277 {
1278         MidiByteArray midi_msg;
1279         midi_msg << sysex_hdr ();
1280         midi_msg << 0x12;
1281         midi_msg << (line_num ? 0x38 : 0x0); /* offsets into char array
1282                                               * on device that
1283                                               * correspond to line
1284                                               * starts
1285                                               */
1286         if (msg.empty()) {
1287
1288                 midi_msg.insert (midi_msg.end(), 55, ' ');
1289
1290         } else {
1291
1292                 /* ascii data to display. @param msg is UTF-8 which is not legal. */
1293                 string ascii = Glib::convert_with_fallback (msg, "UTF-8", "ISO-8859-1", "_");
1294                 string::size_type len = ascii.length();
1295
1296                 if (len > 55) {
1297                         midi_msg << ascii.substr (0, 55);
1298                 } else {
1299                         midi_msg << ascii;
1300
1301                         for (string::size_type i = len; i < 55; ++i) {
1302                                 midi_msg << ' ';
1303                         }
1304                 }
1305         }
1306
1307         midi_msg << MIDI::eox;
1308
1309         return midi_msg;
1310 }
1311
1312 /** display @param msg on the 55x2 screen for @param msecs milliseconds
1313  *
1314  *  @param msg is assumed to be UTF-8 encoded, and will be converted
1315  *  to ASCII with an underscore as fallback character before being
1316  *  sent to the device.
1317  */
1318 void
1319 Surface::display_message_for (string const& msg, uint64_t msecs)
1320 {
1321         string::size_type newline;
1322
1323         if ((newline = msg.find ('\n')) == string::npos) {
1324
1325                 _port->write (display_line (msg, 0));
1326                 _port->write (display_line (string(), 1));
1327
1328         } else if (newline == 0) {
1329
1330                 _port->write (display_line (string(), 0));
1331                 _port->write (display_line (msg.substr (1), 1));
1332
1333         } else {
1334
1335                 string first_line = msg.substr (0, newline-1);
1336                 string second_line = msg.substr (newline+1);
1337
1338                 _port->write (display_line (first_line, 0));
1339                 _port->write (display_line (second_line.substr (0, second_line.find_first_of ('\n')), 1));
1340         }
1341
1342         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1343                 (*s)->block_screen_display_for (msecs);
1344         }
1345 }