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