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