Don't use old session connections on MCP device change, Solves crash on device change.
[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
170         DEBUG_TRACE (DEBUG::MackieControl, "Surface::~Surface done\n");
171 }
172
173 bool
174 Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
175 {
176         if (!_port) {
177                 return false;
178         }
179
180         string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->input_name());
181         string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (_port->output_name());
182
183         if (ni == name1 || ni == name2) {
184                 if (yn) {
185                         connection_state |= InputConnected;
186                 } else {
187                         connection_state &= ~InputConnected;
188                 }
189         } else if (no == name1 || no == name2) {
190                 if (yn) {
191                         connection_state |= OutputConnected;
192                 } else {
193                         connection_state &= ~OutputConnected;
194                 }
195         } else {
196                 /* not our ports */
197                 return false;
198         }
199
200         if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
201
202                 /* this will send a device query message, which should
203                    result in a response that will kick off device type
204                    discovery and activation of the surface(s).
205
206                    The intended order of events is:
207
208                    - each surface sends a device query message
209                    - devices respond with either MCP or LCP response (sysex in both
210                    cases)
211                    - sysex message causes Surface::turn_it_on() which tells the
212                    MCP object that the surface is ready, and sets up strip
213                    displays and binds faders and buttons for that surface
214
215                    In the case of LCP, where this is a handshake process that could
216                    fail, the response process to the initial sysex after a device query
217                    will mark the surface inactive, which won't shut anything down
218                    but will stop any writes to the device.
219
220                    Note: there are no known cases of the handshake process failing.
221
222                    We actually can't initiate this in this callback, so we have
223                    to queue it with the MCP event loop.
224                 */
225
226                 /* XXX this is a horrible hack. Without a short sleep here,
227                    something prevents the device wakeup messages from being
228                    sent and/or the responses from being received.
229                 */
230
231                 g_usleep (100000);
232                 connected ();
233
234         } else {
235                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 disconnected (input or output or both)\n", _name));
236                 _active = false;
237         }
238
239         return true; /* connection status changed */
240 }
241
242 XMLNode&
243 Surface::get_state()
244 {
245         XMLNode* node = new XMLNode (X_("Surface"));
246         node->add_property (X_("name"), _name);
247         node->add_child_nocopy (_port->get_state());
248         return *node;
249 }
250
251 int
252 Surface::set_state (const XMLNode& node, int version)
253 {
254         /* Look for a node named after this surface */
255
256         XMLNodeList const& children = node.children();
257         XMLNode* mynode = 0;
258
259         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
260                 XMLProperty const* prop = (*c)->property (X_("name"));
261                 if (prop) {
262                         if (prop->value() == _name) {
263                                 mynode = *c;
264                                 break;
265                         }
266                 }
267         }
268
269         if (!mynode) {
270                 return 0;
271         }
272
273         if (_mcp.session_load ()) {
274                 XMLNode* portnode = mynode->child (X_("Port"));
275                 if (portnode) {
276                         if (_port->set_state (*portnode, version)) {
277                                 return -1;
278                         }
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)->flip_mode_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::Pan;
1038                 break;
1039         case MackieControlProtocol::Loop:
1040                 show_two_char_display ("LP");
1041                 id = Button::Loop;
1042                 break;
1043         case MackieControlProtocol::AudioTracks:
1044                 show_two_char_display ("AT");
1045                 break;
1046         case MackieControlProtocol::MidiTracks:
1047                 show_two_char_display ("MT");
1048                 break;
1049         default:
1050                 break;
1051         }
1052
1053         if (id >= 0) {
1054
1055                 /* we are attempting to turn a global button/LED on */
1056
1057                 map<int,Control*>::iterator x = controls_by_device_independent_id.find (id);
1058
1059                 if (x != controls_by_device_independent_id.end()) {
1060                         Button* button = dynamic_cast<Button*> (x->second);
1061                         if (button) {
1062                                 _port->write (button->set_state (on));
1063                         }
1064                 }
1065         }
1066
1067         if (!text.empty()) {
1068                 for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1069                         _port->write ((*s)->display (1, text));
1070                 }
1071         }
1072 }
1073
1074 void
1075 Surface::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& routes)
1076 {
1077         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1078                 (*s)->gui_selection_changed (routes);
1079         }
1080 }
1081
1082 void
1083 Surface::say_hello ()
1084 {
1085         /* wakeup for Mackie Control */
1086         MidiByteArray wakeup (7, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x00, MIDI::eox);
1087         _port->write (wakeup);
1088         wakeup[4] = 0x15; /* wakup Mackie XT */
1089         _port->write (wakeup);
1090         wakeup[4] = 0x10; /* wakeup Logic Control */
1091         _port->write (wakeup);
1092         wakeup[4] = 0x11; /* wakeup Logic Control XT */
1093         _port->write (wakeup);
1094 }
1095
1096 void
1097 Surface::next_jog_mode ()
1098 {
1099 }
1100
1101 void
1102 Surface::set_jog_mode (JogWheel::Mode)
1103 {
1104 }
1105
1106 bool
1107 Surface::route_is_locked_to_strip (boost::shared_ptr<Route> r) const
1108 {
1109         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1110                 if ((*s)->route() == r && (*s)->locked()) {
1111                         return true;
1112                 }
1113         }
1114         return false;
1115 }
1116
1117 void
1118 Surface::notify_metering_state_changed()
1119 {
1120         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1121                 (*s)->notify_metering_state_changed ();
1122         }
1123 }
1124
1125 void
1126 Surface::reset ()
1127 {
1128         if (_port) {
1129                 /* reset msg for Mackie Control */
1130                 MidiByteArray msg;
1131                 msg << sysex_hdr();
1132                 msg << 0x08;
1133                 msg << 0x00;
1134                 msg << MIDI::eox;
1135                 _port->write (msg);
1136         }
1137 }
1138
1139 void
1140 Surface::toggle_backlight ()
1141 {
1142         if (_port) {
1143                 int onoff = random() %2;
1144                 MidiByteArray msg;
1145                 msg << sysex_hdr ();
1146                 msg << 0xa;
1147                 msg << (onoff ? 0x1 : 0x0);
1148                 msg << MIDI::eox;
1149                 _port->write (msg);
1150         }
1151 }
1152
1153 void
1154 Surface::recalibrate_faders ()
1155 {
1156         if (_port) {
1157                 MidiByteArray msg;
1158                 msg << sysex_hdr ();
1159                 msg << 0x09;
1160                 msg << 0x00;
1161                 msg << MIDI::eox;
1162                 _port->write (msg);
1163         }
1164 }
1165
1166 void
1167 Surface::set_touch_sensitivity (int sensitivity)
1168 {
1169         /* NOTE: assumed called from GUI code, hence sleep() */
1170
1171         /* sensitivity already clamped by caller */
1172
1173         if (_port) {
1174                 MidiByteArray msg;
1175
1176                 msg << sysex_hdr ();
1177                 msg << 0x0e;
1178                 msg << 0xff; /* overwritten for each fader below */
1179                 msg << (sensitivity & 0x7f);
1180                 msg << MIDI::eox;
1181
1182                 for (int fader = 0; fader < 9; ++fader) {
1183                         msg[6] = fader;
1184                         _port->write (msg);
1185                 }
1186         }
1187 }
1188
1189 void
1190 Surface::hui_heartbeat ()
1191 {
1192         if (!_port) {
1193                 return;
1194         }
1195
1196         MidiByteArray msg (3, MIDI::on, 0x0, 0x0);
1197         _port->write (msg);
1198 }
1199
1200 void
1201 Surface::connected ()
1202 {
1203         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 now connected, trying to ping device...\n", _name));
1204
1205         say_hello ();
1206
1207         if (_mcp.device_info().no_handshake()) {
1208                 turn_it_on ();
1209         }
1210 }
1211
1212 MidiByteArray
1213 Surface::display_line (string const& msg, int line_num)
1214 {
1215         MidiByteArray midi_msg;
1216         midi_msg << sysex_hdr ();
1217         midi_msg << 0x12;
1218         midi_msg << (line_num ? 0x38 : 0x0); /* offsets into char array
1219                                               * on device that
1220                                               * correspond to line
1221                                               * starts
1222                                               */
1223         if (msg.empty()) {
1224
1225                 midi_msg.insert (midi_msg.end(), 55, ' ');
1226
1227         } else {
1228
1229                 /* ascii data to display. @param msg is UTF-8 which is not legal. */
1230                 string ascii = Glib::convert_with_fallback (msg, "UTF-8", "ISO-8859-1", "_");
1231                 string::size_type len = ascii.length();
1232
1233                 if (len > 55) {
1234                         midi_msg << ascii.substr (0, 55);
1235                 } else {
1236                         midi_msg << ascii;
1237
1238                         for (string::size_type i = len; i < 55; ++i) {
1239                                 midi_msg << ' ';
1240                         }
1241                 }
1242         }
1243
1244         midi_msg << MIDI::eox;
1245
1246         return midi_msg;
1247 }
1248
1249 /** display @param msg on the 55x2 screen for @param msecs milliseconds
1250  *
1251  *  @param msg is assumed to be UTF-8 encoded, and will be converted
1252  *  to ASCII with an underscore as fallback character before being
1253  *  sent to the device.
1254  */
1255 void
1256 Surface::display_message_for (string const& msg, uint64_t msecs)
1257 {
1258         string::size_type newline;
1259
1260         if ((newline = msg.find ('\n')) == string::npos) {
1261
1262                 _port->write (display_line (msg, 0));
1263                 _port->write (display_line (string(), 1));
1264
1265         } else if (newline == 0) {
1266
1267                 _port->write (display_line (string(), 0));
1268                 _port->write (display_line (msg.substr (1), 1));
1269
1270         } else {
1271
1272                 string first_line = msg.substr (0, newline-1);
1273                 string second_line = msg.substr (newline+1);
1274
1275                 _port->write (display_line (first_line, 0));
1276                 _port->write (display_line (second_line.substr (0, second_line.find_first_of ('\n')), 1));
1277         }
1278
1279         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1280                 (*s)->block_screen_display_for (msecs);
1281         }
1282 }