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