08e78e187057f20fd97515056ef025cb8e179831
[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::setup_master ()
368 {
369         boost::shared_ptr<Route> m;
370
371         if ((m = _mcp.get_session().monitor_out()) == 0) {
372                 m = _mcp.get_session().master_out();
373         }
374
375         if (!m) {
376                 return;
377         }
378
379         _master_fader = dynamic_cast<Fader*> (Fader::factory (*this, _mcp.device_info().strip_cnt(), "master", *groups["master"]));
380
381         _master_fader->set_control (m->gain_control());
382         m->gain_control()->Changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&Surface::master_gain_changed, this), ui_context());
383
384         Groups::iterator group_it;
385         group_it = groups.find("master");
386
387         DeviceInfo device_info = _mcp.device_info();
388         GlobalButtonInfo master_button = device_info.get_global_button(Button::MasterFaderTouch);
389         Button* bb = dynamic_cast<Button*> (Button::factory (
390                 *this,
391                 Button::MasterFaderTouch,
392                 master_button.id,
393                 master_button.label,
394                 *(group_it->second)
395 ));
396         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface %1 Master Fader new button BID %2 id %3\n",
397                 number(), Button::MasterFaderTouch, bb->id()));
398 }
399
400 void
401 Surface::master_gain_changed ()
402 {
403         if (!_master_fader) {
404                 return;
405         }
406
407         boost::shared_ptr<AutomationControl> ac = _master_fader->control();
408         if (!ac) {
409                 return;
410         }
411
412         float normalized_position = ac->internal_to_interface (ac->get_value());
413         if (normalized_position == _last_master_gain_written) {
414                 return;
415         }
416
417         DEBUG_TRACE (DEBUG::MackieControl, "Surface::master_gain_changed: updating surface master fader\n");
418
419         _port->write (_master_fader->set_position (normalized_position));
420         _last_master_gain_written = normalized_position;
421 }
422
423 float
424 Surface::scaled_delta (float delta, float current_speed)
425 {
426         /* XXX needs work before use */
427         const float sign = delta < 0.0 ? -1.0 : 1.0;
428
429         return ((sign * std::pow (delta + 1.0, 2.0)) + current_speed) / 100.0;
430 }
431
432 void
433 Surface::display_bank_start (uint32_t current_bank)
434 {
435         if  (current_bank == 0) {
436                 // send Ar. to 2-char display on the master
437                 show_two_char_display ("Ar", "..");
438         } else {
439                 // write the current first remote_id to the 2-char display
440                 show_two_char_display (current_bank);
441         }
442 }
443
444 void
445 Surface::blank_jog_ring ()
446 {
447         Control* control = controls_by_device_independent_id[Jog::ID];
448
449         if (control) {
450                 Pot* pot = dynamic_cast<Pot*> (control);
451                 if (pot) {
452                         _port->write (pot->set (0.0, false, Pot::spread));
453                 }
454         }
455 }
456
457 float
458 Surface::scrub_scaling_factor () const
459 {
460         return 100.0;
461 }
462
463 void
464 Surface::connect_to_signals ()
465 {
466         if (!_connected) {
467
468
469                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 connecting to signals on port %2\n",
470                                                                    number(), _port->input_port().name()));
471
472                 MIDI::Parser* p = _port->input_port().parser();
473
474                 /* Incoming sysex */
475                 p->sysex.connect_same_thread (*this, boost::bind (&Surface::handle_midi_sysex, this, _1, _2, _3));
476                 /* V-Pot messages are Controller */
477                 p->controller.connect_same_thread (*this, boost::bind (&Surface::handle_midi_controller_message, this, _1, _2));
478                 /* Button messages are NoteOn */
479                 p->note_on.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
480                 /* Button messages are NoteOn but libmidi++ sends note-on w/velocity = 0 as note-off so catch them too */
481                 p->note_off.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
482                 /* Fader messages are Pitchbend */
483                 uint32_t i;
484                 for (i = 0; i < _mcp.device_info().strip_cnt(); i++) {
485                         p->channel_pitchbend[i].connect_same_thread (*this, boost::bind (&Surface::handle_midi_pitchbend_message, this, _1, _2, i));
486                 }
487                 // Master fader
488                 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()));
489
490                 _connected = true;
491         }
492 }
493
494 void
495 Surface::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uint32_t fader_id)
496 {
497         /* Pitchbend messages are fader position messages. Nothing in the data we get
498          * from the MIDI::Parser conveys the fader ID, which was given by the
499          * channel ID in the status byte.
500          *
501          * Instead, we have used bind() to supply the fader-within-strip ID
502          * when we connected to the per-channel pitchbend events.
503          */
504
505         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface::handle_midi_pitchbend_message on port %3, fader = %1 value = %2 (%4)\n",
506                                                            fader_id, pb, _number, pb/16384.0));
507
508         if (_mcp.device_info().no_handshake()) {
509                 turn_it_on ();
510         }
511
512         if (_mcp.main_modifier_state() & MackieControlProtocol::MODIFIER_SHIFT) {
513                 /* user is doing a reset to unity gain but device sends a PB
514                  * message in the middle of the touch on/off messages. Ignore
515                  * it.
516                  */
517                 return;
518         }
519
520         Fader* fader = faders[fader_id];
521
522         if (fader) {
523                 Strip* strip = dynamic_cast<Strip*> (&fader->group());
524                 float pos = pb / 16384.0;
525                 if (strip) {
526                         strip->handle_fader (*fader, pos);
527                 } else {
528                         DEBUG_TRACE (DEBUG::MackieControl, "Handling master fader\n");
529                         /* master fader */
530                         fader->set_value (pos); // alter master gain
531                         _port->write (fader->set_position (pos)); // write back value (required for servo)
532                 }
533         } else {
534                 DEBUG_TRACE (DEBUG::MackieControl, "fader not found\n");
535         }
536 }
537
538 void
539 Surface::handle_midi_note_on_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
540 {
541         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface::handle_midi_note_on_message %1 = %2\n", (int) ev->note_number, (int) ev->velocity));
542
543         if (_mcp.device_info().no_handshake()) {
544                 turn_it_on ();
545         }
546
547         if (_mcp.device_info().device_type() == DeviceInfo::HUI && ev->note_number == 0 && ev->velocity == 127) {
548                 turn_it_on ();
549         }
550
551         /* fader touch sense is given by "buttons" 0xe..0xe7 and 0xe8 for the
552          * master.
553          */
554
555         if (ev->note_number >= 0xE0 && ev->note_number <= 0xE8) {
556                 Fader* fader = faders[ev->note_number];
557
558                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface: fader touch message, fader = %1\n", fader));
559
560                 if (fader) {
561
562                         Strip* strip = dynamic_cast<Strip*> (&fader->group());
563
564                         if (ev->velocity > 64) {
565                                 strip->handle_fader_touch (*fader, true);
566                         } else {
567                                 strip->handle_fader_touch (*fader, false);
568                         }
569                 }
570                 return;
571         }
572
573         Button* button = buttons[ev->note_number];
574
575         if (button) {
576
577                 if (ev->velocity > 64) {
578                         button->pressed ();
579                 }
580
581                 Strip* strip = dynamic_cast<Strip*> (&button->group());
582
583                 if (strip) {
584                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 button %2 pressed ? %3\n",
585                                                                            strip->index(), button->name(), (ev->velocity > 64)));
586                         strip->handle_button (*button, ev->velocity > 64 ? press : release);
587                 } else {
588                         /* global button */
589                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("global button %1\n", button->id()));
590                         _mcp.handle_button_event (*this, *button, ev->velocity > 64 ? press : release);
591                 }
592
593                 if (ev->velocity <= 64) {
594                         button->released ();
595                 }
596
597         } else {
598                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("no button found for %1\n", (int) ev->note_number));
599         }
600
601         /* button release should reset timer AFTER handler(s) have run */
602 }
603
604 void
605 Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
606 {
607         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("SurfacePort::handle_midi_controller %1 = %2\n", (int) ev->controller_number, (int) ev->value));
608
609         if (_mcp.device_info().no_handshake()) {
610                 turn_it_on ();
611         }
612
613         Pot* pot = pots[ev->controller_number];
614
615         // bit 6 gives the sign
616         float sign = (ev->value & 0x40) == 0 ? 1.0 : -1.0;
617         // bits 0..5 give the velocity. we interpret this as "ticks
618         // moved before this message was sent"
619         float ticks = (ev->value & 0x3f);
620         if (ticks == 0) {
621                 /* euphonix and perhaps other devices send zero
622                    when they mean 1, we think.
623                 */
624                 ticks = 1;
625         }
626
627         float delta = 0;
628         if (mcp().main_modifier_state() == MackieControlProtocol::MODIFIER_CONTROL) {
629                 delta = sign * (ticks / (float) 0xff);
630         } else {
631                 delta = sign * (ticks / (float) 0x3f);
632         }
633
634         if (!pot) {
635                 if (ev->controller_number == Jog::ID && _jog_wheel) {
636
637                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Jog wheel moved %1\n", ticks));
638                         _jog_wheel->jog_event (delta);
639                         return;
640                 }
641                 // add external (pedal?) control here
642
643                 return;
644         }
645
646         Strip* strip = dynamic_cast<Strip*> (&pot->group());
647         if (strip) {
648                 strip->handle_pot (*pot, delta);
649         }
650 }
651
652 void
653 Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count)
654 {
655         MidiByteArray bytes (count, raw_bytes);
656
657         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handle_midi_sysex: %1\n", bytes));
658
659         if (_mcp.device_info().no_handshake()) {
660                 turn_it_on ();
661         }
662
663         /* always save the device type ID so that our outgoing sysex messages
664          * are correct
665          */
666
667         if (_stype == mcu) {
668                 mackie_sysex_hdr[4] = bytes[4];
669         } else {
670                 mackie_sysex_hdr_xt[4] = bytes[4];
671         }
672
673         switch (bytes[5]) {
674         case 0x01:
675                 /* MCP: Device Ready
676                    LCP: Connection Challenge
677                 */
678                 if (bytes[4] == 0x10 || bytes[4] == 0x11) {
679                         DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device connection challenge\n");
680                         write_sysex (host_connection_query (bytes));
681                 } else {
682                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mackie Control Device ready, current status = %1\n", _active));
683                         turn_it_on ();
684                 }
685                 break;
686
687         case 0x03: /* LCP Connection Confirmation */
688                 DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device confirms connection, ardour replies\n");
689                 if (bytes[4] == 0x10 || bytes[4] == 0x11) {
690                         write_sysex (host_connection_confirmation (bytes));
691                         turn_it_on ();
692                 }
693                 break;
694
695         case 0x04: /* LCP: Confirmation Denied */
696                 DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device denies connection\n");
697                 _active = false;
698                 break;
699         default:
700                 error << "MCP: unknown sysex: " << bytes << endmsg;
701         }
702 }
703
704 static MidiByteArray
705 calculate_challenge_response (MidiByteArray::iterator begin, MidiByteArray::iterator end)
706 {
707         MidiByteArray l;
708         back_insert_iterator<MidiByteArray> back  (l);
709         copy (begin, end, back);
710
711         MidiByteArray retval;
712
713         // this is how to calculate the response to the challenge.
714         // from the Logic docs.
715         retval <<  (0x7f &  (l[0] +  (l[1] ^ 0xa) - l[3]));
716         retval <<  (0x7f &  ( (l[2] >> l[3]) ^  (l[0] + l[3])));
717         retval <<  (0x7f &  ((l[3] -  (l[2] << 2)) ^  (l[0] | l[1])));
718         retval <<  (0x7f &  (l[1] - l[2] +  (0xf0 ^  (l[3] << 4))));
719
720         return retval;
721 }
722
723 MidiByteArray
724 Surface::host_connection_query (MidiByteArray & bytes)
725 {
726         MidiByteArray response;
727
728         if (bytes[4] != 0x10 && bytes[4] != 0x11) {
729                 /* not a Logic Control device - no response required */
730                 return response;
731         }
732
733         // handle host connection query
734         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host connection query: %1\n", bytes));
735
736         if  (bytes.size() != 18) {
737                 cerr << "expecting 18 bytes, read " << bytes << " from " << _port->input_port().name() << endl;
738                 return response;
739         }
740
741         // build and send host connection reply
742         response << 0x02;
743         copy (bytes.begin() + 6, bytes.begin() + 6 + 7, back_inserter (response));
744         response << calculate_challenge_response (bytes.begin() + 6 + 7, bytes.begin() + 6 + 7 + 4);
745         return response;
746 }
747
748 MidiByteArray
749 Surface::host_connection_confirmation (const MidiByteArray & bytes)
750 {
751         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host_connection_confirmation: %1\n", bytes));
752
753         // decode host connection confirmation
754         if  (bytes.size() != 14) {
755                 ostringstream os;
756                 os << "expecting 14 bytes, read " << bytes << " from " << _port->input_port().name();
757                 throw MackieControlException (os.str());
758         }
759
760         // send version request
761         return MidiByteArray (2, 0x13, 0x00);
762 }
763
764 void
765 Surface::turn_it_on ()
766 {
767         if (_active) {
768                 return;
769         }
770
771         _active = true;
772
773         _mcp.device_ready ();
774
775         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
776                 (*s)->notify_all ();
777         }
778
779         update_view_mode_display ();
780
781         if (_mcp.device_info ().has_global_controls ()) {
782                 _mcp.update_global_button (Button::Read, _mcp.metering_active ());
783         }
784 }
785
786 void
787 Surface::write_sysex (const MidiByteArray & mba)
788 {
789         if (mba.empty()) {
790                 return;
791         }
792
793         MidiByteArray buf;
794         buf << sysex_hdr() << mba << MIDI::eox;
795         _port->write (buf);
796 }
797
798 void
799 Surface::write_sysex (MIDI::byte msg)
800 {
801         MidiByteArray buf;
802         buf << sysex_hdr() << msg << MIDI::eox;
803         _port->write (buf);
804 }
805
806 uint32_t
807 Surface::n_strips (bool with_locked_strips) const
808 {
809         if (with_locked_strips) {
810                 return strips.size();
811         }
812
813         uint32_t n = 0;
814
815         for (Strips::const_iterator it = strips.begin(); it != strips.end(); ++it) {
816                 if (!(*it)->locked()) {
817                         ++n;
818                 }
819         }
820         return n;
821 }
822
823 Strip*
824 Surface::nth_strip (uint32_t n) const
825 {
826         if (n > n_strips()) {
827                 return 0;
828         }
829         return strips[n];
830 }
831
832 void
833 Surface::zero_all ()
834 {
835         if (_mcp.device_info().has_timecode_display ()) {
836                 display_timecode (string (10, '0'), string (10, ' '));
837         }
838
839         if (_mcp.device_info().has_two_character_display()) {
840                 show_two_char_display (string (2, '0'), string (2, ' '));
841         }
842
843         if (_mcp.device_info().has_master_fader () && _master_fader) {
844                 _port->write (_master_fader->zero ());
845         }
846
847         // zero all strips
848         for (Strips::iterator it = strips.begin(); it != strips.end(); ++it) {
849                 (*it)->zero();
850         }
851
852         zero_controls ();
853 }
854
855 void
856 Surface::zero_controls ()
857 {
858         if (!_mcp.device_info().has_global_controls()) {
859                 return;
860         }
861
862         // turn off global buttons and leds
863
864         for (Controls::iterator it = controls.begin(); it != controls.end(); ++it) {
865                 Control & control = **it;
866                 if (!control.group().is_strip()) {
867                         _port->write (control.zero());
868                 }
869         }
870
871         // and the led ring for the master strip
872         blank_jog_ring ();
873
874         _last_master_gain_written = 0.0f;
875 }
876
877 void
878 Surface::periodic (uint64_t now_usecs)
879 {
880         master_gain_changed();
881         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
882                 (*s)->periodic (now_usecs);
883         }
884 }
885
886 void
887 Surface::redisplay (ARDOUR::microseconds_t now)
888 {
889         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
890                 (*s)->redisplay (now);
891         }
892 }
893
894 void
895 Surface::write (const MidiByteArray& data)
896 {
897         if (_active) {
898                 _port->write (data);
899         } else {
900                 DEBUG_TRACE (DEBUG::MackieControl, "surface not active, write ignored\n");
901         }
902 }
903
904 void
905 Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
906 {
907         vector<boost::shared_ptr<Route> >::const_iterator r;
908         Strips::iterator s = strips.begin();
909
910         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mapping %1 routes\n", routes.size()));
911
912         for (r = routes.begin(); r != routes.end() && s != strips.end(); ++s) {
913
914                 /* don't try to assign routes to a locked strip. it won't
915                    use it anyway, but if we do, then we get out of sync
916                    with the proposed mapping.
917                 */
918
919                 if (!(*s)->locked()) {
920                         (*s)->set_route (*r);
921                         ++r;
922                 }
923         }
924
925         for (; s != strips.end(); ++s) {
926                 (*s)->set_route (boost::shared_ptr<Route>());
927         }
928
929
930 }
931
932 static char
933 translate_seven_segment (char achar)
934 {
935         achar = toupper (achar);
936
937         if  (achar >= 0x40 && achar <= 0x60) {
938                 return achar - 0x40;
939         } else if  (achar >= 0x21 && achar <= 0x3f) {
940                 return achar;
941         } else {
942                 return 0x00;
943         }
944 }
945
946 void
947 Surface::show_two_char_display (const std::string & msg, const std::string & dots)
948 {
949         if (_stype != mcu || !_mcp.device_info().has_two_character_display() || msg.length() != 2 || dots.length() != 2) {
950                 return;
951         }
952
953         MidiByteArray right (3, 0xb0, 0x4b, 0x00);
954         MidiByteArray left (3, 0xb0, 0x4a, 0x00);
955
956         right[2] = translate_seven_segment (msg[0]) +  (dots[0] == '.' ? 0x40 : 0x00);
957         left[2] = translate_seven_segment (msg[1]) +  (dots[1] == '.' ? 0x40 : 0x00);
958
959         _port->write (right);
960         _port->write (left);
961 }
962
963 void
964 Surface::show_two_char_display (unsigned int value, const std::string & /*dots*/)
965 {
966         ostringstream os;
967         os << setfill('0') << setw(2) << value % 100;
968         show_two_char_display (os.str());
969 }
970
971 void
972 Surface::display_timecode (const std::string & timecode, const std::string & last_timecode)
973 {
974         if (!_active || !_mcp.device_info().has_timecode_display()) {
975                 return;
976         }
977         // if there's no change, send nothing, not even sysex header
978         if  (timecode == last_timecode) return;
979
980         // length sanity checking
981         string local_timecode = timecode;
982
983         // truncate to 10 characters
984         if  (local_timecode.length() > 10) {
985                 local_timecode = local_timecode.substr (0, 10);
986         }
987
988         // pad to 10 characters
989         while  (local_timecode.length() < 10) {
990                 local_timecode += " ";
991         }
992
993         // translate characters.
994         // Only the characters that actually changed are sent.
995         int position = 0x3f;
996         int i;
997         for (i = local_timecode.length () - 1; i >= 0; i--) {
998                 position++;
999                 if (local_timecode[i] == last_timecode[i]) {
1000                         continue;
1001                 }
1002                 MidiByteArray retval (2, 0xb0, position);
1003                 retval << translate_seven_segment (local_timecode[i]);
1004                 _port->write (retval);
1005         }
1006 }
1007
1008 void
1009 Surface::update_flip_mode_display ()
1010 {
1011         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1012                 (*s)->potmode_changed (true);
1013         }
1014 }
1015
1016  void
1017 Surface::update_potmode ()
1018 {
1019         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1020                 (*s)->potmode_changed (false);
1021         }
1022 }
1023
1024 void
1025 Surface::update_view_mode_display ()
1026 {
1027         string text;
1028         int id = -1;
1029
1030         if (!_active) {
1031                 return;
1032         }
1033
1034         switch (_mcp.view_mode()) {
1035         case MackieControlProtocol::Mixer:
1036                 show_two_char_display ("Mx");
1037                 id = Button::View;
1038                 text = _("Mixer View");
1039                 break;
1040         case MackieControlProtocol::AudioTracks:
1041                 show_two_char_display ("AT");
1042                 id = Button::AudioTracks;
1043                 text = _("Audio Tracks");
1044                 break;
1045         case MackieControlProtocol::MidiTracks:
1046                 show_two_char_display ("MT");
1047                 id = Button::MidiTracks;
1048                 text = _("MIDI Tracks");
1049                 break;
1050         case MackieControlProtocol::Plugins:
1051                 show_two_char_display ("PL");
1052                 id = Button::Plugin;
1053                 text = _("Plugins");
1054                 break;
1055         case MackieControlProtocol::Busses:
1056                 show_two_char_display ("BS");
1057                 id = Button::Busses;
1058                 text = _("Busses");
1059                 break;
1060         case MackieControlProtocol::Auxes:
1061                 show_two_char_display ("AB");
1062                 id = Button::Aux;
1063                 text = _("Auxes");
1064                 break;
1065         default:
1066                 break;
1067         }
1068
1069         vector<int> view_mode_buttons;
1070         view_mode_buttons.push_back (Button::View);
1071         view_mode_buttons.push_back (Button::Busses);
1072         view_mode_buttons.push_back (Button::Plugin);
1073         view_mode_buttons.push_back (Button::AudioTracks);
1074         view_mode_buttons.push_back (Button::MidiTracks);
1075         view_mode_buttons.push_back (Button::Aux);
1076
1077         if (id >= 0) {
1078
1079                 for (vector<int>::iterator i = view_mode_buttons.begin(); i != view_mode_buttons.end(); ++i) {
1080                         map<int,Control*>::iterator x = controls_by_device_independent_id.find (id);
1081
1082                         if (x != controls_by_device_independent_id.end()) {
1083                                 Button* button = dynamic_cast<Button*> (x->second);
1084                                 if (button) {
1085                                         bool onoff;
1086                                         onoff = (*i) == id;
1087
1088                                         _port->write (button->set_state (onoff));
1089                                 }
1090                         }
1091                 }
1092         }
1093
1094         if (!text.empty()) {
1095                 display_message_for (text, 1000);
1096         }
1097 }
1098
1099 void
1100 Surface::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& routes)
1101 {
1102         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1103                 (*s)->gui_selection_changed (routes);
1104         }
1105 }
1106
1107 void
1108 Surface::say_hello ()
1109 {
1110         /* wakeup for Mackie Control */
1111         MidiByteArray wakeup (7, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x00, MIDI::eox);
1112         _port->write (wakeup);
1113         wakeup[4] = 0x15; /* wakup Mackie XT */
1114         _port->write (wakeup);
1115         wakeup[4] = 0x10; /* wakeup Logic Control */
1116         _port->write (wakeup);
1117         wakeup[4] = 0x11; /* wakeup Logic Control XT */
1118         _port->write (wakeup);
1119 }
1120
1121 void
1122 Surface::next_jog_mode ()
1123 {
1124 }
1125
1126 void
1127 Surface::set_jog_mode (JogWheel::Mode)
1128 {
1129 }
1130
1131 bool
1132 Surface::route_is_locked_to_strip (boost::shared_ptr<Route> r) const
1133 {
1134         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1135                 if ((*s)->route() == r && (*s)->locked()) {
1136                         return true;
1137                 }
1138         }
1139         return false;
1140 }
1141
1142 void
1143 Surface::notify_metering_state_changed()
1144 {
1145         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1146                 (*s)->notify_metering_state_changed ();
1147         }
1148 }
1149
1150 void
1151 Surface::reset ()
1152 {
1153         if (_port) {
1154                 /* reset msg for Mackie Control */
1155                 MidiByteArray msg;
1156                 msg << sysex_hdr();
1157                 msg << 0x08;
1158                 msg << 0x00;
1159                 msg << MIDI::eox;
1160                 _port->write (msg);
1161         }
1162 }
1163
1164 void
1165 Surface::toggle_backlight ()
1166 {
1167         if (_port) {
1168                 int onoff = random() %2;
1169                 MidiByteArray msg;
1170                 msg << sysex_hdr ();
1171                 msg << 0xa;
1172                 msg << (onoff ? 0x1 : 0x0);
1173                 msg << MIDI::eox;
1174                 _port->write (msg);
1175         }
1176 }
1177
1178 void
1179 Surface::recalibrate_faders ()
1180 {
1181         if (_port) {
1182                 MidiByteArray msg;
1183                 msg << sysex_hdr ();
1184                 msg << 0x09;
1185                 msg << 0x00;
1186                 msg << MIDI::eox;
1187                 _port->write (msg);
1188         }
1189 }
1190
1191 void
1192 Surface::set_touch_sensitivity (int sensitivity)
1193 {
1194         /* NOTE: assumed called from GUI code, hence sleep() */
1195
1196         /* sensitivity already clamped by caller */
1197
1198         if (_port) {
1199                 MidiByteArray msg;
1200
1201                 msg << sysex_hdr ();
1202                 msg << 0x0e;
1203                 msg << 0xff; /* overwritten for each fader below */
1204                 msg << (sensitivity & 0x7f);
1205                 msg << MIDI::eox;
1206
1207                 for (int fader = 0; fader < 9; ++fader) {
1208                         msg[6] = fader;
1209                         _port->write (msg);
1210                 }
1211         }
1212 }
1213
1214 void
1215 Surface::hui_heartbeat ()
1216 {
1217         if (!_port) {
1218                 return;
1219         }
1220
1221         MidiByteArray msg (3, MIDI::on, 0x0, 0x0);
1222         _port->write (msg);
1223 }
1224
1225 void
1226 Surface::connected ()
1227 {
1228         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 now connected, trying to ping device...\n", _name));
1229
1230         say_hello ();
1231
1232         if (_mcp.device_info().no_handshake()) {
1233                 turn_it_on ();
1234         }
1235 }
1236
1237 MidiByteArray
1238 Surface::display_line (string const& msg, int line_num)
1239 {
1240         MidiByteArray midi_msg;
1241         midi_msg << sysex_hdr ();
1242         midi_msg << 0x12;
1243         midi_msg << (line_num ? 0x38 : 0x0); /* offsets into char array
1244                                               * on device that
1245                                               * correspond to line
1246                                               * starts
1247                                               */
1248         if (msg.empty()) {
1249
1250                 midi_msg.insert (midi_msg.end(), 55, ' ');
1251
1252         } else {
1253
1254                 /* ascii data to display. @param msg is UTF-8 which is not legal. */
1255                 string ascii = Glib::convert_with_fallback (msg, "UTF-8", "ISO-8859-1", "_");
1256                 string::size_type len = ascii.length();
1257
1258                 if (len > 55) {
1259                         midi_msg << ascii.substr (0, 55);
1260                 } else {
1261                         midi_msg << ascii;
1262
1263                         for (string::size_type i = len; i < 55; ++i) {
1264                                 midi_msg << ' ';
1265                         }
1266                 }
1267         }
1268
1269         midi_msg << MIDI::eox;
1270
1271         return midi_msg;
1272 }
1273
1274 /** display @param msg on the 55x2 screen for @param msecs milliseconds
1275  *
1276  *  @param msg is assumed to be UTF-8 encoded, and will be converted
1277  *  to ASCII with an underscore as fallback character before being
1278  *  sent to the device.
1279  */
1280 void
1281 Surface::display_message_for (string const& msg, uint64_t msecs)
1282 {
1283         string::size_type newline;
1284
1285         if ((newline = msg.find ('\n')) == string::npos) {
1286
1287                 _port->write (display_line (msg, 0));
1288                 _port->write (display_line (string(), 1));
1289
1290         } else if (newline == 0) {
1291
1292                 _port->write (display_line (string(), 0));
1293                 _port->write (display_line (msg.substr (1), 1));
1294
1295         } else {
1296
1297                 string first_line = msg.substr (0, newline-1);
1298                 string second_line = msg.substr (newline+1);
1299
1300                 _port->write (display_line (first_line, 0));
1301                 _port->write (display_line (second_line.substr (0, second_line.find_first_of ('\n')), 1));
1302         }
1303
1304         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1305                 (*s)->block_screen_display_for (msecs);
1306         }
1307 }