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