MCP: tweak operation of most transport buttons, make save button work, start using...
[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 "pbd/pthread_utils.h"
38 #include "pbd/error.h"
39 #include "pbd/memento_command.h"
40 #include "pbd/convert.h"
41
42 #include "ardour/dB.h"
43 #include "ardour/debug.h"
44 #include "ardour/location.h"
45 #include "ardour/meter.h"
46 #include "ardour/panner.h"
47 #include "ardour/panner_shell.h"
48 #include "ardour/route.h"
49 #include "ardour/session.h"
50 #include "ardour/tempo.h"
51 #include "ardour/types.h"
52 #include "ardour/audioengine.h"
53
54 #include "mackie_control_protocol.h"
55
56 #include "midi_byte_array.h"
57 #include "mackie_control_exception.h"
58 #include "mackie_midi_builder.h"
59 #include "surface_port.h"
60 #include "surface.h"
61
62 #include "strip.h"
63 #include "control_group.h"
64 #include "meter.h"
65 #include "button.h"
66 #include "fader.h"
67 #include "pot.h"
68
69 using namespace ARDOUR;
70 using namespace std;
71 using namespace Mackie;
72 using namespace PBD;
73 using namespace Glib;
74
75 #include "i18n.h"
76
77 #include "pbd/abstract_ui.cc" // instantiate template
78
79 #define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__))
80
81 const int MackieControlProtocol::MODIFIER_OPTION = 0x1;
82 const int MackieControlProtocol::MODIFIER_CONTROL = 0x2;
83 const int MackieControlProtocol::MODIFIER_SHIFT = 0x3;
84 const int MackieControlProtocol::MODIFIER_CMDALT = 0x4;
85
86 MackieControlProtocol* MackieControlProtocol::_instance = 0;
87
88 bool MackieControlProtocol::probe()
89 {
90         return true;
91 }
92
93 MackieControlProtocol::MackieControlProtocol (Session& session)
94         : ControlProtocol (session, X_("Mackie"), this)
95         , AbstractUI<MackieControlUIRequest> ("mackie")
96         , _current_initial_bank (0)
97         , _timecode_type (ARDOUR::AnyTime::BBT)
98         , _input_bundle (new ARDOUR::Bundle (_("Mackie Control In"), true))
99         , _output_bundle (new ARDOUR::Bundle (_("Mackie Control Out"), false))
100         , _gui (0)
101         , _zoom_mode (false)
102         , _scrub_mode (false)
103         , _flip_mode (false)
104         , _current_selected_track (-1)
105 {
106         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
107
108         AudioEngine::instance()->PortConnectedOrDisconnected.connect (
109                 audio_engine_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
110                 this
111                 );
112
113         _instance = this;
114 }
115
116 MackieControlProtocol::~MackieControlProtocol()
117 {
118         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol\n");
119
120         _active = false;
121
122         try {
123                 close();
124         }
125         catch (exception & e) {
126                 cout << "~MackieControlProtocol caught " << e.what() << endl;
127         }
128         catch (...) {
129                 cout << "~MackieControlProtocol caught unknown" << endl;
130         }
131
132         DEBUG_TRACE (DEBUG::MackieControl, "finished ~MackieControlProtocol::MackieControlProtocol\n");
133
134         _instance = 0;
135 }
136
137 void
138 MackieControlProtocol::thread_init ()
139 {
140         struct sched_param rtparam;
141
142         pthread_set_name (X_("MackieControl"));
143
144         PBD::notify_gui_about_thread_creation (X_("gui"), pthread_self(), X_("MackieControl"), 2048);
145         ARDOUR::SessionEvent::create_per_thread_pool (X_("MackieControl"), 128);
146
147         memset (&rtparam, 0, sizeof (rtparam));
148         rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
149
150         if (pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam) != 0) {
151                 // do we care? not particularly.
152         }
153 }
154
155 // go to the previous track.
156 // Assume that get_sorted_routes().size() > route_table.size()
157 void 
158 MackieControlProtocol::prev_track()
159 {
160         if (_current_initial_bank >= 1) {
161                 session->set_dirty();
162                 switch_banks (_current_initial_bank - 1);
163         }
164 }
165
166 // go to the next track.
167 // Assume that get_sorted_routes().size() > route_table.size()
168 void 
169 MackieControlProtocol::next_track()
170 {
171         Sorted sorted = get_sorted_routes();
172         if (_current_initial_bank + n_strips() < sorted.size()) {
173                 session->set_dirty();
174                 switch_banks (_current_initial_bank + 1);
175         }
176 }
177
178 // predicate for sort call in get_sorted_routes
179 struct RouteByRemoteId
180 {
181         bool operator () (const boost::shared_ptr<Route> & a, const boost::shared_ptr<Route> & b) const
182         {
183                 return a->remote_control_id() < b->remote_control_id();
184         }
185
186         bool operator () (const Route & a, const Route & b) const
187         {
188                 return a.remote_control_id() < b.remote_control_id();
189         }
190
191         bool operator () (const Route * a, const Route * b) const
192         {
193                 return a->remote_control_id() < b->remote_control_id();
194         }
195 };
196
197 MackieControlProtocol::Sorted 
198 MackieControlProtocol::get_sorted_routes()
199 {
200         Sorted sorted;
201
202         // fetch all routes
203         boost::shared_ptr<RouteList> routes = session->get_routes();
204         set<uint32_t> remote_ids;
205
206         // routes with remote_id 0 should never be added
207         // TODO verify this with ardour devs
208         // remote_ids.insert (0);
209
210         // sort in remote_id order, and exclude master, control and hidden routes
211         // and any routes that are already set.
212         for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it) {
213                 Route & route = **it;
214                 if (
215                         route.active()
216                         && !route.is_master()
217                         && !route.is_hidden()
218                         && !route.is_monitor()
219                         && remote_ids.find (route.remote_control_id()) == remote_ids.end()
220                         ) {
221                         sorted.push_back (*it);
222                         remote_ids.insert (route.remote_control_id());
223                 }
224         }
225         sort (sorted.begin(), sorted.end(), RouteByRemoteId());
226         return sorted;
227 }
228
229 void 
230 MackieControlProtocol::refresh_current_bank()
231 {
232         switch_banks (_current_initial_bank, true);
233 }
234
235 uint32_t
236 MackieControlProtocol::n_strips() const
237 {
238         uint32_t strip_count = 0;
239
240         for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
241                 if ((*si)->active()) {
242                         strip_count += (*si)->n_strips ();
243                 }
244         }
245
246         return strip_count;
247 }
248
249 void 
250 MackieControlProtocol::switch_banks (uint32_t initial, bool force)
251 {
252         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch banking to start at %1 force ? %2 current = %3\n", initial, force, _current_initial_bank));
253
254         if (initial == _current_initial_bank && !force) {
255                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
256                 return;
257         }
258
259         Sorted sorted = get_sorted_routes();
260         uint32_t strip_cnt = n_strips();
261
262         if (sorted.size() <= strip_cnt && !force) {
263                 /* no banking */
264                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
265                 return;
266         }
267
268         uint32_t delta = sorted.size() - strip_cnt;
269
270         if (delta > 0 && initial > delta) {
271                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
272                 return;
273         }
274
275         _current_initial_bank = initial;
276         _current_selected_track = -1;
277
278         for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
279                 (*si)->drop_routes ();
280         }
281
282         // Map current bank of routes onto each surface(+strip)
283
284         if (_current_initial_bank <= sorted.size()) {
285
286                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to %1, %2, available routes %3\n", _current_initial_bank, strip_cnt, sorted.size()));
287
288                 // link routes to strips
289
290                 Sorted::iterator r = sorted.begin() + _current_initial_bank;
291                 
292                 for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
293                         vector<boost::shared_ptr<Route> > routes;
294                         uint32_t added = 0;
295
296                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface has %1 strips\n", (*si)->n_strips()));
297
298                         for (; r != sorted.end() && added < (*si)->n_strips(); ++r, ++added) {
299                                 routes.push_back (*r);
300                                 cerr << "\t\tadded " << (*r)->name() << endl;
301                         }
302
303                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("give surface %1 routes\n", routes.size()));
304
305                         (*si)->map_routes (routes);
306                 }
307         }
308
309         // display the current start bank.
310         surfaces.front()->display_bank_start (_current_initial_bank);
311 }
312
313 int 
314 MackieControlProtocol::set_active (bool yn)
315 {
316         if (yn == _active) {
317                 return 0;
318         }
319
320         try
321         {
322                 if (yn) {
323
324                         /* start event loop */
325
326                         BaseUI::run ();
327
328                         create_surfaces ();
329                         connect_session_signals ();
330                         
331                         _active = true;
332                         update_surfaces ();
333
334                         /* set up periodic task for metering and automation
335                          */
336
337                         Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (100); // milliseconds
338                         periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::periodic));
339                         periodic_timeout->attach (main_loop()->get_context());
340
341                 } else {
342                         BaseUI::quit ();
343                         close();
344                         _active = false;
345                 }
346         }
347         
348         catch (exception & e) {
349                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("set_active to false because exception caught: %1\n", e.what()));
350                 _active = false;
351                 throw;
352         }
353
354         return 0;
355 }
356
357 bool
358 MackieControlProtocol::periodic ()
359 {
360         if (!_active) {
361                 return false;
362         }
363
364         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
365                 (*s)->periodic ();
366         }
367         
368         update_timecode_display();
369
370         return true;
371 }
372
373
374 void 
375 MackieControlProtocol::update_timecode_beats_led()
376 {
377         switch (_timecode_type) {
378                 case ARDOUR::AnyTime::BBT:
379                         update_global_led ("beats", on);
380                         update_global_led ("timecode", off);
381                         break;
382                 case ARDOUR::AnyTime::Timecode:
383                         update_global_led ("timecode", on);
384                         update_global_led ("beats", off);
385                         break;
386                 default:
387                         ostringstream os;
388                         os << "Unknown Anytime::Type " << _timecode_type;
389                         throw runtime_error (os.str());
390         }
391 }
392
393 void 
394 MackieControlProtocol::update_global_button (const string & name, LedState ls)
395 {
396         boost::shared_ptr<Surface> surface = surfaces.front();
397
398         if (!surface->type() == mcu) {
399                 return;
400         }
401
402         if (surface->controls_by_name.find (name) != surface->controls_by_name.end()) {
403                 Button * button = dynamic_cast<Button*> (surface->controls_by_name[name]);
404                 surface->write (builder.build_led (button->led(), ls));
405         } else {
406                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Button %1 not found\n", name));
407         }
408 }
409
410 void 
411 MackieControlProtocol::update_global_led (const string & name, LedState ls)
412 {
413         boost::shared_ptr<Surface> surface = surfaces.front();
414
415         if (!surface->type() == mcu) {
416                 return;
417         }
418
419         if (surface->controls_by_name.find (name) != surface->controls_by_name.end()) {
420                 Led * led = dynamic_cast<Led*> (surface->controls_by_name[name]);
421                 surface->write (builder.build_led (*led, ls));
422         } else {
423                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Led %1 not found\n", name));
424         }
425 }
426
427 // send messages to surface to set controls to correct values
428 void 
429 MackieControlProtocol::update_surfaces()
430 {
431         if (!_active) {
432                 return;
433         }
434
435         // do the initial bank switch to connect signals
436         // _current_initial_bank is initialised by set_state
437         switch_banks (_current_initial_bank, true);
438         
439         // sometimes the jog wheel is a pot
440         surfaces.front()->blank_jog_ring ();
441         
442         // update global buttons and displays
443
444         notify_record_state_changed();
445         notify_transport_state_changed();
446         update_timecode_beats_led();
447 }
448
449 void 
450 MackieControlProtocol::connect_session_signals()
451 {
452         // receive routes added
453         session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_route_added, this, _1), this);
454         // receive record state toggled
455         session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_record_state_changed, this), this);
456         // receive transport state changed
457         session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_transport_state_changed, this), this);
458         session->TransportLooped.connect (session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_loop_state_changed, this), this);
459         // receive punch-in and punch-out
460         Config->ParameterChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), this);
461         session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), this);
462         // receive rude solo changed
463         session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), this);
464
465         // make sure remote id changed signals reach here
466         // see also notify_route_added
467         Sorted sorted = get_sorted_routes();
468
469         for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
470                 (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind(&MackieControlProtocol::notify_remote_id_changed, this), this);
471         }
472 }
473
474 void 
475 MackieControlProtocol::create_surfaces ()
476 {
477         string device_name = "mcu";
478         surface_type_t stype = mcu;
479
480         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces\n",
481                                                            1 + ARDOUR::Config->get_mackie_extenders()));
482
483         for (uint32_t n = 0; n < 1 + ARDOUR::Config->get_mackie_extenders(); ++n) {
484
485                 boost::shared_ptr<Surface> surface (new Surface (*this, session->engine().jack(), device_name, n, stype));
486                 surfaces.push_back (surface);
487                 
488                 device_name = "mcu_xt";
489                 stype = ext;
490
491                 _input_bundle->add_channel (
492                         surface->port().input_port().name(),
493                         ARDOUR::DataType::MIDI,
494                         session->engine().make_port_name_non_relative (surface->port().input_port().name())
495                         );
496                 
497                 _output_bundle->add_channel (
498                         surface->port().output_port().name(),
499                         ARDOUR::DataType::MIDI,
500                         session->engine().make_port_name_non_relative (surface->port().output_port().name())
501                         );
502
503                 int fd;
504                 MIDI::Port& input_port (surface->port().input_port());
505                 
506                 if ((fd = input_port.selectable ()) >= 0) {
507                         Glib::RefPtr<IOSource> psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR);
508
509                         psrc->connect (sigc::bind (sigc::mem_fun (this, &MackieControlProtocol::midi_input_handler), &input_port));
510                         psrc->attach (main_loop()->get_context());
511                         
512                         // glibmm hack: for now, store only the GSource*
513
514                         port_sources.push_back (psrc->gobj());
515                         g_source_ref (psrc->gobj());
516                 }
517         }
518 }
519
520 void 
521 MackieControlProtocol::close()
522 {
523         clear_ports ();
524
525         port_connections.drop_connections ();
526         session_connections.drop_connections ();
527         route_connections.drop_connections ();
528         periodic_connection.disconnect ();
529
530         surfaces.clear ();
531 }
532
533 XMLNode& 
534 MackieControlProtocol::get_state()
535 {
536         DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state\n");
537
538         // add name of protocol
539         XMLNode* node = new XMLNode (X_("Protocol"));
540         node->add_property (X_("name"), ARDOUR::ControlProtocol::_name);
541
542         // add current bank
543         ostringstream os;
544         os << _current_initial_bank;
545         node->add_property (X_("bank"), os.str());
546
547         return *node;
548 }
549
550 int 
551 MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
552 {
553         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", _active));
554
555         int retval = 0;
556
557         // fetch current bank
558
559         if (node.property (X_("bank")) != 0) {
560                 string bank = node.property (X_("bank"))->value();
561                 try {
562                         set_active (true);
563                         uint32_t new_bank = atoi (bank.c_str());
564                         if (_current_initial_bank != new_bank) {
565                                 switch_banks (new_bank);
566                         }
567                 }
568                 catch (exception & e) {
569                         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("exception in MackieControlProtocol::set_state: %1\n", e.what()));
570                         return -1;
571                 }
572         }
573
574         return retval;
575 }
576
577
578 /////////////////////////////////////////////////
579 // handlers for Route signals
580 // TODO should these be part of RouteSignal?
581 // They started off as signal/slot handlers for signals
582 // from Route, but they're also used in polling for automation
583 /////////////////////////////////////////////////
584
585 // TODO handle plugin automation polling
586 string 
587 MackieControlProtocol::format_bbt_timecode (framepos_t now_frame)
588 {
589         Timecode::BBT_Time bbt_time;
590         session->bbt_time (now_frame, bbt_time);
591
592         // According to the Logic docs
593         // digits: 888/88/88/888
594         // BBT mode: Bars/Beats/Subdivisions/Ticks
595         ostringstream os;
596         os << setw(3) << setfill('0') << bbt_time.bars;
597         os << setw(2) << setfill('0') << bbt_time.beats;
598
599         // figure out subdivisions per beat
600         const ARDOUR::Meter & meter = session->tempo_map().meter_at (now_frame);
601         int subdiv = 2;
602         if (meter.note_divisor() == 8 && (meter.divisions_per_bar() == 12.0 || meter.divisions_per_bar() == 9.0 || meter.divisions_per_bar() == 6.0)) {
603                 subdiv = 3;
604         }
605
606         uint32_t subdivisions = bbt_time.ticks / uint32_t (Timecode::BBT_Time::ticks_per_beat / subdiv);
607         uint32_t ticks = bbt_time.ticks % uint32_t (Timecode::BBT_Time::ticks_per_beat / subdiv);
608
609         os << setw(2) << setfill('0') << subdivisions + 1;
610         os << setw(3) << setfill('0') << ticks;
611
612         return os.str();
613 }
614
615 string 
616 MackieControlProtocol::format_timecode_timecode (framepos_t now_frame)
617 {
618         Timecode::Time timecode;
619         session->timecode_time (now_frame, timecode);
620
621         // According to the Logic docs
622         // digits: 888/88/88/888
623         // Timecode mode: Hours/Minutes/Seconds/Frames
624         ostringstream os;
625         os << setw(3) << setfill('0') << timecode.hours;
626         os << setw(2) << setfill('0') << timecode.minutes;
627         os << setw(2) << setfill('0') << timecode.seconds;
628         os << setw(3) << setfill('0') << timecode.frames;
629
630         return os.str();
631 }
632
633 void 
634 MackieControlProtocol::update_timecode_display()
635 {
636         boost::shared_ptr<Surface> surface = surfaces.front();
637
638         if (surface->type() != mcu || !surface->has_timecode_display()) {
639                 return;
640         }
641
642         // do assignment here so current_frame is fixed
643         framepos_t current_frame = session->transport_frame();
644         string timecode;
645
646         switch (_timecode_type) {
647         case ARDOUR::AnyTime::BBT:
648                 timecode = format_bbt_timecode (current_frame);
649                 break;
650         case ARDOUR::AnyTime::Timecode:
651                 timecode = format_timecode_timecode (current_frame);
652                 break;
653         default:
654                 return;
655         }
656         
657         // only write the timecode string to the MCU if it's changed
658         // since last time. This is to reduce midi bandwidth used.
659         if (timecode != _timecode_last) {
660                 surface->display_timecode (timecode, _timecode_last);
661                 _timecode_last = timecode;
662         }
663 }
664
665 ///////////////////////////////////////////
666 // Session signals
667 ///////////////////////////////////////////
668
669 void MackieControlProtocol::notify_parameter_changed (std::string const & p)
670 {
671         if (p == "punch-in") {
672                 update_global_button ("punch_in", session->config.get_punch_in());
673         } else if (p == "punch-out") {
674                 update_global_button ("punch_out", session->config.get_punch_out());
675         } else if (p == "clicking") {
676                 update_global_button ("clicking", Config->get_clicking());
677         } else {
678                 DEBUG_TRACE (DEBUG::MackieControl, string_compose ("parameter changed: %1\n", p));
679         }
680 }
681
682 // RouteList is the set of routes that have just been added
683 void 
684 MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
685 {
686         // currently assigned banks are less than the full set of
687         // strips, so activate the new strip now.
688
689         refresh_current_bank();
690
691         // otherwise route added, but current bank needs no updating
692
693         // make sure remote id changes in the new route are handled
694         typedef ARDOUR::RouteList ARS;
695
696         for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
697                 (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_remote_id_changed, this), this);
698         }
699 }
700
701 void 
702 MackieControlProtocol::notify_solo_active_changed (bool active)
703 {
704         boost::shared_ptr<Surface> surface = surfaces.front();
705         
706         Button * rude_solo = reinterpret_cast<Button*> (surface->controls_by_name["solo"]);
707
708         if (rude_solo) {
709                 surface->write (builder.build_led (*rude_solo, active ? flashing : off));
710         }
711 }
712
713 void 
714 MackieControlProtocol::notify_remote_id_changed()
715 {
716         Sorted sorted = get_sorted_routes();
717         uint32_t sz = n_strips();
718
719         // if a remote id has been moved off the end, we need to shift
720         // the current bank backwards.
721
722         if (sorted.size() - _current_initial_bank < sz) {
723                 // but don't shift backwards past the zeroth channel
724                 switch_banks (max((Sorted::size_type) 0, sorted.size() - sz));
725         } else {
726                 // Otherwise just refresh the current bank
727                 refresh_current_bank();
728         }
729 }
730
731 ///////////////////////////////////////////
732 // Transport signals
733 ///////////////////////////////////////////
734
735 void 
736 MackieControlProtocol::notify_loop_state_changed()
737 {
738         update_global_button ("loop", session->get_play_loop());
739 }
740
741 void 
742 MackieControlProtocol::notify_transport_state_changed()
743 {
744         // switch various play and stop buttons on / off
745         update_global_button ("play", session->transport_rolling());
746         update_global_button ("stop", !session->transport_rolling());
747         update_global_button ("rewind", session->transport_speed() < 0.0);
748         update_global_button ("ffwd", session->transport_speed() > 1.0);
749
750         _transport_previously_rolling = session->transport_rolling();
751
752 }
753
754 void
755 MackieControlProtocol::notify_record_state_changed ()
756 {
757         Button * rec = reinterpret_cast<Button*> (surfaces.front()->controls_by_name["record"]);
758         if (rec) {
759                 LedState ls;
760
761                 switch (session->record_status()) {
762                 case Session::Disabled:
763                         ls = off;
764                         break;
765                 case Session::Recording:
766                         ls = on;
767                         break;
768                 case Session::Enabled:
769                         ls = flashing;
770                         break;
771                 }
772
773                 surfaces.front()->write (builder.build_led (*rec, ls));
774         }
775 }
776
777 list<boost::shared_ptr<ARDOUR::Bundle> >
778 MackieControlProtocol::bundles ()
779 {
780         list<boost::shared_ptr<ARDOUR::Bundle> > b;
781         b.push_back (_input_bundle);
782         b.push_back (_output_bundle);
783         return b;
784 }
785
786 void
787 MackieControlProtocol::port_connected_or_disconnected (string a, string b, bool connected)
788 {
789         /* If something is connected to one of our output ports, send MIDI to update the surface
790            to whatever state it should have.
791         */
792
793         if (!connected) {
794                 return;
795         }
796
797         for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
798                 string const n = AudioEngine::instance()->make_port_name_non_relative ((*s)->port().output_port().name ());
799                 if (a == n || b == n) {
800                         update_surfaces ();
801                         return;
802                 }
803         }
804 }
805
806 void
807 MackieControlProtocol::do_request (MackieControlUIRequest* req)
808 {
809         if (req->type == CallSlot) {
810
811                 call_slot (MISSING_INVALIDATOR, req->the_slot);
812
813         } else if (req->type == Quit) {
814
815                 stop ();
816         }
817 }
818
819 int
820 MackieControlProtocol::stop ()
821 {
822         BaseUI::quit ();
823
824         return 0;
825 }
826
827 /** Add a timeout so that a control's in_use flag will be reset some time in the future.
828  *  @param in_use_control the control whose in_use flag to reset.
829  *  @param touch_control a touch control to emit an event for, or 0.
830  */
831 void
832 MackieControlProtocol::add_in_use_timeout (Surface& surface, Control& in_use_control, Control* touch_control)
833 {
834         Glib::RefPtr<Glib::TimeoutSource> timeout (Glib::TimeoutSource::create (250)); // milliseconds
835
836         in_use_control.in_use_connection.disconnect ();
837         in_use_control.in_use_connection = timeout->connect (
838                 sigc::bind (sigc::mem_fun (*this, &MackieControlProtocol::control_in_use_timeout), &surface, &in_use_control, touch_control));
839         in_use_control.in_use_touch_control = touch_control;
840         
841         timeout->attach (main_loop()->get_context());
842
843         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for surface %1, control %2 touch control %3\n",
844                                                            surface.number(), &in_use_control, touch_control));}
845
846 /** Handle timeouts to reset in_use for controls that can't
847  *  do this by themselves (e.g. pots, and faders without touch support).
848  *  @param in_use_control the control whose in_use flag to reset.
849  *  @param touch_control a touch control to emit an event for, or 0.
850  */
851 bool
852 MackieControlProtocol::control_in_use_timeout (Surface* surface, Control* in_use_control, Control* touch_control)
853 {
854         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout elapsed for surface %1, control %2 touch control %3\n",
855                                                            surface->number(), in_use_control, touch_control));
856
857         in_use_control->set_in_use (false);
858
859         if (touch_control) {
860                 // empty control_state
861                 ControlState control_state;
862                 surface->handle_control_event (*touch_control, control_state);
863         }
864         
865         // only call this method once from the timer
866         return false;
867 }
868
869 void 
870 MackieControlProtocol::update_led (Surface& surface, Button& button, Mackie::LedState ls)
871 {
872         if (ls != none) {
873                 surface.port().write (builder.build_led (button, ls));
874         }
875 }
876
877 void 
878 MackieControlProtocol::handle_button_event (Surface& surface, Button& button, ButtonState bs)
879 {
880         if  (bs != press && bs != release) {
881                 update_led (surface, button, none);
882                 return;
883         }
884         
885         LedState ls;
886
887         DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2\n", (bs == press ? "press" : "release"), button.raw_id()));
888
889         switch  (button.raw_id()) {
890         case 0x28: // io
891                 switch  (bs) {
892                 case press: ls = io_press (button); break;
893                 case release: ls = io_release (button); break;
894                 case neither: break;
895                 }
896                 break;
897                 
898         case 0x29: // sends
899                 switch  (bs) {
900                 case press: ls = sends_press (button); break;
901                 case release: ls = sends_release (button); break;
902                 case neither: break;
903                 }
904                 break;
905                 
906         case 0x2a: // pan
907                 switch  (bs) {
908                 case press: ls = pan_press (button); break;
909                 case release: ls = pan_release (button); break;
910                 case neither: break;
911                 }
912                 break;
913                 
914         case 0x2b: // plugin
915                 switch  (bs) {
916                 case press: ls = plugin_press (button); break;
917                 case release: ls = plugin_release (button); break;
918                 case neither: break;
919                 }
920                 break;
921                 
922         case 0x2c: // eq
923                 switch  (bs) {
924                 case press: ls = eq_press (button); break;
925                 case release: ls = eq_release (button); break;
926                 case neither: break;
927                 }
928                 break;
929                 
930         case 0x2d: // dyn
931                 switch  (bs) {
932                 case press: ls = dyn_press (button); break;
933                 case release: ls = dyn_release (button); break;
934                 case neither: break;
935                 }
936                 break;
937                 
938         case 0x2e: // left
939                 switch  (bs) {
940                 case press: ls = left_press (button); break;
941                 case release: ls = left_release (button); break;
942                 case neither: break;
943                 }
944                 break;
945                 
946         case 0x2f: // right
947                 switch  (bs) {
948                 case press: ls = right_press (button); break;
949                 case release: ls = right_release (button); break;
950                 case neither: break;
951                 }
952                 break;
953                 
954         case 0x30: // channel_left
955                 switch  (bs) {
956                 case press: ls = channel_left_press (button); break;
957                 case release: ls = channel_left_release (button); break;
958                 case neither: break;
959                 }
960                 break;
961                 
962         case 0x31: // channel_right
963                 switch  (bs) {
964                 case press: ls = channel_right_press (button); break;
965                 case release: ls = channel_right_release (button); break;
966                 case neither: break;
967                 }
968                 break;
969                 
970         case 0x32: // flip
971                 switch  (bs) {
972                 case press: ls = flip_press (button); break;
973                 case release: ls = flip_release (button); break;
974                 case neither: break;
975                 }
976                 break;
977
978         case 0x33: // edit
979                 switch  (bs) {
980                 case press: ls = edit_press (button); break;
981                 case release: ls = edit_release (button); break;
982                 case neither: break;
983                 }
984                 break;
985
986         case 0x34: // name_value
987                 switch  (bs) {
988                 case press: ls = name_value_press (button); break;
989                 case release: ls = name_value_release (button); break;
990                 case neither: break;
991                 }
992                 break;
993
994         case 0x35: // timecode_beats
995                 switch  (bs) {
996                 case press: ls = timecode_beats_press (button); break;
997                 case release: ls = timecode_beats_release (button); break;
998                 case neither: break;
999                 }
1000                 break;
1001
1002         case 0x36: // F1
1003                 switch  (bs) {
1004                 case press: ls = F1_press (button); break;
1005                 case release: ls = F1_release (button); break;
1006                 case neither: break;
1007                 }
1008                 break;
1009
1010         case 0x37: // F2
1011                 switch  (bs) {
1012                 case press: ls = F2_press (button); break;
1013                 case release: ls = F2_release (button); break;
1014                 case neither: break;
1015                 }
1016                 break;
1017
1018         case 0x38: // F3
1019                 switch  (bs) {
1020                 case press: ls = F3_press (button); break;
1021                 case release: ls = F3_release (button); break;
1022                 case neither: break;
1023                 }
1024                 break;
1025
1026         case 0x39: // F4
1027                 switch  (bs) {
1028                 case press: ls = F4_press (button); break;
1029                 case release: ls = F4_release (button); break;
1030                 case neither: break;
1031                 }
1032                 break;
1033
1034         case 0x3a: // F5
1035                 switch  (bs) {
1036                 case press: ls = F5_press (button); break;
1037                 case release: ls = F5_release (button); break;
1038                 case neither: break;
1039                 }
1040                 break;
1041
1042         case 0x3b: // F6
1043                 switch  (bs) {
1044                 case press: ls = F6_press (button); break;
1045                 case release: ls = F6_release (button); break;
1046                 case neither: break;
1047                 }
1048                 break;
1049
1050         case 0x3c: // F7
1051                 switch  (bs) {
1052                 case press: ls = F7_press (button); break;
1053                 case release: ls = F7_release (button); break;
1054                 case neither: break;
1055                 }
1056                 break;
1057
1058         case 0x3d: // F8
1059                 switch  (bs) {
1060                 case press: ls = F8_press (button); break;
1061                 case release: ls = F8_release (button); break;
1062                 case neither: break;
1063                 }
1064                 break;
1065
1066         case 0x3e: // F9
1067                 switch  (bs) {
1068                 case press: ls = F9_press (button); break;
1069                 case release: ls = F9_release (button); break;
1070                 case neither: break;
1071                 }
1072                 break;
1073
1074         case 0x3f: // F10
1075                 switch  (bs) {
1076                 case press: ls = F10_press (button); break;
1077                 case release: ls = F10_release (button); break;
1078                 case neither: break;
1079                 }
1080                 break;
1081
1082         case 0x40: // F11
1083                 switch  (bs) {
1084                 case press: ls = F11_press (button); break;
1085                 case release: ls = F11_release (button); break;
1086                 case neither: break;
1087                 }
1088                 break;
1089
1090         case 0x41: // F12
1091                 switch  (bs) {
1092                 case press: ls = F12_press (button); break;
1093                 case release: ls = F12_release (button); break;
1094                 case neither: break;
1095                 }
1096                 break;
1097
1098         case 0x42: // F13
1099                 switch  (bs) {
1100                 case press: ls = F13_press (button); break;
1101                 case release: ls = F13_release (button); break;
1102                 case neither: break;
1103                 }
1104                 break;
1105
1106         case 0x43: // F14
1107                 switch  (bs) {
1108                 case press: ls = F14_press (button); break;
1109                 case release: ls = F14_release (button); break;
1110                 case neither: break;
1111                 }
1112                 break;
1113
1114         case 0x44: // F15
1115                 switch  (bs) {
1116                 case press: ls = F15_press (button); break;
1117                 case release: ls = F15_release (button); break;
1118                 case neither: break;
1119                 }
1120                 break;
1121
1122         case 0x45: // F16
1123                 switch  (bs) {
1124                 case press: ls = F16_press (button); break;
1125                 case release: ls = F16_release (button); break;
1126                 case neither: break;
1127                 }
1128                 break;
1129
1130         case 0x46: // shift
1131                 switch  (bs) {
1132                 case press: ls = shift_press (button); break;
1133                 case release: ls = shift_release (button); break;
1134                 case neither: break;
1135                 }
1136                 break;
1137
1138         case 0x47: // option
1139                 switch  (bs) {
1140                 case press: ls = option_press (button); break;
1141                 case release: ls = option_release (button); break;
1142                 case neither: break;
1143                 }
1144                 break;
1145
1146         case Button::Ctrl:
1147                 switch  (bs) {
1148                 case press: ls = control_press (button); break;
1149                 case release: ls = control_release (button); break;
1150                 case neither: break;
1151                 }
1152                 break;
1153
1154         case 0x49: // cmd_alt
1155                 switch  (bs) {
1156                 case press: ls = cmd_alt_press (button); break;
1157                 case release: ls = cmd_alt_release (button); break;
1158                 case neither: break;
1159                 }
1160                 break;
1161
1162         case 0x4a: // on
1163                 switch  (bs) {
1164                 case press: ls = on_press (button); break;
1165                 case release: ls = on_release (button); break;
1166                 case neither: break;
1167                 }
1168                 break;
1169
1170         case 0x4b: // rec_ready
1171                 switch  (bs) {
1172                 case press: ls = rec_ready_press (button); break;
1173                 case release: ls = rec_ready_release (button); break;
1174                 case neither: break;
1175                 }
1176                 break;
1177
1178         case Button::Undo: // undo
1179                 switch  (bs) {
1180                 case press: ls = undo_press (button); break;
1181                 case release: ls = undo_release (button); break;
1182                 case neither: break;
1183                 }
1184                 break;
1185
1186         case Button::Save:
1187                 switch (bs) {
1188                 case press: ls = save_press (button); break;
1189                 case release: ls = save_release (button); break;
1190                 case neither: break;
1191                 }
1192                 break;
1193
1194         case Button::Touch: // touch
1195                 switch  (bs) {
1196                 case press: ls = touch_press (button); break;
1197                 case release: ls = touch_release (button); break;
1198                 case neither: break;
1199                 }
1200                 break;
1201
1202         case Button::Redo: // redo
1203                 switch  (bs) {
1204                 case press: ls = redo_press (button); break;
1205                 case release: ls = redo_release (button); break;
1206                 case neither: break;
1207                 }
1208                 break;
1209
1210         case Button::Marker: // marker
1211                 switch  (bs) {
1212                 case press: ls = marker_press (button); break;
1213                 case release: ls = marker_release (button); break;
1214                 case neither: break;
1215                 }
1216                 break;
1217
1218         case Button::Enter: // enter
1219                 switch  (bs) {
1220                 case press: ls = enter_press (button); break;
1221                 case release: ls = enter_release (button); break;
1222                 case neither: break;
1223                 }
1224                 break;
1225
1226         case 0x52: // cancel
1227                 switch  (bs) {
1228                 case press: ls = cancel_press (button); break;
1229                 case release: ls = cancel_release (button); break;
1230                 case neither: break;
1231                 }
1232                 break;
1233
1234         case 0x53: // mixer
1235                 switch  (bs) {
1236                 case press: ls = mixer_press (button); break;
1237                 case release: ls = mixer_release (button); break;
1238                 case neither: break;
1239                 }
1240                 break;
1241
1242         case 0x54: // frm_left
1243                 switch  (bs) {
1244                 case press: ls = frm_left_press (button); break;
1245                 case release: ls = frm_left_release (button); break;
1246                 case neither: break;
1247                 }
1248                 break;
1249
1250         case 0x55: // frm_right
1251                 switch  (bs) {
1252                 case press: ls = frm_right_press (button); break;
1253                 case release: ls = frm_right_release (button); break;
1254                 case neither: break;
1255                 }
1256                 break;
1257
1258         case 0x56: // loop
1259                 switch  (bs) {
1260                 case press: ls = loop_press (button); break;
1261                 case release: ls = loop_release (button); break;
1262                 case neither: break;
1263                 }
1264                 break;
1265
1266         case 0x57: // punch_in
1267                 switch  (bs) {
1268                 case press: ls = punch_in_press (button); break;
1269                 case release: ls = punch_in_release (button); break;
1270                 case neither: break;
1271                 }
1272                 break;
1273
1274         case 0x58: // punch_out
1275                 switch  (bs) {
1276                 case press: ls = punch_out_press (button); break;
1277                 case release: ls = punch_out_release (button); break;
1278                 case neither: break;
1279                 }
1280                 break;
1281
1282         case 0x59: // home
1283                 switch  (bs) {
1284                 case press: ls = home_press (button); break;
1285                 case release: ls = home_release (button); break;
1286                 case neither: break;
1287                 }
1288                 break;
1289
1290         case 0x5a: // end
1291                 switch  (bs) {
1292                 case press: ls = end_press (button); break;
1293                 case release: ls = end_release (button); break;
1294                 case neither: break;
1295                 }
1296                 break;
1297
1298         case Button::Rewind:
1299                 switch  (bs) {
1300                 case press: ls = rewind_press (button); break;
1301                 case release: ls = rewind_release (button); break;
1302                 case neither: break;
1303                 }
1304                 break;
1305
1306         case Button::Ffwd:
1307                 switch  (bs) {
1308                 case press: ls = ffwd_press (button); break;
1309                 case release: ls = ffwd_release (button); break;
1310                 case neither: break;
1311                 }
1312                 break;
1313
1314         case Button::Stop:
1315                 switch  (bs) {
1316                 case press: ls = stop_press (button); break;
1317                 case release: ls = stop_release (button); break;
1318                 case neither: break;
1319                 }
1320                 break;
1321
1322         case Button::Play:
1323                 switch  (bs) {
1324                 case press: ls = play_press (button); break;
1325                 case release: ls = play_release (button); break;
1326                 case neither: break;
1327                 }
1328                 break;
1329
1330         case 0x5f: // record
1331                 switch  (bs) {
1332                 case press: ls = record_press (button); break;
1333                 case release: ls = record_release (button); break;
1334                 case neither: break;
1335                 }
1336                 break;
1337
1338         case 0x60: // cursor_up
1339                 switch  (bs) {
1340                 case press: ls = cursor_up_press (button); break;
1341                 case release: ls = cursor_up_release (button); break;
1342                 case neither: break;
1343                 }
1344                 break;
1345
1346         case 0x61: // cursor_down
1347                 switch  (bs) {
1348                 case press: ls = cursor_down_press (button); break;
1349                 case release: ls = cursor_down_release (button); break;
1350                 case neither: break;
1351                 }
1352                 break;
1353
1354         case 0x62: // cursor_left
1355                 switch  (bs) {
1356                 case press: ls = cursor_left_press (button); break;
1357                 case release: ls = cursor_left_release (button); break;
1358                 case neither: break;
1359                 }
1360                 break;
1361
1362         case 0x63: // cursor_right
1363                 switch  (bs) {
1364                 case press: ls = cursor_right_press (button); break;
1365                 case release: ls = cursor_right_release (button); break;
1366                 case neither: break;
1367                 }
1368                 break;
1369
1370         case 0x64: // zoom
1371                 switch  (bs) {
1372                 case press: ls = zoom_press (button); break;
1373                 case release: ls = zoom_release (button); break;
1374                 case neither: break;
1375                 }
1376                 break;
1377
1378         case 0x65: // scrub
1379                 switch  (bs) {
1380                 case press: ls = scrub_press (button); break;
1381                 case release: ls = scrub_release (button); break;
1382                 case neither: break;
1383                 }
1384                 break;
1385
1386         case 0x66: // user_a
1387                 switch  (bs) {
1388                 case press: ls = user_a_press (button); break;
1389                 case release: ls = user_a_release (button); break;
1390                 case neither: break;
1391                 }
1392                 break;
1393
1394         case 0x67: // user_b
1395                 switch  (bs) {
1396                 case press: ls = user_b_press (button); break;
1397                 case release: ls = user_b_release (button); break;
1398                 case neither: break;
1399                 }
1400                 break;
1401
1402         }
1403
1404         update_led (surface, button, ls);
1405 }
1406
1407 void
1408 MackieControlProtocol::select_track (boost::shared_ptr<Route> r)
1409 {
1410         if (_modifier_state == MODIFIER_SHIFT) {
1411                 r->gain_control()->set_value (0.0);
1412         } else {
1413                 if (_current_selected_track > 0 && r->remote_control_id() == (uint32_t) _current_selected_track) {
1414                         UnselectTrack (); /* EMIT SIGNAL */
1415                         _current_selected_track = -1;
1416                 } else {
1417                         SelectByRID (r->remote_control_id()); /* EMIT SIGNAL */
1418                         _current_selected_track = r->remote_control_id();;
1419                 }
1420         }
1421 }
1422
1423 bool
1424 MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port)
1425 {
1426         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on  %1\n", port->name()));
1427
1428         if (ioc & ~IO_IN) {
1429                 return false;
1430         }
1431
1432         if (ioc & IO_IN) {
1433
1434                 CrossThreadChannel::drain (port->selectable());
1435
1436                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", port->name()));
1437                 framepos_t now = session->engine().frame_time();
1438                 port->parse (now);
1439         }
1440
1441         return true;
1442 }
1443
1444 void
1445 MackieControlProtocol::clear_ports ()
1446 {
1447         for (PortSources::iterator i = port_sources.begin(); i != port_sources.end(); ++i) {
1448                 g_source_destroy (*i);
1449                 g_source_unref (*i);
1450         }
1451
1452         port_sources.clear ();
1453 }
1454