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