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