"merge" (i.e. wholesale import) 2.0-ongoing Mackie code and then fix to compile in...
[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<Session::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 ( Session::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                 // but only the first time around
547                 master_route_signal = shared_ptr<RouteSignal>( new RouteSignal( *master_route(), *this, master_strip(), mcu_port() ) );
548                 // update strip from route
549                 master_route_signal->notify_all();
550                 
551                 // sometimes the jog wheel is a pot
552                 surface().blank_jog_ring( mcu_port(), builder );
553                 
554                 // update global buttons and displays
555                 notify_record_state_changed();
556                 notify_transport_state_changed();
557                 update_smpte_beats_led();
558         }
559 }
560
561 void MackieControlProtocol::connect_session_signals()
562 {
563         // receive routes added
564         connections_back = session->RouteAdded.connect( ( mem_fun (*this, &MackieControlProtocol::notify_route_added) ) );
565         // receive record state toggled
566         connections_back = session->RecordStateChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_record_state_changed) ) );
567         // receive transport state changed
568         connections_back = session->TransportStateChange.connect( ( mem_fun (*this, &MackieControlProtocol::notify_transport_state_changed) ) );
569         // receive punch-in and punch-out
570         connections_back = Config->ParameterChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_parameter_changed) ) );
571         // receive rude solo changed
572         connections_back = session->SoloActive.connect( ( mem_fun (*this, &MackieControlProtocol::notify_solo_active_changed) ) );
573         
574         // make sure remote id changed signals reach here
575         // see also notify_route_added
576         Sorted sorted = get_sorted_routes();
577         for ( Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it )
578         {
579                 connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) );
580         }
581 }
582
583 void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
584 {
585 #ifdef DEBUG
586         cout << "add port " << midi_port.name() << ", " << midi_port.device() << ", " << midi_port.type() << endl;
587         cout << "MIDI::Port::ALSA_Sequencer " << MIDI::Port::ALSA_Sequencer << endl;
588         cout << "MIDI::Port::Unknown " << MIDI::Port::Unknown << endl;
589 #endif
590         if ( string( midi_port.device() ) == string( "ardour" ) )
591         {
592                 throw MackieControlException( "The Mackie MCU driver will not use a port with device=ardour" );
593         }
594         else if ( midi_port.type() == MIDI::Port::ALSA_Sequencer )
595         {
596                 throw MackieControlException( "alsa/sequencer ports don't work with the Mackie MCU driver right now" );
597         }
598         else
599         {
600                 MackiePort * sport = new MackiePort( *this, midi_port, number );
601                 _ports.push_back( sport );
602                 
603                 connections_back = sport->init_event.connect(
604                         sigc::bind (
605                                 mem_fun (*this, &MackieControlProtocol::handle_port_init)
606                                 , sport
607                         )
608                 );
609
610                 connections_back = sport->active_event.connect(
611                         sigc::bind (
612                                 mem_fun (*this, &MackieControlProtocol::handle_port_active)
613                                 , sport
614                         )
615                 );
616
617                 connections_back = sport->inactive_event.connect(
618                         sigc::bind (
619                                 mem_fun (*this, &MackieControlProtocol::handle_port_inactive)
620                                 , sport
621                         )
622                 );
623                 
624                 _ports_changed = true;
625         }
626 }
627
628 void MackieControlProtocol::create_ports()
629 {
630         MIDI::Manager * mm = MIDI::Manager::instance();
631
632         // open main port
633         {
634                 MIDI::Port * midi_port = mm->port( default_port_name );
635
636                 if ( midi_port == 0 ) {
637                         ostringstream os;
638                         os << string_compose( _("no MIDI port named \"%1\" exists - Mackie control disabled"), default_port_name );
639                         error << os.str() << endmsg;
640                         throw MackieControlException( os.str() );
641                 }
642                 add_port( *midi_port, 0 );
643         }
644         
645         // open extender ports. Up to 9. Should be enough.
646         // could also use mm->get_midi_ports()
647         string ext_port_base = "mcu_xt_";
648         for ( int index = 1; index <= 9; ++index )
649         {
650                 ostringstream os;
651                 os << ext_port_base << index;
652                 MIDI::Port * midi_port = mm->port( os.str() );
653                 if ( midi_port != 0 ) add_port( *midi_port, index );
654         }
655 }
656
657 shared_ptr<Route> MackieControlProtocol::master_route()
658 {
659         shared_ptr<Route> retval;
660         retval = session->route_by_name( "master" );
661         if ( retval == 0 )
662         {
663                 // TODO search through all routes for one with the master attribute set
664         }
665         return retval;
666 }
667
668 Strip & MackieControlProtocol::master_strip()
669 {
670         return dynamic_cast<Strip&>( *surface().groups["master"] );
671 }
672
673 void MackieControlProtocol::initialize_surface()
674 {
675         // set up the route table
676         int strips = 0;
677         for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
678         {
679                 strips += (*it)->strips();
680         }
681         
682         set_route_table_size( strips );
683         
684         // TODO same as code in mackie_port.cc
685         string emulation = ARDOUR::Config->get_mackie_emulation();
686         if ( emulation == "bcf" )
687         {
688                 _surface = new BcfSurface( strips );
689         }
690         else if ( emulation == "mcu" )
691         {
692                 _surface = new MackieSurface( strips );
693         }
694         else
695         {
696                 ostringstream os;
697                 os << "no Surface class found for emulation: " << emulation;
698                 throw MackieControlException( os.str() );
699         }
700
701         _surface->init();
702         
703         // Connect events. Must be after route table otherwise there will be trouble
704         for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
705         {
706                 connections_back = (*it)->control_event.connect( ( mem_fun (*this, &MackieControlProtocol::handle_control_event) ) );
707         }
708 }
709
710 void MackieControlProtocol::close()
711 {
712         // stop polling, and wait for it...
713         // must be before other shutdown otherwise polling loop
714         // calls methods on objects that are deleted
715         _polling = false;
716         pthread_join( thread, 0 );
717         
718         // TODO disconnect port active/inactive signals
719         // Or at least put a lock here
720         
721         // disconnect global signals from Session
722         // TODO Since *this is a sigc::trackable, this shouldn't be necessary
723         // but it is for some reason
724 #if 0
725         for( vector<sigc::connection>::iterator it = _connections.begin(); it != _connections.end(); ++it )
726         {
727                 it->disconnect();
728         }
729 #endif
730         
731         if ( _surface != 0 )
732         {
733                 // These will fail if the port has gone away.
734                 // So catch the exception and do the rest of the
735                 // close afterwards
736                 // because the bcf doesn't respond to the next 3 sysex messages
737                 try
738                 {
739                         zero_all();
740                 }
741                 catch ( exception & e )
742                 {
743 #ifdef DEBUG
744                         cout << "MackieControlProtocol::close caught exception: " << e.what() << endl;
745 #endif
746                 }
747                 
748                 for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
749                 {
750                         try
751                         {
752                                 MackiePort & port = **it;
753                                 // faders to minimum
754                                 port.write_sysex( 0x61 );
755                                 // All LEDs off
756                                 port.write_sysex( 0x62 );
757                                 // Reset (reboot into offline mode)
758                                 port.write_sysex( 0x63 );
759                         }
760                         catch ( exception & e )
761                         {
762 #ifdef DEBUG
763                                 cout << "MackieControlProtocol::close caught exception: " << e.what() << endl;
764 #endif
765                         }
766                 }
767                 
768                 // disconnect routes from strips
769                 clear_route_signals();
770                 
771                 delete _surface;
772                 _surface = 0;
773         }
774         
775         // shut down MackiePorts
776         for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
777         {
778                 delete *it;
779         }
780         _ports.clear();
781         
782         // this is done already in monitor_work. But it's here so we know.
783         delete[] pfd;
784         pfd = 0;
785         nfds = 0;
786 }
787
788 void* MackieControlProtocol::_monitor_work (void* arg)
789 {
790         return static_cast<MackieControlProtocol*>(arg)->monitor_work ();
791 }
792
793 XMLNode & MackieControlProtocol::get_state()
794 {
795 #ifdef DEBUG
796         cout << "MackieControlProtocol::get_state" << endl;
797 #endif
798         
799         // add name of protocol
800         XMLNode* node = new XMLNode( X_("Protocol") );
801         node->add_property( X_("name"), _name );
802         
803         // add current bank
804         ostringstream os;
805         os << _current_initial_bank;
806         node->add_property( X_("bank"), os.str() );
807         
808         return *node;
809 }
810
811 int MackieControlProtocol::set_state( const XMLNode & node )
812 {
813 #ifdef DEBUG
814         cout << "MackieControlProtocol::set_state: active " << _active << endl;
815 #endif
816         int retval = 0;
817         
818         // fetch current bank
819         if ( node.property( X_("bank") ) != 0 )
820         {
821                 string bank = node.property( X_("bank") )->value();
822                 try
823                 {
824                         set_active( true );
825                         uint32_t new_bank = atoi( bank.c_str() );
826                         if ( _current_initial_bank != new_bank ) switch_banks( new_bank );
827                 }
828                 catch ( exception & e )
829                 {
830 #ifdef DEBUG
831                         cout << "exception in MackieControlProtocol::set_state: " << e.what() << endl;
832 #endif
833                         return -1;
834                 }
835         }
836         
837         return retval;
838 }
839
840 void MackieControlProtocol::handle_control_event( SurfacePort & port, Control & control, const ControlState & state )
841 {
842         // find the route for the control, if there is one
843         boost::shared_ptr<Route> route;
844         if ( control.group().is_strip() )
845         {
846                 if ( control.group().is_master() )
847                 {
848                         route = master_route();
849                 }
850                 else
851                 {
852                         uint32_t index = control.ordinal() - 1 + ( port.number() * port.strips() );
853                         if ( index < route_table.size() )
854                                 route = route_table[index];
855                         else
856                                 cerr << "Warning: index is " << index << " which is not in the route table, size: " << route_table.size() << endl;
857                 }
858         }
859         
860         // This handles control element events from the surface
861         // the state of the controls on the surface is usually updated
862         // from UI events.
863         switch ( control.type() )
864         {
865                 case Control::type_fader:
866                         // find the route in the route table for the id
867                         // if the route isn't available, skip it
868                         // at which point the fader should just reset itself
869                         if ( route != 0 )
870                         {
871                                 route->gain_control()->set_value( state.pos );
872                                 
873                                 // must echo bytes back to slider now, because
874                                 // the notifier only works if the fader is not being
875                                 // touched. Which it is if we're getting input.
876                                 port.write( builder.build_fader( (Fader&)control, state.pos ) );
877                         }
878                         break;
879                         
880                 case Control::type_button:
881                         if ( control.group().is_strip() )
882                         {
883                                 // strips
884                                 if ( route != 0 )
885                                 {
886                                         handle_strip_button( control, state.button_state, route );
887                                 }
888                                 else
889                                 {
890                                         // no route so always switch the light off
891                                         // because no signals will be emitted by a non-route
892                                         port.write( builder.build_led( control.led(), off ) );
893                                 }
894                         }
895                         else if ( control.group().is_master() )
896                         {
897                                 // master fader touch
898                                 if ( route != 0 )
899                                 {
900                                         handle_strip_button( control, state.button_state, route );
901                                 }
902                         }
903                         else
904                         {
905                                 // handle all non-strip buttons
906                                 surface().handle_button( *this, state.button_state, dynamic_cast<Button&>( control ) );
907                         }
908                         break;
909                         
910                 // pot (jog wheel, external control)
911                 case Control::type_pot:
912                         if ( control.group().is_strip() )
913                         {
914                                 if ( route != 0 )
915                                 {
916                                         // pan for mono input routes, or stereo linked panners
917                                         if ( route->panner().npanners() == 1 || ( route->panner().npanners() == 2 && route->panner().linked() ) )
918                                         {
919                                                 // assume pan for now
920                                                 float xpos;
921                                                 route->panner().streampanner (0).get_effective_position (xpos);
922                                                 
923                                                 // calculate new value, and trim
924                                                 xpos += state.delta * state.sign;
925                                                 if ( xpos > 1.0 )
926                                                         xpos = 1.0;
927                                                 else if ( xpos < 0.0 )
928                                                         xpos = 0.0;
929                                                 
930                                                 route->panner().streampanner (0).set_position( xpos );
931                                         }
932                                 }
933                                 else
934                                 {
935                                         // it's a pot for an umnapped route, so turn all the lights off
936                                         port.write( builder.build_led_ring( dynamic_cast<Pot &>( control ), off ) );
937                                 }
938                         }
939                         else
940                         {
941                                 if ( control.is_jog() )
942                                 {
943                                         _jog_wheel.jog_event( port, control, state );
944                                 }
945                                 else
946                                 {
947                                         cout << "external controller" << state.ticks * state.sign << endl;
948                                 }
949                         }
950                         break;
951                         
952                 default:
953                         cout << "Control::type not handled: " << control.type() << endl;
954         }
955 }
956
957 /////////////////////////////////////////////////
958 // handlers for Route signals
959 // TODO should these be part of RouteSignal?
960 // They started off as sigc handlers for signals
961 // from Route, but they're also used in polling for automation
962 /////////////////////////////////////////////////
963
964 void MackieControlProtocol::notify_solo_changed( RouteSignal * route_signal )
965 {
966         try
967         {
968                 Button & button = route_signal->strip().solo();
969                 route_signal->port().write( builder.build_led( button, route_signal->route().soloed() ) );
970         }
971         catch( exception & e )
972         {
973                 cout << e.what() << endl;
974         }
975 }
976
977 void MackieControlProtocol::notify_mute_changed( RouteSignal * route_signal )
978 {
979         try
980         {
981                 Button & button = route_signal->strip().mute();
982                 route_signal->port().write( builder.build_led( button, route_signal->route().muted() ) );
983         }
984         catch( exception & e )
985         {
986                 cout << e.what() << endl;
987         }
988 }
989
990 void MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_signal )
991 {
992         try
993         {
994                 Button & button = route_signal->strip().recenable();
995                 route_signal->port().write( builder.build_led( button, route_signal->route().record_enabled() ) );
996         }
997         catch( exception & e )
998         {
999                 cout << e.what() << endl;
1000         }
1001 }
1002
1003 void MackieControlProtocol::notify_active_changed( RouteSignal * route_signal )
1004 {
1005         try
1006         {
1007 #ifdef DEBUG
1008                 cout << "MackieControlProtocol::notify_active_changed" << endl;
1009 #endif
1010                 refresh_current_bank();
1011         }
1012         catch( exception & e )
1013         {
1014                 cout << e.what() << endl;
1015         }
1016 }
1017         
1018 void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, bool force_update )
1019 {
1020         try
1021         {
1022                 Fader & fader = route_signal->strip().gain();
1023                 if ( !fader.in_use() )
1024                 {
1025                         float gain_value = route_signal->route().gain_control()->get_value();
1026                         // check that something has actually changed
1027                         if ( force_update || gain_value != route_signal->last_gain_written() )
1028                         {
1029                                 route_signal->port().write( builder.build_fader( fader, gain_value ) );
1030                                 route_signal->last_gain_written( gain_value );
1031                         }
1032                 }
1033         }
1034         catch( exception & e )
1035         {
1036                 cout << e.what() << endl;
1037         }
1038 }
1039
1040 void MackieControlProtocol::notify_name_changed( RouteSignal * route_signal )
1041 {
1042         try
1043         {
1044                 Strip & strip = route_signal->strip();
1045                 if ( !strip.is_master() )
1046                 {
1047                         string line1;
1048                         string fullname = route_signal->route().name();
1049                         
1050                         if ( fullname.length() <= 6 )
1051                         {
1052                                 line1 = fullname;
1053                         }
1054                         else
1055                         {
1056                                 line1 = PBD::short_version( fullname, 6 );
1057                         }
1058                         
1059                         SurfacePort & port = route_signal->port();
1060                         port.write( builder.strip_display( port, strip, 0, line1 ) );
1061                         port.write( builder.strip_display_blank( port, strip, 1 ) );
1062                 }
1063         }
1064         catch( exception & e )
1065         {
1066                 cout << e.what() << endl;
1067         }
1068 }
1069
1070 void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, bool force_update )
1071 {
1072         try
1073         {
1074                 Pot & pot = route_signal->strip().vpot();
1075                 const Panner & panner = route_signal->route().panner();
1076                 if ( panner.npanners() == 1 || ( panner.npanners() == 2 && panner.linked() ) )
1077                 {
1078                         float pos;
1079                         route_signal->route().panner().streampanner(0).get_effective_position( pos );
1080                         
1081                         // cache the MidiByteArray here, because the mackie led control is much lower
1082                         // resolution than the panner control. So we save lots of byte
1083                         // sends in spite of more work on the comparison
1084                         MidiByteArray bytes = builder.build_led_ring( pot, ControlState( on, pos ), MackieMidiBuilder::midi_pot_mode_dot );
1085                         // check that something has actually changed
1086                         if ( force_update || bytes != route_signal->last_pan_written() )
1087                         {
1088                                 route_signal->port().write( bytes );
1089                                 route_signal->last_pan_written( bytes );
1090                         }
1091                 }
1092                 else
1093                 {
1094                         route_signal->port().write( builder.zero_control( pot ) );
1095                 }
1096         }
1097         catch( exception & e )
1098         {
1099                 cout << e.what() << endl;
1100         }
1101 }
1102
1103 // TODO handle plugin automation polling
1104 void MackieControlProtocol::update_automation( RouteSignal & rs )
1105 {
1106         ARDOUR::AutoState gain_state = rs.route().gain_control()->automation_state();
1107         if ( gain_state == Touch || gain_state == Play )
1108         {
1109                 notify_gain_changed( &rs, false );
1110         }
1111         
1112         ARDOUR::AutoState panner_state = rs.route().panner().automation_state();
1113         if ( panner_state == Touch || panner_state == Play )
1114         {
1115                 notify_panner_changed( &rs, false );
1116         }
1117         _automation_last.start();
1118 }
1119
1120 string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
1121 {
1122         BBT_Time bbt_time;
1123         session->bbt_time( now_frame, bbt_time );
1124         
1125         // According to the Logic docs
1126         // digits: 888/88/88/888
1127         // BBT mode: Bars/Beats/Subdivisions/Ticks
1128         ostringstream os;
1129         os << setw(3) << setfill('0') << bbt_time.bars;
1130         os << setw(2) << setfill('0') << bbt_time.beats;
1131         
1132         // figure out subdivisions per beat
1133         const Meter & meter = session->tempo_map().meter_at( now_frame );
1134         int subdiv = 2;
1135         if ( meter.note_divisor() == 8 && (meter.beats_per_bar() == 12.0 || meter.beats_per_bar() == 9.0 || meter.beats_per_bar() == 6.0) )
1136         {
1137                 subdiv = 3;
1138         }
1139         
1140         uint32_t subdivisions = bbt_time.ticks / uint32_t( Meter::ticks_per_beat / subdiv );
1141         uint32_t ticks = bbt_time.ticks % uint32_t( Meter::ticks_per_beat / subdiv );
1142         
1143         os << setw(2) << setfill('0') << subdivisions + 1;
1144         os << setw(3) << setfill('0') << ticks;
1145         
1146         return os.str();
1147 }
1148
1149 string MackieControlProtocol::format_smpte_timecode( nframes_t now_frame )
1150 {
1151         SMPTE::Time smpte;
1152         session->smpte_time( now_frame, smpte );
1153
1154         // According to the Logic docs
1155         // digits: 888/88/88/888
1156         // SMPTE mode: Hours/Minutes/Seconds/Frames
1157         ostringstream os;
1158         os << setw(3) << setfill('0') << smpte.hours;
1159         os << setw(2) << setfill('0') << smpte.minutes;
1160         os << setw(2) << setfill('0') << smpte.seconds;
1161         os << setw(3) << setfill('0') << smpte.frames;
1162         
1163         return os.str();
1164 }
1165
1166 void MackieControlProtocol::update_timecode_display()
1167 {
1168         if ( surface().has_timecode_display() )
1169         {
1170                 // do assignment here so current_frame is fixed
1171                 nframes_t current_frame = session->transport_frame();
1172                 string timecode;
1173                 
1174                 switch ( _timecode_type )
1175                 {
1176                         case ARDOUR::AnyTime::BBT:
1177                                 timecode = format_bbt_timecode( current_frame );
1178                                 break;
1179                         case ARDOUR::AnyTime::SMPTE:
1180                                 timecode = format_smpte_timecode( current_frame );
1181                                 break;
1182                         default:
1183                                 ostringstream os;
1184                                 os << "Unknown timecode: " << _timecode_type;
1185                                 throw runtime_error( os.str() );
1186                 }       
1187                 
1188                 // only write the timecode string to the MCU if it's changed
1189                 // since last time. This is to reduce midi bandwidth used.
1190                 if ( timecode != _timecode_last )
1191                 {
1192                         surface().display_timecode( mcu_port(), builder, timecode, _timecode_last );
1193                         _timecode_last = timecode;
1194                 }
1195         }
1196 }
1197
1198 void MackieControlProtocol::poll_session_data()
1199 {
1200         if ( _active && _automation_last.elapsed() >= 20 )
1201         {
1202                 // do all currently mapped routes
1203                 for( RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it )
1204                 {
1205                         update_automation( **it );
1206                 }
1207                 
1208                 // and the master strip
1209                 if ( master_route_signal != 0 )
1210                 {
1211                         update_automation( *master_route_signal );
1212                 }
1213                 
1214                 update_timecode_display();
1215                 
1216                 _automation_last.start();
1217         }
1218 }
1219
1220 /////////////////////////////////////
1221 // Transport Buttons
1222 /////////////////////////////////////
1223
1224 LedState MackieControlProtocol::frm_left_press( Button & button )
1225 {
1226         // can use first_mark_before/after as well
1227         unsigned long elapsed = _frm_left_last.restart();
1228         
1229         Location * loc = session->locations()->first_location_before (
1230                 session->transport_frame()
1231         );
1232         
1233         // allow a quick double to go past a previous mark 
1234         if ( session->transport_rolling() && elapsed < 500 && loc != 0 )
1235         {
1236                 Location * loc_two_back = session->locations()->first_location_before ( loc->start() );
1237                 if ( loc_two_back != 0 )
1238                 {
1239                         loc = loc_two_back;
1240                 }
1241         }
1242         
1243         // move to the location, if it's valid
1244         if ( loc != 0 )
1245         {
1246                 session->request_locate( loc->start(), session->transport_rolling() );
1247         }
1248         
1249         return on;
1250 }
1251
1252 LedState MackieControlProtocol::frm_left_release( Button & button )
1253 {
1254         return off;
1255 }
1256
1257 LedState MackieControlProtocol::frm_right_press( Button & button )
1258 {
1259         // can use first_mark_before/after as well
1260         Location * loc = session->locations()->first_location_after (
1261                 session->transport_frame()
1262         );
1263         if ( loc != 0 ) session->request_locate( loc->start(), session->transport_rolling() );
1264         return on;
1265 }
1266
1267 LedState MackieControlProtocol::frm_right_release( Button & button )
1268 {
1269         return off;
1270 }
1271
1272 LedState MackieControlProtocol::stop_press( Button & button )
1273 {
1274         session->request_stop();
1275         return on;
1276 }
1277
1278 LedState MackieControlProtocol::stop_release( Button & button )
1279 {
1280         return session->transport_stopped();
1281 }
1282
1283 LedState MackieControlProtocol::play_press( Button & button )
1284 {
1285         session->request_transport_speed( 1.0 );
1286         return on;
1287 }
1288
1289 LedState MackieControlProtocol::play_release( Button & button )
1290 {
1291         return session->transport_rolling();
1292 }
1293
1294 LedState MackieControlProtocol::record_press( Button & button )
1295 {
1296         if ( session->get_record_enabled() )
1297                 session->disable_record( false );
1298         else
1299                 session->maybe_enable_record();
1300         return on;
1301 }
1302
1303 LedState MackieControlProtocol::record_release( Button & button )
1304 {
1305         if ( session->get_record_enabled() )
1306         {
1307                 if ( session->transport_rolling() )
1308                         return on;
1309                 else
1310                         return flashing;
1311         }
1312         else
1313                 return off;
1314 }
1315
1316 LedState MackieControlProtocol::rewind_press( Button & button )
1317 {
1318         _jog_wheel.push( JogWheel::speed );
1319         _jog_wheel.transport_direction( -1 );
1320         session->request_transport_speed( -_jog_wheel.transport_speed() );
1321         return on;
1322 }
1323
1324 LedState MackieControlProtocol::rewind_release( Button & button )
1325 {
1326         _jog_wheel.pop();
1327         _jog_wheel.transport_direction( 0 );
1328         if ( _transport_previously_rolling )
1329                 session->request_transport_speed( 1.0 );
1330         else
1331                 session->request_stop();
1332         return off;
1333 }
1334
1335 LedState MackieControlProtocol::ffwd_press( Button & button )
1336 {
1337         _jog_wheel.push( JogWheel::speed );
1338         _jog_wheel.transport_direction( 1 );
1339         session->request_transport_speed( _jog_wheel.transport_speed() );
1340         return on;
1341 }
1342
1343 LedState MackieControlProtocol::ffwd_release( Button & button )
1344 {
1345         _jog_wheel.pop();
1346         _jog_wheel.transport_direction( 0 );
1347         if ( _transport_previously_rolling )
1348                 session->request_transport_speed( 1.0 );
1349         else
1350                 session->request_stop();
1351         return off;
1352 }
1353
1354 LedState MackieControlProtocol::loop_press( Button & button )
1355 {
1356         session->request_play_loop( !session->get_play_loop() );
1357         return on;
1358 }
1359
1360 LedState MackieControlProtocol::loop_release( Button & button )
1361 {
1362         return session->get_play_loop();
1363 }
1364
1365 LedState MackieControlProtocol::punch_in_press( Button & button )
1366 {
1367         bool state = !Config->get_punch_in();
1368         Config->set_punch_in( state );
1369         return state;
1370 }
1371
1372 LedState MackieControlProtocol::punch_in_release( Button & button )
1373 {
1374         return Config->get_punch_in();
1375 }
1376
1377 LedState MackieControlProtocol::punch_out_press( Button & button )
1378 {
1379         bool state = !Config->get_punch_out();
1380         Config->set_punch_out( state );
1381         return state;
1382 }
1383
1384 LedState MackieControlProtocol::punch_out_release( Button & button )
1385 {
1386         return Config->get_punch_out();
1387 }
1388
1389 LedState MackieControlProtocol::home_press( Button & button )
1390 {
1391         session->goto_start();
1392         return on;
1393 }
1394
1395 LedState MackieControlProtocol::home_release( Button & button )
1396 {
1397         return off;
1398 }
1399
1400 LedState MackieControlProtocol::end_press( Button & button )
1401 {
1402         session->goto_end();
1403         return on;
1404 }
1405
1406 LedState MackieControlProtocol::end_release( Button & button )
1407 {
1408         return off;
1409 }
1410
1411 LedState MackieControlProtocol::clicking_press( Button & button )
1412 {
1413         bool state = !Config->get_clicking();
1414         Config->set_clicking( state );
1415         return state;
1416 }
1417
1418 LedState MackieControlProtocol::clicking_release( Button & button )
1419 {
1420         return Config->get_clicking();
1421 }
1422
1423 LedState MackieControlProtocol::global_solo_press( Button & button )
1424 {
1425         bool state = !session->soloing();
1426         session->set_all_solo ( state );
1427         return state;
1428 }
1429
1430 LedState MackieControlProtocol::global_solo_release( Button & button )
1431 {
1432         return session->soloing();
1433 }
1434
1435 ///////////////////////////////////////////
1436 // Session signals
1437 ///////////////////////////////////////////
1438
1439 void MackieControlProtocol::notify_parameter_changed( const char * name_str )
1440 {
1441         string name( name_str );
1442         if ( name == "punch-in" )
1443         {
1444                 update_global_button( "punch_in", Config->get_punch_in() );
1445         }
1446         else if ( name == "punch-out" )
1447         {
1448                 update_global_button( "punch_out", Config->get_punch_out() );
1449         }
1450         else if ( name == "clicking" )
1451         {
1452                 update_global_button( "clicking", Config->get_clicking() );
1453         }
1454         else
1455         {
1456 #ifdef DEBUG
1457                 cout << "parameter changed: " << name << endl;
1458 #endif
1459         }
1460 }
1461
1462 // RouteList is the set of routes that have just been added
1463 void MackieControlProtocol::notify_route_added( ARDOUR::Session::RouteList & rl )
1464 {
1465         // currently assigned banks are less than the full set of
1466         // strips, so activate the new strip now.
1467         if ( route_signals.size() < route_table.size() )
1468         {
1469                 refresh_current_bank();
1470         }
1471         // otherwise route added, but current bank needs no updating
1472         
1473         // make sure remote id changes in the new route are handled
1474         typedef ARDOUR::Session::RouteList ARS;
1475         for ( ARS::iterator it = rl.begin(); it != rl.end(); ++it )
1476         {
1477                 connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) );
1478         }
1479 }
1480
1481 void MackieControlProtocol::notify_solo_active_changed( bool active )
1482 {
1483         Button * rude_solo = reinterpret_cast<Button*>( surface().controls_by_name["solo"] );
1484         mcu_port().write( builder.build_led( *rude_solo, active ? flashing : off ) );
1485 }
1486
1487 void MackieControlProtocol::notify_remote_id_changed()
1488 {
1489         Sorted sorted = get_sorted_routes();
1490         
1491         // if a remote id has been moved off the end, we need to shift
1492         // the current bank backwards.
1493         if ( sorted.size() - _current_initial_bank < route_signals.size() )
1494         {
1495                 // but don't shift backwards past the zeroth channel
1496                 switch_banks( max((Sorted::size_type) 0, sorted.size() - route_signals.size() ) );
1497         }
1498         // Otherwise just refresh the current bank
1499         else
1500         {
1501                 refresh_current_bank();
1502         }
1503 }
1504
1505 ///////////////////////////////////////////
1506 // Transport signals
1507 ///////////////////////////////////////////
1508
1509 void MackieControlProtocol::notify_record_state_changed()
1510 {
1511         // switch rec button on / off / flashing
1512         Button * rec = reinterpret_cast<Button*>( surface().controls_by_name["record"] );
1513         mcu_port().write( builder.build_led( *rec, record_release( *rec ) ) );
1514 }
1515
1516 void MackieControlProtocol::notify_transport_state_changed()
1517 {
1518         // switch various play and stop buttons on / off
1519         update_global_button( "play", session->transport_rolling() );
1520         update_global_button( "stop", !session->transport_rolling() );
1521         update_global_button( "loop", session->get_play_loop() );
1522         
1523         _transport_previously_rolling = session->transport_rolling();
1524         
1525         // rec is special because it's tristate
1526         Button * rec = reinterpret_cast<Button*>( surface().controls_by_name["record"] );
1527         mcu_port().write( builder.build_led( *rec, record_release( *rec ) ) );
1528 }
1529
1530 /////////////////////////////////////
1531 // Bank Switching
1532 /////////////////////////////////////
1533 LedState MackieControlProtocol::left_press( Button & button )
1534 {
1535         Sorted sorted = get_sorted_routes();
1536         if ( sorted.size() > route_table.size() )
1537         {
1538                 int new_initial = _current_initial_bank - route_table.size();
1539                 if ( new_initial < 0 ) new_initial = 0;
1540                 if ( new_initial != int( _current_initial_bank ) )
1541                 {
1542                         session->set_dirty();
1543                         switch_banks( new_initial );
1544                 }
1545                 
1546                 return on;
1547         }
1548         else
1549         {
1550                 return flashing;
1551         }
1552 }
1553
1554 LedState MackieControlProtocol::left_release( Button & button )
1555 {
1556         return off;
1557 }
1558
1559 LedState MackieControlProtocol::right_press( Button & button )
1560 {
1561         Sorted sorted = get_sorted_routes();
1562         if ( sorted.size() > route_table.size() )
1563         {
1564                 uint32_t delta = sorted.size() - ( route_table.size() + _current_initial_bank );
1565                 if ( delta > route_table.size() ) delta = route_table.size();
1566                 if ( delta > 0 )
1567                 {
1568                         session->set_dirty();
1569                         switch_banks( _current_initial_bank + delta );
1570                 }
1571                 
1572                 return on;
1573         }
1574         else
1575         {
1576                 return flashing;
1577         }
1578 }
1579
1580 LedState MackieControlProtocol::right_release( Button & button )
1581 {
1582         return off;
1583 }
1584
1585 LedState MackieControlProtocol::channel_left_press( Button & button )
1586 {
1587         Sorted sorted = get_sorted_routes();
1588         if ( sorted.size() > route_table.size() )
1589         {
1590                 prev_track();
1591                 return on;
1592         }
1593         else
1594         {
1595                 return flashing;
1596         }
1597 }
1598
1599 LedState MackieControlProtocol::channel_left_release( Button & button )
1600 {
1601         return off;
1602 }
1603
1604 LedState MackieControlProtocol::channel_right_press( Button & button )
1605 {
1606         Sorted sorted = get_sorted_routes();
1607         if ( sorted.size() > route_table.size() )
1608         {
1609                 next_track();
1610                 return on;
1611         }
1612         else
1613         {
1614                 return flashing;
1615         }
1616 }
1617
1618 LedState MackieControlProtocol::channel_right_release( Button & button )
1619 {
1620         return off;
1621 }
1622
1623 /////////////////////////////////////
1624 // Functions
1625 /////////////////////////////////////
1626 LedState MackieControlProtocol::marker_press( Button & button )
1627 {
1628         // cut'n'paste from LocationUI::add_new_location()
1629         string markername;
1630         nframes_t where = session->audible_frame();
1631         session->locations()->next_available_name(markername,"mcu");
1632         Location *location = new Location (where, where, markername, Location::IsMark);
1633         session->begin_reversible_command (_("add marker"));
1634         XMLNode &before = session->locations()->get_state();
1635         session->locations()->add (location, true);
1636         XMLNode &after = session->locations()->get_state();
1637         session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
1638         session->commit_reversible_command ();
1639         return on;
1640 }
1641
1642 LedState MackieControlProtocol::marker_release( Button & button )
1643 {
1644         return off;
1645 }
1646
1647 void jog_wheel_state_display( JogWheel::State state, SurfacePort & port )
1648 {
1649         switch( state )
1650         {
1651                 case JogWheel::zoom: port.write( builder.two_char_display( "Zm" ) ); break;
1652                 case JogWheel::scroll: port.write( builder.two_char_display( "Sc" ) ); break;
1653                 case JogWheel::scrub: port.write( builder.two_char_display( "Sb" ) ); break;
1654                 case JogWheel::shuttle: port.write( builder.two_char_display( "Sh" ) ); break;
1655                 case JogWheel::speed: port.write( builder.two_char_display( "Sp" ) ); break;
1656                 case JogWheel::select: port.write( builder.two_char_display( "Se" ) ); break;
1657         }
1658 }
1659
1660 Mackie::LedState MackieControlProtocol::zoom_press( Mackie::Button & )
1661 {
1662         _jog_wheel.zoom_state_toggle();
1663         update_global_button( "scrub", _jog_wheel.jog_wheel_state() == JogWheel::scrub );
1664         jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
1665         return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
1666 }
1667
1668 Mackie::LedState MackieControlProtocol::zoom_release( Mackie::Button & )
1669 {
1670         return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
1671 }
1672
1673 Mackie::LedState MackieControlProtocol::scrub_press( Mackie::Button & )
1674 {
1675         _jog_wheel.scrub_state_cycle();
1676         update_global_button( "zoom", _jog_wheel.jog_wheel_state() == JogWheel::zoom );
1677         jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
1678         return
1679                 _jog_wheel.jog_wheel_state() == JogWheel::scrub
1680                 ||
1681                 _jog_wheel.jog_wheel_state() == JogWheel::shuttle
1682         ;
1683 }
1684
1685 Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & )
1686 {
1687         return
1688                 _jog_wheel.jog_wheel_state() == JogWheel::scrub
1689                 ||
1690                 _jog_wheel.jog_wheel_state() == JogWheel::shuttle
1691         ;
1692 }
1693
1694 LedState MackieControlProtocol::drop_press( Button & button )
1695 {
1696         session->remove_last_capture();
1697         return on;
1698 }
1699
1700 LedState MackieControlProtocol::drop_release( Button & button )
1701 {
1702         return off;
1703 }
1704
1705 LedState MackieControlProtocol::save_press( Button & button )
1706 {
1707         session->save_state( "" );
1708         return on;
1709 }
1710
1711 LedState MackieControlProtocol::save_release( Button & button )
1712 {
1713         return off;
1714 }
1715
1716 LedState MackieControlProtocol::smpte_beats_press( Button & )
1717 {
1718         switch ( _timecode_type )
1719         {
1720                 case ARDOUR::AnyTime::BBT:
1721                         _timecode_type = ARDOUR::AnyTime::SMPTE;
1722                         break;
1723                 case ARDOUR::AnyTime::SMPTE:
1724                         _timecode_type = ARDOUR::AnyTime::BBT;
1725                         break;
1726                 default:
1727                         ostringstream os;
1728                         os << "Unknown Anytime::Type " << _timecode_type;
1729                         throw runtime_error( os.str() );
1730         }
1731         update_smpte_beats_led();
1732         return on;
1733 }
1734
1735 LedState MackieControlProtocol::smpte_beats_release( Button & )
1736 {
1737         return off;
1738 }