b883d0b51ab706867de5fda966b8c01a4dafb5a6
[ardour.git] / libs / surfaces / mackie / mackie_control_protocol.cc
1 /*
2         Copyright (C) 2006,2007 John Anderson
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 #include <fcntl.h>
20 #include <iostream>
21 #include <algorithm>
22 #include <cmath>
23 #include <sstream>
24 #include <vector>
25 #include <iomanip>
26
27 #include <inttypes.h>
28 #include <float.h>
29 #include <sys/time.h>
30 #include <errno.h>
31 #include <poll.h>
32
33 #include <boost/shared_array.hpp>
34
35 #include "midi++/types.h"
36 #include "midi++/port.h"
37 #include "midi++/manager.h"
38 #include "pbd/pthread_utils.h"
39 #include "pbd/error.h"
40 #include "pbd/memento_command.h"
41 #include "pbd/convert.h"
42
43 #include "ardour/dB.h"
44 #include "ardour/debug.h"
45 #include "ardour/location.h"
46 #include "ardour/midi_ui.h"
47 #include "ardour/meter.h"
48 #include "ardour/panner.h"
49 #include "ardour/panner_shell.h"
50 #include "ardour/route.h"
51 #include "ardour/session.h"
52 #include "ardour/tempo.h"
53 #include "ardour/types.h"
54 #include "ardour/audioengine.h"
55
56 #include "mackie_control_protocol.h"
57
58 #include "midi_byte_array.h"
59 #include "mackie_control_exception.h"
60 #include "route_signal.h"
61 #include "mackie_midi_builder.h"
62 #include "surface_port.h"
63 #include "surface.h"
64 #include "bcf_surface.h"
65 #include "mackie_surface.h"
66
67 using namespace ARDOUR;
68 using namespace std;
69 using namespace Mackie;
70 using namespace PBD;
71
72 #include "i18n.h"
73
74 #include "pbd/abstract_ui.cc" // instantiate template
75
76 #define NUCLEUS_DEBUG 1
77
78 MackieMidiBuilder builder;
79
80 #define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
81 #define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__))
82
83 extern PBD::EventLoop::InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
84 #define invalidator(x) __invalidator ((x), __FILE__, __LINE__)
85
86 MackieControlProtocol::MackieControlProtocol (Session& session)
87         : ControlProtocol (session, X_("Mackie"), MidiControlUI::instance())
88         , AbstractUI<MackieControlUIRequest> ("mackie")
89         , _current_initial_bank (0)
90         , _surface (0)
91         , _jog_wheel (*this)
92         , _timecode_type (ARDOUR::AnyTime::BBT)
93         , _input_bundle (new ARDOUR::Bundle (_("Mackie Control In"), true))
94         , _output_bundle (new ARDOUR::Bundle (_("Mackie Control Out"), false))
95         , _gui (0)
96 {
97         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
98
99         AudioEngine::instance()->PortConnectedOrDisconnected.connect (
100                 audio_engine_connections, invalidator (*this), ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
101                 midi_ui_context ()
102                 );
103 }
104
105 MackieControlProtocol::~MackieControlProtocol()
106 {
107         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol\n");
108
109         try {
110                 close();
111         }
112         catch (exception & e) {
113                 cout << "~MackieControlProtocol caught " << e.what() << endl;
114         }
115         catch (...) {
116                 cout << "~MackieControlProtocol caught unknown" << endl;
117         }
118
119         DEBUG_TRACE (DEBUG::MackieControl, "finished ~MackieControlProtocol::MackieControlProtocol\n");
120 }
121
122 Mackie::Surface& 
123 MackieControlProtocol::surface()
124 {
125         if (_surface == 0) {
126                 throw MackieControlException ("_surface is 0 in MackieControlProtocol::surface");
127         }
128         return *_surface;
129 }
130
131 const Mackie::SurfacePort& 
132 MackieControlProtocol::mcu_port() const
133 {
134         if (_ports.size() < 1) {
135                 return _dummy_port;
136         } else {
137                 return dynamic_cast<const MackiePort &> (*_ports[0]);
138         }
139 }
140
141 Mackie::SurfacePort& 
142 MackieControlProtocol::mcu_port()
143 {
144         if (_ports.size() < 1) {
145                 return _dummy_port;
146         } else {
147                 return dynamic_cast<MackiePort &> (*_ports[0]);
148         }
149 }
150
151 // go to the previous track.
152 // Assume that get_sorted_routes().size() > route_table.size()
153 void 
154 MackieControlProtocol::prev_track()
155 {
156         if (_current_initial_bank >= 1) {
157                 session->set_dirty();
158                 switch_banks (_current_initial_bank - 1);
159         }
160 }
161
162 // go to the next track.
163 // Assume that get_sorted_routes().size() > route_table.size()
164 void 
165 MackieControlProtocol::next_track()
166 {
167         Sorted sorted = get_sorted_routes();
168         if (_current_initial_bank + route_table.size() < sorted.size()) {
169                 session->set_dirty();
170                 switch_banks (_current_initial_bank + 1);
171         }
172 }
173
174 void 
175 MackieControlProtocol::clear_route_signals()
176 {
177         Glib::Mutex::Lock lm (route_signals_lock);
178
179         for (RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it) {
180                 delete *it;
181         }
182
183         route_signals.clear();
184 }
185
186 // return the port for a given id - 0 based
187 // throws an exception if no port found
188 MackiePort& 
189 MackieControlProtocol::port_for_id (uint32_t index)
190 {
191         uint32_t current_max = 0;
192
193         for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
194                 current_max += (*it)->strips();
195                 if (index < current_max) { 
196                         return **it;
197                 }
198         }
199
200         // oops - no matching port
201         ostringstream os;
202         os << "No port for index " << index;
203         cerr << "No port for index " << index << endl;
204         throw MackieControlException (os.str());
205 }
206
207 // predicate for sort call in get_sorted_routes
208 struct RouteByRemoteId
209 {
210         bool operator () (const boost::shared_ptr<Route> & a, const boost::shared_ptr<Route> & b) const
211         {
212                 return a->remote_control_id() < b->remote_control_id();
213         }
214
215         bool operator () (const Route & a, const Route & b) const
216         {
217                 return a.remote_control_id() < b.remote_control_id();
218         }
219
220         bool operator () (const Route * a, const Route * b) const
221         {
222                 return a->remote_control_id() < b->remote_control_id();
223         }
224 };
225
226 MackieControlProtocol::Sorted 
227 MackieControlProtocol::get_sorted_routes()
228 {
229         Sorted sorted;
230
231         // fetch all routes
232         boost::shared_ptr<RouteList> routes = session->get_routes();
233         set<uint32_t> remote_ids;
234
235         // routes with remote_id 0 should never be added
236         // TODO verify this with ardour devs
237         // remote_ids.insert (0);
238
239         // sort in remote_id order, and exclude master, control and hidden routes
240         // and any routes that are already set.
241         for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it) {
242                 Route & route = **it;
243                 if (
244                         route.active()
245                         && !route.is_master()
246                         && !route.is_hidden()
247                         && !route.is_monitor()
248                         && remote_ids.find (route.remote_control_id()) == remote_ids.end()
249                         ) {
250                         sorted.push_back (*it);
251                         remote_ids.insert (route.remote_control_id());
252                 }
253         }
254         sort (sorted.begin(), sorted.end(), RouteByRemoteId());
255         return sorted;
256 }
257
258 void 
259 MackieControlProtocol::refresh_current_bank()
260 {
261         switch_banks (_current_initial_bank);
262 }
263
264 void 
265 MackieControlProtocol::switch_banks (int initial)
266 {
267         // DON'T prevent bank switch if initial == _current_initial_bank
268         // because then this method can't be used as a refresh
269
270         Sorted sorted = get_sorted_routes();
271         int delta = sorted.size() - route_table.size();
272
273         if (initial < 0 || (delta > 0 && initial > delta)) {
274                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
275                 return;
276         }
277
278         _current_initial_bank = initial;
279         clear_route_signals();
280
281         // now set the signals for new routes
282         if (_current_initial_bank <= sorted.size()) {
283
284                 uint32_t end_pos = min (route_table.size(), sorted.size());
285                 uint32_t i = 0;
286                 Sorted::iterator it = sorted.begin() + _current_initial_bank;
287                 Sorted::iterator end = sorted.begin() + _current_initial_bank + end_pos;
288
289                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to %1, %2\n", _current_initial_bank, end_pos));
290
291                 route_table.clear ();
292                 set_route_table_size (surface().strips.size());
293
294                 // link routes to strips
295
296                 Glib::Mutex::Lock lm (route_signals_lock);
297
298                 for (; it != end && it != sorted.end(); ++it, ++i) {
299                         boost::shared_ptr<Route> route = *it;
300
301                         assert (surface().strips[i]);
302                         Strip & strip = *surface().strips[i];
303
304                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("remote id %1 connecting %2 to %3 with port %4\n", 
305                                                                            route->remote_control_id(), route->name(), strip.name(), port_for_id(i)));
306                         set_route_table (i, route);
307                         RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i));
308                         route_signals.push_back (rs);
309                         rs->notify_all ();
310                 }
311
312                 // create dead strips if there aren't enough routes to
313                 // fill a bank
314                 for (; i < route_table.size(); ++i) {
315                         Strip & strip = *surface().strips[i];
316                         // send zero for this strip
317                         MackiePort & port = port_for_id(i);
318                         port.write (builder.zero_strip (port, strip));
319                 }
320         }
321
322         // display the current start bank.
323         surface().display_bank_start (mcu_port(), builder, _current_initial_bank);
324 }
325
326 void 
327 MackieControlProtocol::zero_all()
328 {
329         // TODO turn off Timecode displays
330
331         // zero all strips
332         for (Surface::Strips::iterator it = surface().strips.begin(); it != surface().strips.end(); ++it) {
333                 MackiePort & port = port_for_id ((*it)->index());
334                 port.write (builder.zero_strip (port, **it));
335         }
336
337         // and the master strip
338         mcu_port().write (builder.zero_strip (dynamic_cast<MackiePort&> (mcu_port()), master_strip()));
339
340         // turn off global buttons and leds
341         // global buttons are only ever on mcu_port, so we don't have
342         // to figure out which port.
343         for (Surface::Controls::iterator it = surface().controls.begin(); it != surface().controls.end(); ++it) {
344                 Control & control = **it;
345                 if (!control.group().is_strip() && control.accepts_feedback()) {
346                         mcu_port().write (builder.zero_control (control));
347                 }
348         }
349
350         // any hardware-specific stuff
351         surface().zero_all (mcu_port(), builder);
352 }
353
354 int 
355 MackieControlProtocol::set_active (bool yn)
356 {
357         if (yn == _active) {
358                 return 0;
359         }
360
361         try
362         {
363                 // the reason for the locking and unlocking is that
364                 // glibmm can't do a condition wait on a RecMutex
365                 if (yn) {
366                         // TODO what happens if this fails half way?
367
368                         // start an event loop
369
370                         BaseUI::run ();
371                         
372                         // create MackiePorts
373                         {
374                                 Glib::Mutex::Lock lock (update_mutex);
375                                 create_ports();
376                         }
377                         
378                         // now initialise MackiePorts - ie exchange sysex messages
379                         for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
380                                 (*it)->open();
381                         }
382                         
383                         // wait until all ports are active
384                         // TODO a more sophisticated approach would
385                         // allow things to start up with only an MCU, even if
386                         // extenders were specified but not responding.
387                         for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
388                                 (*it)->wait_for_init();
389                         }
390                         
391                         // create surface object. This depends on the ports being
392                         // correctly initialised
393                         initialize_surface();
394                         connect_session_signals();
395                         
396                         // yeehah!
397                         _active = true;
398                         
399                         // send current control positions to surface
400                         // must come after _active = true otherwise it won't run
401                         update_surface();
402
403                         Glib::RefPtr<Glib::TimeoutSource> meter_timeout = Glib::TimeoutSource::create (100); // milliseconds
404
405                         meter_connection = meter_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::meter_update));
406
407                         meter_timeout->attach (main_loop()->get_context());
408
409                 } else {
410                         BaseUI::quit ();
411                         close();
412                         _active = false;
413                 }
414         }
415         
416         catch (exception & e) {
417                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("set_active to false because exception caught: %1\n", e.what()));
418                 _active = false;
419                 throw;
420         }
421
422         return 0;
423 }
424
425 bool
426 MackieControlProtocol::meter_update ()
427 {
428         /* update automation while we're here */
429
430         poll_session_data ();
431
432         {
433                 Glib::Mutex::Lock lm (route_signals_lock);
434                 
435                 for (std::vector<RouteSignal*>::iterator r = route_signals.begin(); r != route_signals.end(); ++r) {
436                         float dB;
437                         
438                         dB = const_cast<PeakMeter&> ((*r)->route()->peak_meter()).peak_power (0);
439                         Mackie::Meter& m = (*r)->strip().meter();
440                         
441                         float def = 0.0f; /* Meter deflection %age */
442                         
443                         if (dB < -70.0f) {
444                                 def = 0.0f;
445                         } else if (dB < -60.0f) {
446                                 def = (dB + 70.0f) * 0.25f;
447                         } else if (dB < -50.0f) {
448                                 def = (dB + 60.0f) * 0.5f + 2.5f;
449                         } else if (dB < -40.0f) {
450                                 def = (dB + 50.0f) * 0.75f + 7.5f;
451                         } else if (dB < -30.0f) {
452                                 def = (dB + 40.0f) * 1.5f + 15.0f;
453                         } else if (dB < -20.0f) {
454                                 def = (dB + 30.0f) * 2.0f + 30.0f;
455                         } else if (dB < 6.0f) {
456                                 def = (dB + 20.0f) * 2.5f + 50.0f;
457                         } else {
458                                 def = 115.0f;
459                         }
460                         
461                         /* 115 is the deflection %age that would be
462                            when dB=6.0. this is an arbitrary
463                            endpoint for our scaling.
464                         */
465                         
466                         (*r)->port().write (builder.build_meter (m, def/115.0));
467                 }
468         }
469
470         return _active; // call it again as long as we're active
471 }
472
473 bool 
474 MackieControlProtocol::handle_strip_button (SurfacePort & port, Control & control, ButtonState bs, boost::shared_ptr<Route> route)
475 {
476         bool state = false;
477
478         if (bs == press) {
479                 if (control.name() == "recenable") {
480                         state = !route->record_enabled();
481                         route->set_record_enabled (state, this);
482                 } else if (control.name() == "mute") {
483                         state = !route->muted();
484                         route->set_mute (state, this);
485                 } else if (control.name() == "solo") {
486                         state = !route->soloed();
487                         route->set_solo (state, this);
488                 } else if (control.name() == "select") {
489                         // TODO make the track selected. Whatever that means.
490                         //state = default_button_press (dynamic_cast<Button&> (control));
491                 } else if (control.name() == "vselect") {
492                         // TODO could be used to select different things to apply the pot to?
493                         //state = default_button_press (dynamic_cast<Button&> (control));
494                 }
495         }
496
497         if (control.name() == "fader_touch") {
498                 state = bs == press;
499                 control.strip().gain().set_in_use (state);
500
501                 if (ARDOUR::Config->get_mackie_emulation() == "bcf" && state) {
502                         /* BCF faders don't support touch, so add a timeout to reset
503                            their `in_use' state.
504                         */
505                         add_in_use_timeout (port, control.strip().gain(), &control.strip().fader_touch());
506                 }
507         }
508
509         return state;
510 }
511
512 void 
513 MackieControlProtocol::update_led (Mackie::Button & button, Mackie::LedState ls)
514 {
515         if (ls != none) {
516                 SurfacePort * port = 0;
517                 if (button.group().is_strip()) {
518                         if (button.group().is_master()) {
519                                 port = &mcu_port();
520                         } else {
521                                 port = &port_for_id (dynamic_cast<const Strip&> (button.group()).index());
522                         }
523                 } else {
524                         port = &mcu_port();
525                 }
526                 port->write (builder.build_led (button, ls));
527         }
528 }
529
530 void 
531 MackieControlProtocol::update_timecode_beats_led()
532 {
533         switch (_timecode_type) {
534                 case ARDOUR::AnyTime::BBT:
535                         update_global_led ("beats", on);
536                         update_global_led ("timecode", off);
537                         break;
538                 case ARDOUR::AnyTime::Timecode:
539                         update_global_led ("timecode", on);
540                         update_global_led ("beats", off);
541                         break;
542                 default:
543                         ostringstream os;
544                         os << "Unknown Anytime::Type " << _timecode_type;
545                         throw runtime_error (os.str());
546         }
547 }
548
549 void 
550 MackieControlProtocol::update_global_button (const string & name, LedState ls)
551 {
552         if (surface().controls_by_name.find (name) != surface().controls_by_name.end()) {
553                 Button * button = dynamic_cast<Button*> (surface().controls_by_name[name]);
554                 mcu_port().write (builder.build_led (button->led(), ls));
555         } else {
556                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Button %1 not found\n", name));
557         }
558 }
559
560 void 
561 MackieControlProtocol::update_global_led (const string & name, LedState ls)
562 {
563         if (surface().controls_by_name.find (name) != surface().controls_by_name.end()) {
564                 Led * led = dynamic_cast<Led*> (surface().controls_by_name[name]);
565                 mcu_port().write (builder.build_led (*led, ls));
566         } else {
567                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Led %1 not found\n", name));
568         }
569 }
570
571 // send messages to surface to set controls to correct values
572 void 
573 MackieControlProtocol::update_surface()
574 {
575         if (!_active) {
576                 return;
577         }
578
579         // do the initial bank switch to connect signals
580         // _current_initial_bank is initialised by set_state
581         switch_banks (_current_initial_bank);
582         
583         /* Create a RouteSignal for the master route, if we don't already have one */
584         if (!master_route_signal) {
585                 boost::shared_ptr<Route> mr = master_route ();
586                 if (mr) {
587                         master_route_signal = boost::shared_ptr<RouteSignal> (new RouteSignal (mr, *this, master_strip(), mcu_port()));
588                         // update strip from route
589                         master_route_signal->notify_all();
590                 }
591         }
592         
593         // sometimes the jog wheel is a pot
594         surface().blank_jog_ring (mcu_port(), builder);
595         
596         // update global buttons and displays
597         notify_record_state_changed();
598         notify_transport_state_changed();
599         update_timecode_beats_led();
600 }
601
602 void 
603 MackieControlProtocol::connect_session_signals()
604 {
605         // receive routes added
606         session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_route_added, this, _1), midi_ui_context());
607         // receive record state toggled
608         session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_record_state_changed, this), midi_ui_context());
609         // receive transport state changed
610         session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_transport_state_changed, this), midi_ui_context());
611         // receive punch-in and punch-out
612         Config->ParameterChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
613         session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
614         // receive rude solo changed
615         session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), midi_ui_context());
616
617         // make sure remote id changed signals reach here
618         // see also notify_route_added
619         Sorted sorted = get_sorted_routes();
620
621         for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
622                 (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind(&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
623         }
624 }
625
626 void 
627 MackieControlProtocol::add_port (MIDI::Port & midi_input_port, MIDI::Port & midi_output_port, int number, MackiePort::port_type_t port_type)
628 {
629         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1 %2\n", midi_input_port.name(), midi_output_port.name()));
630
631         MackiePort * sport = new MackiePort (*this, midi_input_port, midi_output_port, number, port_type);
632         _ports.push_back (sport);
633         
634         sport->init_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_init, this, sport));
635         sport->active_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_active, this, sport));
636         sport->inactive_event.connect_same_thread (port_connections, boost::bind (&MackieControlProtocol::handle_port_inactive, this, sport));
637
638         _input_bundle->add_channel (
639                 midi_input_port.name(),
640                 ARDOUR::DataType::MIDI,
641                 session->engine().make_port_name_non_relative (midi_input_port.name())
642                 );
643         
644         _output_bundle->add_channel (
645                 midi_output_port.name(),
646                 ARDOUR::DataType::MIDI,
647                 session->engine().make_port_name_non_relative (midi_output_port.name())
648                 );
649 }
650
651 void 
652 MackieControlProtocol::create_ports()
653 {
654         MIDI::Manager * mm = MIDI::Manager::instance();
655         MIDI::Port * midi_input_port = mm->add_port (
656                 new MIDI::Port (string_compose (_("%1 in"), default_port_name), MIDI::Port::IsInput, session->engine().jack())
657                 );
658         MIDI::Port * midi_output_port = mm->add_port (
659                 new MIDI::Port (string_compose (_("%1 out"), default_port_name), MIDI::Port::IsOutput, session->engine().jack())
660                 );
661
662         /* Create main port */
663
664         if (!midi_input_port->ok() || !midi_output_port->ok()) {
665                 ostringstream os;
666                 os << _("Mackie control MIDI ports could not be created; Mackie control disabled");
667                 error << os.str() << endmsg;
668                 throw MackieControlException (os.str());
669         }
670
671         add_port (*midi_input_port, *midi_output_port, 0, MackiePort::mcu);
672
673         /* Create extender ports */
674
675         for (uint32_t index = 1; index <= Config->get_mackie_extenders(); ++index) {
676                 MIDI::Port * midi_input_port = mm->add_port (
677                         new MIDI::Port (string_compose (_("mcu_xt_%1 in"), index), MIDI::Port::IsInput, session->engine().jack())
678                         );
679                 MIDI::Port * midi_output_port = mm->add_port (
680                         new MIDI::Port (string_compose (_("mcu_xt_%1 out"), index), MIDI::Port::IsOutput, session->engine().jack())
681                         );
682                 if (midi_input_port->ok() && midi_output_port->ok()) {
683                         add_port (*midi_input_port, *midi_output_port, index, MackiePort::ext);
684                 }
685         }
686 }
687
688 boost::shared_ptr<Route> 
689 MackieControlProtocol::master_route()
690 {
691         return session->master_out ();
692 }
693
694 Strip& 
695 MackieControlProtocol::master_strip()
696 {
697         return dynamic_cast<Strip&> (*surface().groups["master"]);
698 }
699
700 void 
701 MackieControlProtocol::initialize_surface()
702 {
703         // set up the route table
704         int strips = 0;
705         for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
706                 strips += (*it)->strips();
707         }
708
709         set_route_table_size (strips);
710
711         // TODO same as code in mackie_port.cc
712         string emulation = ARDOUR::Config->get_mackie_emulation();
713         if (emulation == "bcf") {
714                 _surface = new BcfSurface (strips);
715         } else if (emulation == "mcu") {
716                 _surface = new MackieSurface (strips);
717         } else {
718                 ostringstream os;
719                 os << "no Surface class found for emulation: " << emulation;
720                 throw MackieControlException (os.str());
721         }
722
723         _surface->init();
724 }
725
726 void 
727 MackieControlProtocol::close()
728 {
729
730         // must be before other shutdown otherwise polling loop
731         // calls methods on objects that are deleted
732
733         port_connections.drop_connections ();
734         session_connections.drop_connections ();
735         route_connections.drop_connections ();
736         meter_connection.disconnect ();
737
738         if (_surface != 0) {
739                 // These will fail if the port has gone away.
740                 // So catch the exception and do the rest of the
741                 // close afterwards
742                 // because the bcf doesn't respond to the next 3 sysex messages
743                 try {
744                         zero_all();
745                 }
746
747                 catch (exception & e) {
748                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::close caught exception: %1\n", e.what()));
749                 }
750
751                 for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
752                         try {
753                                 MackiePort & port = **it;
754                                 // faders to minimum
755                                 port.write_sysex (0x61);
756                                 // All LEDs off
757                                 port.write_sysex (0x62);
758                                 // Reset (reboot into offline mode)
759                                 port.write_sysex (0x63);
760                         }
761                         catch (exception & e) {
762                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::close caught exception: %1\n", e.what()));
763                         }
764                 }
765
766                 // disconnect routes from strips
767                 clear_route_signals();
768                 delete _surface;
769                 _surface = 0;
770         }
771
772         // shut down MackiePorts
773         for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
774                 delete *it;
775         }
776
777         _ports.clear();
778 }
779
780 XMLNode& 
781 MackieControlProtocol::get_state()
782 {
783         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state\n");
784
785         // add name of protocol
786         XMLNode* node = new XMLNode (X_("Protocol"));
787         node->add_property (X_("name"), ARDOUR::ControlProtocol::_name);
788
789         // add current bank
790         ostringstream os;
791         os << _current_initial_bank;
792         node->add_property (X_("bank"), os.str());
793
794         return *node;
795 }
796
797 int 
798 MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
799 {
800         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", _active));
801
802         int retval = 0;
803
804         // fetch current bank
805
806         if (node.property (X_("bank")) != 0) {
807                 string bank = node.property (X_("bank"))->value();
808                 try {
809                         set_active (true);
810                         uint32_t new_bank = atoi (bank.c_str());
811                         if (_current_initial_bank != new_bank) {
812                                 switch_banks (new_bank);
813                         }
814                 }
815                 catch (exception & e) {
816                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("exception in MackieControlProtocol::set_state: %1\n", e.what()));
817                         return -1;
818                 }
819         }
820
821         return retval;
822 }
823
824 void 
825 MackieControlProtocol::handle_control_event (SurfacePort & port, Control & control, const ControlState & state)
826 {
827         // find the route for the control, if there is one
828         boost::shared_ptr<Route> route;
829
830         if (control.group().is_strip()) {
831                 if (control.group().is_master()) {
832                         DEBUG_TRACE (DEBUG::MackieControl, "master strip control event\n");
833                         route = master_route();
834                 } else {
835                         uint32_t index = control.ordinal() - 1 + (port.number() * port.strips());
836                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip control event, index = %1, rt size = %2\n",
837                                                                            index, route_table.size()));
838                         if (index < route_table.size()) {
839                                 route = route_table[index];
840                                 if (route) {
841                                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("modifying %1\n", route->name()));
842                                 } else {
843                                         DEBUG_TRACE (DEBUG::MackieControl, "no route found!\n");
844                                 }
845                         } else {
846                                 cerr << "Warning: index is " << index << " which is not in the route table, size: " << route_table.size() << endl;
847                                 DEBUG_TRACE (DEBUG::MackieControl, "illegal route index found!\n");
848                         }
849                 }
850         }
851
852         // This handles control element events from the surface
853         // the state of the controls on the surface is usually updated
854         // from UI events.
855         switch (control.type()) {
856                 case Control::type_fader:
857                         // find the route in the route table for the id
858                         // if the route isn't available, skip it
859                         // at which point the fader should just reset itself
860                         if (route != 0)
861                         {
862                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", state.pos));
863
864                                 route->gain_control()->set_value (slider_position_to_gain (state.pos));
865
866                                 if (ARDOUR::Config->get_mackie_emulation() == "bcf") {
867                                         /* reset the timeout while we're still moving the fader */
868                                         add_in_use_timeout (port, control, control.in_use_touch_control);
869                                 }
870
871                                 // must echo bytes back to slider now, because
872                                 // the notifier only works if the fader is not being
873                                 // touched. Which it is if we're getting input.
874                                 port.write (builder.build_fader ((Fader&)control, state.pos));
875                         }
876                         break;
877
878                 case Control::type_button:
879                         if (control.group().is_strip()) {
880                                 // strips
881                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip button %1\n", control.id()));
882                                 if (route != 0) {
883                                         handle_strip_button (port, control, state.button_state, route);
884                                 } else {
885                                         // no route so always switch the light off
886                                         // because no signals will be emitted by a non-route
887                                         port.write (builder.build_led (control.led(), off));
888                                 }
889                         } else if (control.group().is_master()) {
890                                 // master fader touch
891                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("master strip button %1\n", control.id()));
892                                 if (route != 0) {
893                                         handle_strip_button (port, control, state.button_state, route);
894                                 }
895                         } else {
896                                 // handle all non-strip buttons
897                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("global button %1\n", control.id()));
898                                 surface().handle_button (*this, state.button_state, dynamic_cast<Button&> (control));
899                         }
900                         break;
901
902                 // pot (jog wheel, external control)
903                 case Control::type_pot:
904                         if (control.group().is_strip()) {
905                                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip pot %1\n", control.id()));
906                                 if (route) {
907                                         boost::shared_ptr<Panner> panner = route->panner_shell()->panner();
908                                         // pan for mono input routes, or stereo linked panners
909                                         if (panner) {
910                                                 double p = panner->position ();
911                                                 
912                                                 // calculate new value, and adjust
913                                                 p += state.delta * state.sign;
914                                                 p = min (1.0, p);
915                                                 p = max (0.0, p);
916                                                 panner->set_position (p);
917                                         }
918                                 } else {
919                                         // it's a pot for an umnapped route, so turn all the lights off
920                                         port.write (builder.build_led_ring (dynamic_cast<Pot &> (control), off));
921                                 }
922                         } else {
923                                 if (control.is_jog()) {
924                                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Jog wheel moved %1\n", state.ticks));
925                                         _jog_wheel.jog_event (port, control, state);
926                                 } else {
927                                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("External controller moved %1\n", state.ticks));
928                                         cout << "external controller" << state.ticks * state.sign << endl;
929                                 }
930                         }
931                         break;
932
933                 default:
934                         cout << "Control::type not handled: " << control.type() << endl;
935         }
936 }
937
938 /////////////////////////////////////////////////
939 // handlers for Route signals
940 // TODO should these be part of RouteSignal?
941 // They started off as signal/slot handlers for signals
942 // from Route, but they're also used in polling for automation
943 /////////////////////////////////////////////////
944
945 void 
946 MackieControlProtocol::notify_solo_changed (RouteSignal * route_signal)
947 {
948         try {
949                 Button & button = route_signal->strip().solo();
950                 route_signal->port().write (builder.build_led (button, route_signal->route()->soloed()));
951         }
952         catch (exception & e) {
953                 cout << e.what() << endl;
954         }
955 }
956
957 void 
958 MackieControlProtocol::notify_mute_changed (RouteSignal * route_signal)
959 {
960         try {
961                 Button & button = route_signal->strip().mute();
962                 route_signal->port().write (builder.build_led (button, route_signal->route()->muted()));
963         }
964         catch (exception & e) {
965                 cout << e.what() << endl;
966         }
967 }
968
969 void 
970 MackieControlProtocol::notify_record_enable_changed (RouteSignal * route_signal)
971 {
972         try {
973                 Button & button = route_signal->strip().recenable();
974                 route_signal->port().write (builder.build_led (button, route_signal->route()->record_enabled()));
975         }
976         catch (exception & e) {
977                 cout << e.what() << endl;
978         }
979 }
980
981 void MackieControlProtocol::notify_active_changed (RouteSignal *)
982 {
983         try {
984                 DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::notify_active_changed\n");
985                 refresh_current_bank();
986         }
987         catch (exception & e) {
988                 cout << e.what() << endl;
989         }
990 }
991
992 void 
993 MackieControlProtocol::notify_gain_changed (RouteSignal * route_signal, bool force_update)
994 {
995         try {
996                 Fader & fader = route_signal->strip().gain();
997                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("route %1 gain change, update fader %2 on port %3\n", 
998                                                                    route_signal->route()->name(), 
999                                                                    fader.raw_id(),
1000                                                                    route_signal->port().output_port().name()));
1001                 if (!fader.in_use()) {
1002                         float gain_value = gain_to_slider_position (route_signal->route()->gain_control()->get_value());
1003                         // check that something has actually changed
1004                         if (force_update || gain_value != route_signal->last_gain_written()) {
1005                                 route_signal->port().write (builder.build_fader (fader, gain_value));
1006                                 route_signal->last_gain_written (gain_value);
1007                         }
1008                 }
1009         }
1010         catch (exception & e) {
1011                 cout << e.what() << endl;
1012         }
1013 }
1014
1015 void 
1016 MackieControlProtocol::notify_property_changed (const PropertyChange& what_changed, RouteSignal * route_signal)
1017 {
1018         if (!what_changed.contains (Properties::name)) {
1019                 return;
1020         }
1021
1022         try {
1023                 Strip & strip = route_signal->strip();
1024                 
1025                 if (!strip.is_master()) {
1026                         string line1;
1027                         string fullname = route_signal->route()->name();
1028
1029                         if (fullname.length() <= 6) {
1030                                 line1 = fullname;
1031                         } else {
1032                                 line1 = PBD::short_version (fullname, 6);
1033                         }
1034
1035 #ifdef NUCLEUS_DEBUG
1036                         cerr << "show strip name from " << fullname << " as " << line1 << endl;
1037 #endif
1038
1039                         SurfacePort & port = route_signal->port();
1040                         port.write (builder.strip_display (port, strip, 0, line1));
1041                         port.write (builder.strip_display_blank (port, strip, 1));
1042                 }
1043         }
1044         catch (exception & e) {
1045                 cout << e.what() << endl;
1046         }
1047 }
1048
1049 void 
1050 MackieControlProtocol::notify_panner_changed (RouteSignal * route_signal, bool force_update)
1051 {
1052         try {
1053                 Pot & pot = route_signal->strip().vpot();
1054                 boost::shared_ptr<Panner> panner = route_signal->route()->panner();
1055                 if (panner) {
1056                         double pos = panner->position ();
1057
1058                         // cache the MidiByteArray here, because the mackie led control is much lower
1059                         // resolution than the panner control. So we save lots of byte
1060                         // sends in spite of more work on the comparison
1061                         MidiByteArray bytes = builder.build_led_ring (pot, ControlState (on, pos), MackieMidiBuilder::midi_pot_mode_dot);
1062                         // check that something has actually changed
1063                         if (force_update || bytes != route_signal->last_pan_written())
1064                         {
1065                                 route_signal->port().write (bytes);
1066                                 route_signal->last_pan_written (bytes);
1067                         }
1068                 } else {
1069                         route_signal->port().write (builder.zero_control (pot));
1070                 }
1071         }
1072         catch (exception & e) {
1073                 cout << e.what() << endl;
1074         }
1075 }
1076
1077 // TODO handle plugin automation polling
1078 void 
1079 MackieControlProtocol::update_automation (RouteSignal & rs)
1080 {
1081         ARDOUR::AutoState gain_state = rs.route()->gain_control()->automation_state();
1082
1083         if (gain_state == Touch || gain_state == Play) {
1084                 notify_gain_changed (&rs, false);
1085         }
1086
1087         if (rs.route()->panner()) {
1088                 ARDOUR::AutoState panner_state = rs.route()->panner()->automation_state();
1089                 if (panner_state == Touch || panner_state == Play) {
1090                         notify_panner_changed (&rs, false);
1091                 }
1092         }
1093 }
1094
1095 string 
1096 MackieControlProtocol::format_bbt_timecode (framepos_t now_frame)
1097 {
1098         Timecode::BBT_Time bbt_time;
1099         session->bbt_time (now_frame, bbt_time);
1100
1101         // According to the Logic docs
1102         // digits: 888/88/88/888
1103         // BBT mode: Bars/Beats/Subdivisions/Ticks
1104         ostringstream os;
1105         os << setw(3) << setfill('0') << bbt_time.bars;
1106         os << setw(2) << setfill('0') << bbt_time.beats;
1107
1108         // figure out subdivisions per beat
1109         const ARDOUR::Meter & meter = session->tempo_map().meter_at (now_frame);
1110         int subdiv = 2;
1111         if (meter.note_divisor() == 8 && (meter.divisions_per_bar() == 12.0 || meter.divisions_per_bar() == 9.0 || meter.divisions_per_bar() == 6.0)) {
1112                 subdiv = 3;
1113         }
1114
1115         uint32_t subdivisions = bbt_time.ticks / uint32_t (Timecode::BBT_Time::ticks_per_beat / subdiv);
1116         uint32_t ticks = bbt_time.ticks % uint32_t (Timecode::BBT_Time::ticks_per_beat / subdiv);
1117
1118         os << setw(2) << setfill('0') << subdivisions + 1;
1119         os << setw(3) << setfill('0') << ticks;
1120
1121         return os.str();
1122 }
1123
1124 string 
1125 MackieControlProtocol::format_timecode_timecode (framepos_t now_frame)
1126 {
1127         Timecode::Time timecode;
1128         session->timecode_time (now_frame, timecode);
1129
1130         // According to the Logic docs
1131         // digits: 888/88/88/888
1132         // Timecode mode: Hours/Minutes/Seconds/Frames
1133         ostringstream os;
1134         os << setw(3) << setfill('0') << timecode.hours;
1135         os << setw(2) << setfill('0') << timecode.minutes;
1136         os << setw(2) << setfill('0') << timecode.seconds;
1137         os << setw(3) << setfill('0') << timecode.frames;
1138
1139         return os.str();
1140 }
1141
1142 void 
1143 MackieControlProtocol::update_timecode_display()
1144 {
1145         if (surface().has_timecode_display()) {
1146                 // do assignment here so current_frame is fixed
1147                 framepos_t current_frame = session->transport_frame();
1148                 string timecode;
1149
1150                 switch (_timecode_type) {
1151                         case ARDOUR::AnyTime::BBT:
1152                                 timecode = format_bbt_timecode (current_frame);
1153                                 break;
1154                         case ARDOUR::AnyTime::Timecode:
1155                                 timecode = format_timecode_timecode (current_frame);
1156                                 break;
1157                         default:
1158                                 ostringstream os;
1159                                 os << "Unknown timecode: " << _timecode_type;
1160                                 throw runtime_error (os.str());
1161                 }
1162
1163                 // only write the timecode string to the MCU if it's changed
1164                 // since last time. This is to reduce midi bandwidth used.
1165                 if (timecode != _timecode_last) {
1166                         surface().display_timecode (mcu_port(), builder, timecode, _timecode_last);
1167                         _timecode_last = timecode;
1168                 }
1169         }
1170 }
1171
1172 void 
1173 MackieControlProtocol::poll_session_data()
1174 {
1175         if (_active) {
1176                 // do all currently mapped routes
1177                 {
1178                         Glib::Mutex::Lock lm (route_signals_lock);
1179                         for (RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it) {
1180                                 update_automation (**it);
1181                         }
1182                 }
1183
1184                 // and the master strip
1185                 if (master_route_signal != 0) {
1186                         update_automation (*master_route_signal);
1187                 }
1188
1189                 update_timecode_display();
1190         }
1191 }
1192
1193 /////////////////////////////////////
1194 // Transport Buttons
1195 /////////////////////////////////////
1196
1197 LedState 
1198 MackieControlProtocol::frm_left_press (Button &)
1199 {
1200         // can use first_mark_before/after as well
1201         unsigned long elapsed = _frm_left_last.restart();
1202
1203         Location * loc = session->locations()->first_location_before (
1204                 session->transport_frame()
1205         );
1206
1207         // allow a quick double to go past a previous mark
1208         if (session->transport_rolling() && elapsed < 500 && loc != 0) {
1209                 Location * loc_two_back = session->locations()->first_location_before (loc->start());
1210                 if (loc_two_back != 0)
1211                 {
1212                         loc = loc_two_back;
1213                 }
1214         }
1215
1216         // move to the location, if it's valid
1217         if (loc != 0) {
1218                 session->request_locate (loc->start(), session->transport_rolling());
1219         }
1220
1221         return on;
1222 }
1223
1224 LedState 
1225 MackieControlProtocol::frm_left_release (Button &)
1226 {
1227         return off;
1228 }
1229
1230 LedState 
1231 MackieControlProtocol::frm_right_press (Button &)
1232 {
1233         // can use first_mark_before/after as well
1234         Location * loc = session->locations()->first_location_after (session->transport_frame());
1235         
1236         if (loc != 0) {
1237                 session->request_locate (loc->start(), session->transport_rolling());
1238         }
1239                 
1240         return on;
1241 }
1242
1243 LedState 
1244 MackieControlProtocol::frm_right_release (Button &)
1245 {
1246         return off;
1247 }
1248
1249 LedState 
1250 MackieControlProtocol::stop_press (Button &)
1251 {
1252         session->request_stop();
1253         return on;
1254 }
1255
1256 LedState 
1257 MackieControlProtocol::stop_release (Button &)
1258 {
1259         return session->transport_stopped();
1260 }
1261
1262 LedState 
1263 MackieControlProtocol::play_press (Button &)
1264 {
1265         session->request_transport_speed (1.0);
1266         return on;
1267 }
1268
1269 LedState 
1270 MackieControlProtocol::play_release (Button &)
1271 {
1272         return session->transport_rolling();
1273 }
1274
1275 LedState 
1276 MackieControlProtocol::record_press (Button &)
1277 {
1278         if (session->get_record_enabled()) {
1279                 session->disable_record (false);
1280         } else {
1281                 session->maybe_enable_record();
1282         }
1283         return on;
1284 }
1285
1286 LedState 
1287 MackieControlProtocol::record_release (Button &)
1288 {
1289         if (session->get_record_enabled()) {
1290                 if (session->transport_rolling()) {
1291                         return on;
1292                 } else {
1293                         return flashing;
1294                 }
1295         } else {
1296                 return off;
1297         }
1298 }
1299
1300 LedState 
1301 MackieControlProtocol::rewind_press (Button &)
1302 {
1303         _jog_wheel.push (JogWheel::speed);
1304         _jog_wheel.transport_direction (-1);
1305         session->request_transport_speed (-_jog_wheel.transport_speed());
1306         return on;
1307 }
1308
1309 LedState 
1310 MackieControlProtocol::rewind_release (Button &)
1311 {
1312         _jog_wheel.pop();
1313         _jog_wheel.transport_direction (0);
1314         if (_transport_previously_rolling) {
1315                 session->request_transport_speed (1.0);
1316         } else {
1317                 session->request_stop();
1318         }
1319         return off;
1320 }
1321
1322 LedState 
1323 MackieControlProtocol::ffwd_press (Button &)
1324 {
1325         _jog_wheel.push (JogWheel::speed);
1326         _jog_wheel.transport_direction (1);
1327         session->request_transport_speed (_jog_wheel.transport_speed());
1328         return on;
1329 }
1330
1331 LedState 
1332 MackieControlProtocol::ffwd_release (Button &)
1333 {
1334         _jog_wheel.pop();
1335         _jog_wheel.transport_direction (0);
1336         if (_transport_previously_rolling) {
1337                 session->request_transport_speed (1.0);
1338         } else {
1339                 session->request_stop();
1340         }
1341         return off;
1342 }
1343
1344 LedState 
1345 MackieControlProtocol::loop_press (Button &)
1346 {
1347         session->request_play_loop (!session->get_play_loop());
1348         return on;
1349 }
1350
1351 LedState 
1352 MackieControlProtocol::loop_release (Button &)
1353 {
1354         return session->get_play_loop();
1355 }
1356
1357 LedState 
1358 MackieControlProtocol::punch_in_press (Button &)
1359 {
1360         bool const state = !session->config.get_punch_in();
1361         session->config.set_punch_in (state);
1362         return state;
1363 }
1364
1365 LedState 
1366 MackieControlProtocol::punch_in_release (Button &)
1367 {
1368         return session->config.get_punch_in();
1369 }
1370
1371 LedState 
1372 MackieControlProtocol::punch_out_press (Button &)
1373 {
1374         bool const state = !session->config.get_punch_out();
1375         session->config.set_punch_out (state);
1376         return state;
1377 }
1378
1379 LedState 
1380 MackieControlProtocol::punch_out_release (Button &)
1381 {
1382         return session->config.get_punch_out();
1383 }
1384
1385 LedState 
1386 MackieControlProtocol::home_press (Button &)
1387 {
1388         session->goto_start();
1389         return on;
1390 }
1391
1392 LedState 
1393 MackieControlProtocol::home_release (Button &)
1394 {
1395         return off;
1396 }
1397
1398 LedState 
1399 MackieControlProtocol::end_press (Button &)
1400 {
1401         session->goto_end();
1402         return on;
1403 }
1404
1405 LedState 
1406 MackieControlProtocol::end_release (Button &)
1407 {
1408         return off;
1409 }
1410
1411 LedState 
1412 MackieControlProtocol::clicking_press (Button &)
1413 {
1414         bool state = !Config->get_clicking();
1415         Config->set_clicking (state);
1416         return state;
1417 }
1418
1419 LedState 
1420 MackieControlProtocol::clicking_release (Button &)
1421 {
1422         return Config->get_clicking();
1423 }
1424
1425 LedState MackieControlProtocol::global_solo_press (Button &)
1426 {
1427         bool state = !session->soloing();
1428         session->set_solo (session->get_routes(), state);
1429         return state;
1430 }
1431
1432 LedState MackieControlProtocol::global_solo_release (Button &)
1433 {
1434         return session->soloing();
1435 }
1436
1437 ///////////////////////////////////////////
1438 // Session signals
1439 ///////////////////////////////////////////
1440
1441 void MackieControlProtocol::notify_parameter_changed (std::string const & p)
1442 {
1443         if (p == "punch-in") {
1444                 update_global_button ("punch_in", session->config.get_punch_in());
1445         } else if (p == "punch-out") {
1446                 update_global_button ("punch_out", session->config.get_punch_out());
1447         } else if (p == "clicking") {
1448                 update_global_button ("clicking", Config->get_clicking());
1449         } else {
1450                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("parameter changed: %1\n", p));
1451         }
1452 }
1453
1454 // RouteList is the set of routes that have just been added
1455 void 
1456 MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
1457 {
1458         // currently assigned banks are less than the full set of
1459         // strips, so activate the new strip now.
1460
1461         {
1462                 Glib::Mutex::Lock lm (route_signals_lock);
1463                 if (route_signals.size() < route_table.size()) {
1464                         refresh_current_bank();
1465                 }
1466         }
1467
1468         // otherwise route added, but current bank needs no updating
1469
1470         // make sure remote id changes in the new route are handled
1471         typedef ARDOUR::RouteList ARS;
1472
1473         for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
1474                 (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
1475         }
1476 }
1477
1478 void 
1479 MackieControlProtocol::notify_solo_active_changed (bool active)
1480 {
1481         Button * rude_solo = reinterpret_cast<Button*> (surface().controls_by_name["solo"]);
1482         mcu_port().write (builder.build_led (*rude_solo, active ? flashing : off));
1483 }
1484
1485 void 
1486 MackieControlProtocol::notify_remote_id_changed()
1487 {
1488         Sorted sorted = get_sorted_routes();
1489
1490         // if a remote id has been moved off the end, we need to shift
1491         // the current bank backwards.
1492
1493         uint32_t sz;
1494
1495         {
1496                 Glib::Mutex::Lock lm (route_signals_lock);
1497                 sz = route_signals.size();
1498         }
1499
1500         if (sorted.size() - _current_initial_bank < sz) {
1501                 // but don't shift backwards past the zeroth channel
1502                 switch_banks (max((Sorted::size_type) 0, sorted.size() - sz));
1503         } else {
1504                 // Otherwise just refresh the current bank
1505                 refresh_current_bank();
1506         }
1507 }
1508
1509 ///////////////////////////////////////////
1510 // Transport signals
1511 ///////////////////////////////////////////
1512
1513 void 
1514 MackieControlProtocol::notify_record_state_changed()
1515 {
1516         // switch rec button on / off / flashing
1517         Button * rec = reinterpret_cast<Button*> (surface().controls_by_name["record"]);
1518         mcu_port().write (builder.build_led (*rec, record_release (*rec)));
1519 }
1520
1521 void 
1522 MackieControlProtocol::notify_transport_state_changed()
1523 {
1524         // switch various play and stop buttons on / off
1525         update_global_button ("play", session->transport_rolling());
1526         update_global_button ("stop", !session->transport_rolling());
1527         update_global_button ("loop", session->get_play_loop());
1528
1529         _transport_previously_rolling = session->transport_rolling();
1530
1531         // rec is special because it's tristate
1532         Button * rec = reinterpret_cast<Button*> (surface().controls_by_name["record"]);
1533         mcu_port().write (builder.build_led (*rec, record_release (*rec)));
1534 }
1535
1536 /////////////////////////////////////
1537 // Bank Switching
1538 /////////////////////////////////////
1539 LedState 
1540 MackieControlProtocol::left_press (Button &)
1541 {
1542         Sorted sorted = get_sorted_routes();
1543         if (sorted.size() > route_table.size()) {
1544                 int new_initial = _current_initial_bank - route_table.size();
1545                 if (new_initial < 0) {
1546                         new_initial = 0;
1547                 }
1548                 
1549                 if (new_initial != int (_current_initial_bank)) {
1550                         session->set_dirty();
1551                         switch_banks (new_initial);
1552                 }
1553
1554                 return on;
1555         } else {
1556                 return flashing;
1557         }
1558 }
1559
1560 LedState 
1561 MackieControlProtocol::left_release (Button &)
1562 {
1563         return off;
1564 }
1565
1566 LedState 
1567 MackieControlProtocol::right_press (Button &)
1568 {
1569         Sorted sorted = get_sorted_routes();
1570         if (sorted.size() > route_table.size()) {
1571                 uint32_t delta = sorted.size() - (route_table.size() + _current_initial_bank);
1572
1573                 if (delta > route_table.size()) {
1574                         delta = route_table.size();
1575                 }
1576                 
1577                 if (delta > 0) {
1578                         session->set_dirty();
1579                         switch_banks (_current_initial_bank + delta);
1580                 }
1581
1582                 return on;
1583         } else {
1584                 return flashing;
1585         }
1586 }
1587
1588 LedState 
1589 MackieControlProtocol::right_release (Button &)
1590 {
1591         return off;
1592 }
1593
1594 LedState 
1595 MackieControlProtocol::channel_left_press (Button &)
1596 {
1597         Sorted sorted = get_sorted_routes();
1598         if (sorted.size() > route_table.size()) {
1599                 prev_track();
1600                 return on;
1601         } else {
1602                 return flashing;
1603         }
1604 }
1605
1606 LedState 
1607 MackieControlProtocol::channel_left_release (Button &)
1608 {
1609         return off;
1610 }
1611
1612 LedState 
1613 MackieControlProtocol::channel_right_press (Button &)
1614 {
1615         Sorted sorted = get_sorted_routes();
1616         if (sorted.size() > route_table.size()) {
1617                 next_track();
1618                 return on;
1619         } else {
1620                 return flashing;
1621         }
1622 }
1623
1624 LedState 
1625 MackieControlProtocol::channel_right_release (Button &)
1626 {
1627         return off;
1628 }
1629
1630 /////////////////////////////////////
1631 // Functions
1632 /////////////////////////////////////
1633 LedState 
1634 MackieControlProtocol::marker_press (Button &)
1635 {
1636         // cut'n'paste from LocationUI::add_new_location()
1637         string markername;
1638         framepos_t where = session->audible_frame();
1639         session->locations()->next_available_name(markername,"mcu");
1640         Location *location = new Location (*session, where, where, markername, Location::IsMark);
1641         session->begin_reversible_command (_("add marker"));
1642         XMLNode &before = session->locations()->get_state();
1643         session->locations()->add (location, true);
1644         XMLNode &after = session->locations()->get_state();
1645         session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
1646         session->commit_reversible_command ();
1647         return on;
1648 }
1649
1650 LedState 
1651 MackieControlProtocol::marker_release (Button &)
1652 {
1653         return off;
1654 }
1655
1656 void 
1657 jog_wheel_state_display (JogWheel::State state, SurfacePort & port)
1658 {
1659         switch (state) {
1660                 case JogWheel::zoom:
1661                         port.write (builder.two_char_display ("Zm"));
1662                         break;
1663                 case JogWheel::scroll:
1664                         port.write (builder.two_char_display ("Sc"));
1665                         break;
1666                 case JogWheel::scrub:
1667                         port.write (builder.two_char_display ("Sb"));
1668                         break;
1669                 case JogWheel::shuttle:
1670                         port.write (builder.two_char_display ("Sh"));
1671                         break;
1672                 case JogWheel::speed:
1673                         port.write (builder.two_char_display ("Sp"));
1674                         break;
1675                 case JogWheel::select:
1676                         port.write (builder.two_char_display ("Se"));
1677                         break;
1678         }
1679 }
1680
1681 Mackie::LedState 
1682 MackieControlProtocol::zoom_press (Mackie::Button &)
1683 {
1684         _jog_wheel.zoom_state_toggle();
1685         update_global_button ("scrub", _jog_wheel.jog_wheel_state() == JogWheel::scrub);
1686         jog_wheel_state_display (_jog_wheel.jog_wheel_state(), mcu_port());
1687         return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
1688 }
1689
1690 Mackie::LedState 
1691 MackieControlProtocol::zoom_release (Mackie::Button &)
1692 {
1693         return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
1694 }
1695
1696 Mackie::LedState 
1697 MackieControlProtocol::scrub_press (Mackie::Button &)
1698 {
1699         _jog_wheel.scrub_state_cycle();
1700         update_global_button ("zoom", _jog_wheel.jog_wheel_state() == JogWheel::zoom);
1701         jog_wheel_state_display (_jog_wheel.jog_wheel_state(), mcu_port());
1702         return (
1703                 _jog_wheel.jog_wheel_state() == JogWheel::scrub
1704                 ||
1705                 _jog_wheel.jog_wheel_state() == JogWheel::shuttle
1706                 );
1707 }
1708
1709 Mackie::LedState 
1710 MackieControlProtocol::scrub_release (Mackie::Button &)
1711 {
1712         return (
1713                 _jog_wheel.jog_wheel_state() == JogWheel::scrub
1714                 ||
1715                 _jog_wheel.jog_wheel_state() == JogWheel::shuttle
1716                 );
1717 }
1718
1719 LedState 
1720 MackieControlProtocol::drop_press (Button &)
1721 {
1722         session->remove_last_capture();
1723         return on;
1724 }
1725
1726 LedState 
1727 MackieControlProtocol::drop_release (Button &)
1728 {
1729         return off;
1730 }
1731
1732 LedState 
1733 MackieControlProtocol::save_press (Button &)
1734 {
1735         session->save_state ("");
1736         return on;
1737 }
1738
1739 LedState 
1740 MackieControlProtocol::save_release (Button &)
1741 {
1742         return off;
1743 }
1744
1745 LedState 
1746 MackieControlProtocol::timecode_beats_press (Button &)
1747 {
1748         switch (_timecode_type) {
1749         case ARDOUR::AnyTime::BBT:
1750                 _timecode_type = ARDOUR::AnyTime::Timecode;
1751                 break;
1752         case ARDOUR::AnyTime::Timecode:
1753                 _timecode_type = ARDOUR::AnyTime::BBT;
1754                 break;
1755         default:
1756                 ostringstream os;
1757                 os << "Unknown Anytime::Type " << _timecode_type;
1758                 throw runtime_error (os.str());
1759         }
1760         update_timecode_beats_led();
1761         return on;
1762 }
1763
1764 LedState 
1765 MackieControlProtocol::timecode_beats_release (Button &)
1766 {
1767         return off;
1768 }
1769
1770 list<boost::shared_ptr<ARDOUR::Bundle> >
1771 MackieControlProtocol::bundles ()
1772 {
1773         list<boost::shared_ptr<ARDOUR::Bundle> > b;
1774         b.push_back (_input_bundle);
1775         b.push_back (_output_bundle);
1776         return b;
1777 }
1778
1779 void
1780 MackieControlProtocol::port_connected_or_disconnected (string a, string b, bool connected)
1781 {
1782         /* If something is connected to one of our output ports, send MIDI to update the surface
1783            to whatever state it should have.
1784         */
1785
1786         if (!connected) {
1787                 return;
1788         }
1789
1790         MackiePorts::const_iterator i = _ports.begin();
1791         while (i != _ports.end()) {
1792
1793                 string const n = AudioEngine::instance()->make_port_name_non_relative ((*i)->output_port().name ());
1794
1795                 if (a == n || b == n) {
1796                         break;
1797                 }
1798
1799                 ++i;
1800         }
1801
1802         if (i != _ports.end ()) {
1803                 update_surface ();
1804         }
1805 }
1806
1807 void
1808 MackieControlProtocol::do_request (MackieControlUIRequest* req)
1809 {
1810         if (req->type == CallSlot) {
1811
1812                 call_slot (MISSING_INVALIDATOR, req->the_slot);
1813
1814         } else if (req->type == Quit) {
1815
1816                 stop ();
1817         }
1818 }
1819
1820 int
1821 MackieControlProtocol::stop ()
1822 {
1823         BaseUI::quit ();
1824
1825         return 0;
1826 }
1827
1828 /** Add a timeout so that a control's in_use flag will be reset some time in the future.
1829  *  @param in_use_control the control whose in_use flag to reset.
1830  *  @param touch_control a touch control to emit an event for, or 0.
1831  */
1832 void
1833 MackieControlProtocol::add_in_use_timeout (SurfacePort& port, Control& in_use_control, Control* touch_control)
1834 {
1835         Glib::RefPtr<Glib::TimeoutSource> timeout (Glib::TimeoutSource::create (250)); // milliseconds
1836
1837         in_use_control.in_use_connection.disconnect ();
1838         in_use_control.in_use_connection = timeout->connect (
1839                 sigc::bind (sigc::mem_fun (*this, &MackieControlProtocol::control_in_use_timeout), &port, &in_use_control, touch_control));
1840         in_use_control.in_use_touch_control = touch_control;
1841
1842         timeout->attach (main_loop()->get_context());
1843
1844         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for port %1, control %2 touch control %3\n",
1845                                                            &port, &in_use_control, touch_control));}
1846
1847 /** Handle timeouts to reset in_use for controls that can't
1848  *  do this by themselves (e.g. pots, and faders without touch support).
1849  *  @param in_use_control the control whose in_use flag to reset.
1850  *  @param touch_control a touch control to emit an event for, or 0.
1851  */
1852 bool
1853 MackieControlProtocol::control_in_use_timeout (SurfacePort* port, Control* in_use_control, Control* touch_control)
1854 {
1855         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout elapsed for port %1, control %2 touch control %3\n",
1856                                                            port, in_use_control, touch_control));
1857
1858         in_use_control->set_in_use (false);
1859
1860         if (touch_control) {
1861                 // empty control_state
1862                 ControlState control_state;
1863                 handle_control_event (*port, *touch_control, control_state);
1864         }
1865         
1866         // only call this method once from the timer
1867         return false;
1868 }
1869