fix shared_ptr<Route> management in Mackie support so that deleted routes are destroyed
[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 to %2 strips\n", routes.size(), strips.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                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 being set to null route\n", (*s)->index()));
957                 (*s)->set_route (boost::shared_ptr<Route>());
958         }
959 }
960
961 static char
962 translate_seven_segment (char achar)
963 {
964         achar = toupper (achar);
965
966         if  (achar >= 0x40 && achar <= 0x60) {
967                 return achar - 0x40;
968         } else if  (achar >= 0x21 && achar <= 0x3f) {
969                 return achar;
970         } else {
971                 return 0x00;
972         }
973 }
974
975 void
976 Surface::show_two_char_display (const std::string & msg, const std::string & dots)
977 {
978         if (_stype != mcu || !_mcp.device_info().has_two_character_display() || msg.length() != 2 || dots.length() != 2) {
979                 return;
980         }
981
982         MidiByteArray right (3, 0xb0, 0x4b, 0x00);
983         MidiByteArray left (3, 0xb0, 0x4a, 0x00);
984
985         right[2] = translate_seven_segment (msg[0]) +  (dots[0] == '.' ? 0x40 : 0x00);
986         left[2] = translate_seven_segment (msg[1]) +  (dots[1] == '.' ? 0x40 : 0x00);
987
988         _port->write (right);
989         _port->write (left);
990 }
991
992 void
993 Surface::show_two_char_display (unsigned int value, const std::string & /*dots*/)
994 {
995         ostringstream os;
996         os << setfill('0') << setw(2) << value % 100;
997         show_two_char_display (os.str());
998 }
999
1000 void
1001 Surface::display_timecode (const std::string & timecode, const std::string & last_timecode)
1002 {
1003         if (!_active || !_mcp.device_info().has_timecode_display()) {
1004                 return;
1005         }
1006         // if there's no change, send nothing, not even sysex header
1007         if  (timecode == last_timecode) return;
1008
1009         // length sanity checking
1010         string local_timecode = timecode;
1011
1012         // truncate to 10 characters
1013         if  (local_timecode.length() > 10) {
1014                 local_timecode = local_timecode.substr (0, 10);
1015         }
1016
1017         // pad to 10 characters
1018         while  (local_timecode.length() < 10) {
1019                 local_timecode += " ";
1020         }
1021
1022         // translate characters.
1023         // Only the characters that actually changed are sent.
1024         int position = 0x3f;
1025         int i;
1026         for (i = local_timecode.length () - 1; i >= 0; i--) {
1027                 position++;
1028                 if (local_timecode[i] == last_timecode[i]) {
1029                         continue;
1030                 }
1031                 MidiByteArray retval (2, 0xb0, position);
1032                 retval << translate_seven_segment (local_timecode[i]);
1033                 _port->write (retval);
1034         }
1035 }
1036
1037 void
1038 Surface::update_flip_mode_display ()
1039 {
1040         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1041                 (*s)->flip_mode_changed ();
1042         }
1043 }
1044
1045 void
1046 Surface::subview_mode_changed ()
1047 {
1048         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1049                 (*s)->subview_mode_changed ();
1050         }
1051 }
1052
1053 void
1054 Surface::update_view_mode_display (bool with_helpful_text)
1055 {
1056         string text;
1057         int id = -1;
1058
1059         if (!_active) {
1060                 return;
1061         }
1062
1063         switch (_mcp.view_mode()) {
1064         case MackieControlProtocol::Mixer:
1065                 show_two_char_display ("Mx");
1066                 id = Button::View;
1067                 text = _("Mixer View");
1068                 break;
1069         case MackieControlProtocol::AudioTracks:
1070                 show_two_char_display ("AT");
1071                 id = Button::AudioTracks;
1072                 text = _("Audio Tracks");
1073                 break;
1074         case MackieControlProtocol::MidiTracks:
1075                 show_two_char_display ("MT");
1076                 id = Button::MidiTracks;
1077                 text = _("MIDI Tracks");
1078                 break;
1079         case MackieControlProtocol::Plugins:
1080                 show_two_char_display ("PL");
1081                 id = Button::Plugin;
1082                 text = _("Plugins");
1083                 break;
1084         case MackieControlProtocol::Busses:
1085                 show_two_char_display ("BS");
1086                 id = Button::Busses;
1087                 if (Profile->get_mixbus()) {
1088                         text = _("Mixbusses");
1089                 } else {
1090                         text = _("Busses");
1091                 }
1092                 break;
1093         case MackieControlProtocol::Auxes:
1094                 show_two_char_display ("Au");
1095                 id = Button::Aux;
1096                 text = _("Auxes");
1097                 break;
1098         case MackieControlProtocol::Hidden:
1099                 show_two_char_display ("HI");
1100                 id = Button::Outputs;
1101                 text = _("Hidden Tracks");
1102                 break;
1103         case MackieControlProtocol::Selected:
1104                 show_two_char_display ("SE");
1105                 id = Button::User;
1106                 text = _("Selected Tracks");
1107                 break;
1108         default:
1109                 break;
1110         }
1111
1112         vector<int> view_mode_buttons;
1113         view_mode_buttons.push_back (Button::View);
1114         view_mode_buttons.push_back (Button::Busses);
1115         view_mode_buttons.push_back (Button::Plugin);
1116         view_mode_buttons.push_back (Button::AudioTracks);
1117         view_mode_buttons.push_back (Button::MidiTracks);
1118         view_mode_buttons.push_back (Button::Aux);
1119         view_mode_buttons.push_back (Button::Outputs);
1120         view_mode_buttons.push_back (Button::User);
1121
1122         if (id >= 0) {
1123
1124                 for (vector<int>::iterator i = view_mode_buttons.begin(); i != view_mode_buttons.end(); ++i) {
1125                         map<int,Control*>::iterator x = controls_by_device_independent_id.find (id);
1126
1127                         if (x != controls_by_device_independent_id.end()) {
1128                                 Button* button = dynamic_cast<Button*> (x->second);
1129                                 if (button) {
1130                                         bool onoff;
1131                                         onoff = (*i) == id;
1132
1133                                         _port->write (button->set_state (onoff));
1134                                 }
1135                         }
1136                 }
1137         }
1138
1139         if (with_helpful_text && !text.empty()) {
1140                 display_message_for (text, 1000);
1141         }
1142 }
1143
1144 void
1145 Surface::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& routes)
1146 {
1147         for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
1148                 (*s)->gui_selection_changed (routes);
1149         }
1150 }
1151
1152 void
1153 Surface::say_hello ()
1154 {
1155         /* wakeup for Mackie Control */
1156         MidiByteArray wakeup (7, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x00, MIDI::eox);
1157         _port->write (wakeup);
1158         wakeup[4] = 0x15; /* wakup Mackie XT */
1159         _port->write (wakeup);
1160         wakeup[4] = 0x10; /* wakeup Logic Control */
1161         _port->write (wakeup);
1162         wakeup[4] = 0x11; /* wakeup Logic Control XT */
1163         _port->write (wakeup);
1164 }
1165
1166 void
1167 Surface::next_jog_mode ()
1168 {
1169 }
1170
1171 void
1172 Surface::set_jog_mode (JogWheel::Mode)
1173 {
1174 }
1175
1176 bool
1177 Surface::route_is_locked_to_strip (boost::shared_ptr<Route> r) const
1178 {
1179         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1180                 if ((*s)->route() == r && (*s)->locked()) {
1181                         return true;
1182                 }
1183         }
1184         return false;
1185 }
1186
1187 bool
1188 Surface::route_is_mapped (boost::shared_ptr<Route> r) const
1189 {
1190         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1191                 if ((*s)->route() == r) {
1192                         return true;
1193                 }
1194         }
1195
1196         return false;
1197 }
1198
1199 void
1200 Surface::notify_metering_state_changed()
1201 {
1202         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1203                 (*s)->notify_metering_state_changed ();
1204         }
1205 }
1206
1207 void
1208 Surface::reset ()
1209 {
1210         if (_port) {
1211                 /* reset msg for Mackie Control */
1212                 MidiByteArray msg;
1213                 msg << sysex_hdr();
1214                 msg << 0x08;
1215                 msg << 0x00;
1216                 msg << MIDI::eox;
1217                 _port->write (msg);
1218         }
1219 }
1220
1221 void
1222 Surface::toggle_backlight ()
1223 {
1224         if (_port) {
1225                 int onoff = random() %2;
1226                 MidiByteArray msg;
1227                 msg << sysex_hdr ();
1228                 msg << 0xa;
1229                 msg << (onoff ? 0x1 : 0x0);
1230                 msg << MIDI::eox;
1231                 _port->write (msg);
1232         }
1233 }
1234
1235 void
1236 Surface::recalibrate_faders ()
1237 {
1238         if (_port) {
1239                 MidiByteArray msg;
1240                 msg << sysex_hdr ();
1241                 msg << 0x09;
1242                 msg << 0x00;
1243                 msg << MIDI::eox;
1244                 _port->write (msg);
1245         }
1246 }
1247
1248 void
1249 Surface::set_touch_sensitivity (int sensitivity)
1250 {
1251         /* NOTE: assumed called from GUI code, hence sleep() */
1252
1253         /* sensitivity already clamped by caller */
1254
1255         if (_port) {
1256                 MidiByteArray msg;
1257
1258                 msg << sysex_hdr ();
1259                 msg << 0x0e;
1260                 msg << 0xff; /* overwritten for each fader below */
1261                 msg << (sensitivity & 0x7f);
1262                 msg << MIDI::eox;
1263
1264                 for (int fader = 0; fader < 9; ++fader) {
1265                         msg[6] = fader;
1266                         _port->write (msg);
1267                 }
1268         }
1269 }
1270
1271 void
1272 Surface::hui_heartbeat ()
1273 {
1274         if (!_port) {
1275                 return;
1276         }
1277
1278         MidiByteArray msg (3, MIDI::on, 0x0, 0x0);
1279         _port->write (msg);
1280 }
1281
1282 void
1283 Surface::connected ()
1284 {
1285         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 now connected, trying to ping device...\n", _name));
1286
1287         say_hello ();
1288
1289         if (_mcp.device_info().no_handshake()) {
1290                 turn_it_on ();
1291         }
1292 }
1293
1294 MidiByteArray
1295 Surface::display_line (string const& msg, int line_num)
1296 {
1297         MidiByteArray midi_msg;
1298         midi_msg << sysex_hdr ();
1299         midi_msg << 0x12;
1300         midi_msg << (line_num ? 0x38 : 0x0); /* offsets into char array
1301                                               * on device that
1302                                               * correspond to line
1303                                               * starts
1304                                               */
1305         if (msg.empty()) {
1306
1307                 midi_msg.insert (midi_msg.end(), 55, ' ');
1308
1309         } else {
1310
1311                 /* ascii data to display. @param msg is UTF-8 which is not legal. */
1312                 string ascii = Glib::convert_with_fallback (msg, "UTF-8", "ISO-8859-1", "_");
1313                 string::size_type len = ascii.length();
1314
1315                 if (len > 55) {
1316                         midi_msg << ascii.substr (0, 55);
1317                 } else {
1318                         midi_msg << ascii;
1319
1320                         for (string::size_type i = len; i < 55; ++i) {
1321                                 midi_msg << ' ';
1322                         }
1323                 }
1324         }
1325
1326         midi_msg << MIDI::eox;
1327
1328         return midi_msg;
1329 }
1330
1331 /** display @param msg on the 55x2 screen for @param msecs milliseconds
1332  *
1333  *  @param msg is assumed to be UTF-8 encoded, and will be converted
1334  *  to ASCII with an underscore as fallback character before being
1335  *  sent to the device.
1336  */
1337 void
1338 Surface::display_message_for (string const& msg, uint64_t msecs)
1339 {
1340         string::size_type newline;
1341
1342         if ((newline = msg.find ('\n')) == string::npos) {
1343
1344                 _port->write (display_line (msg, 0));
1345                 _port->write (display_line (string(), 1));
1346
1347         } else if (newline == 0) {
1348
1349                 _port->write (display_line (string(), 0));
1350                 _port->write (display_line (msg.substr (1), 1));
1351
1352         } else {
1353
1354                 string first_line = msg.substr (0, newline-1);
1355                 string second_line = msg.substr (newline+1);
1356
1357                 _port->write (display_line (first_line, 0));
1358                 _port->write (display_line (second_line.substr (0, second_line.find_first_of ('\n')), 1));
1359         }
1360
1361         for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
1362                 (*s)->block_screen_display_for (msecs);
1363         }
1364 }