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