Part 1 of loading 2.X sessions; some things work, some things don't, hacks a-plenty.
[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         session->config.ParameterChanged.connect ( ( mem_fun (*this, &MackieControlProtocol::notify_parameter_changed) ) );
575         // receive rude solo changed
576         connections_back = session->SoloActive.connect( ( mem_fun (*this, &MackieControlProtocol::notify_solo_active_changed) ) );
577         
578         // make sure remote id changed signals reach here
579         // see also notify_route_added
580         Sorted sorted = get_sorted_routes();
581         for ( Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it )
582         {
583                 connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) );
584         }
585 }
586
587 void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
588 {
589 #ifdef DEBUG
590         cout << "add port " << midi_port.name() << ", " << midi_port.device() << ", " << midi_port.type() << endl;
591         cout << "MIDI::Port::ALSA_Sequencer " << MIDI::Port::ALSA_Sequencer << endl;
592         cout << "MIDI::Port::Unknown " << MIDI::Port::Unknown << endl;
593 #endif
594         if ( string( midi_port.device() ) == string( "ardour" ) && midi_port.type() == MIDI::Port::ALSA_Sequencer )
595         {
596                 throw MackieControlException( "The Mackie MCU driver will not use a port with device=ardour" );
597         }
598         else if ( midi_port.type() == MIDI::Port::ALSA_Sequencer )
599         {
600                 throw MackieControlException( "alsa/sequencer ports don't work with the Mackie MCU driver right now" );
601         }
602         else
603         {
604                 MackiePort * sport = new MackiePort( *this, midi_port, number );
605                 _ports.push_back( sport );
606                 
607                 connections_back = sport->init_event.connect(
608                         sigc::bind (
609                                 mem_fun (*this, &MackieControlProtocol::handle_port_init)
610                                 , sport
611                         )
612                 );
613
614                 connections_back = sport->active_event.connect(
615                         sigc::bind (
616                                 mem_fun (*this, &MackieControlProtocol::handle_port_active)
617                                 , sport
618                         )
619                 );
620
621                 connections_back = sport->inactive_event.connect(
622                         sigc::bind (
623                                 mem_fun (*this, &MackieControlProtocol::handle_port_inactive)
624                                 , sport
625                         )
626                 );
627                 
628                 _ports_changed = true;
629         }
630 }
631
632 void MackieControlProtocol::create_ports()
633 {
634         MIDI::Manager * mm = MIDI::Manager::instance();
635
636         // open main port
637         {
638                 MIDI::Port * midi_port = mm->port( default_port_name );
639
640                 if ( midi_port == 0 ) {
641                         ostringstream os;
642                         os << string_compose( _("no MIDI port named \"%1\" exists - Mackie control disabled"), default_port_name );
643                         error << os.str() << endmsg;
644                         throw MackieControlException( os.str() );
645                 }
646                 add_port( *midi_port, 0 );
647         }
648         
649         // open extender ports. Up to 9. Should be enough.
650         // could also use mm->get_midi_ports()
651         string ext_port_base = "mcu_xt_";
652         for ( int index = 1; index <= 9; ++index )
653         {
654                 ostringstream os;
655                 os << ext_port_base << index;
656                 MIDI::Port * midi_port = mm->port( os.str() );
657                 if ( midi_port != 0 ) add_port( *midi_port, index );
658         }
659 }
660
661 shared_ptr<Route> MackieControlProtocol::master_route()
662 {
663         return session->master_out ();
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, int version)
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 && route->panner() )
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 *)
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                 boost::shared_ptr<Panner> panner = route_signal->route()->panner();
1074                 if ( (panner && 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         if ( rs.route()->panner() ) {
1111                 ARDOUR::AutoState panner_state = rs.route()->panner()->automation_state();
1112                 if ( panner_state == Touch || panner_state == Play )
1113                 {
1114                         notify_panner_changed( &rs, false );
1115                 }
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 &)
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 &)
1253 {
1254         return off;
1255 }
1256
1257 LedState MackieControlProtocol::frm_right_press (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 &)
1268 {
1269         return off;
1270 }
1271
1272 LedState MackieControlProtocol::stop_press (Button &)
1273 {
1274         session->request_stop();
1275         return on;
1276 }
1277
1278 LedState MackieControlProtocol::stop_release (Button &)
1279 {
1280         return session->transport_stopped();
1281 }
1282
1283 LedState MackieControlProtocol::play_press (Button &)
1284 {
1285         session->request_transport_speed( 1.0 );
1286         return on;
1287 }
1288
1289 LedState MackieControlProtocol::play_release (Button &)
1290 {
1291         return session->transport_rolling();
1292 }
1293
1294 LedState MackieControlProtocol::record_press (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 &)
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 &)
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 &)
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 &)
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 &)
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 &)
1355 {
1356         session->request_play_loop( !session->get_play_loop() );
1357         return on;
1358 }
1359
1360 LedState MackieControlProtocol::loop_release (Button &)
1361 {
1362         return session->get_play_loop();
1363 }
1364
1365 LedState MackieControlProtocol::punch_in_press (Button &)
1366 {
1367         bool state = !session->config.get_punch_in();
1368         session->config.set_punch_in( state );
1369         return state;
1370 }
1371
1372 LedState MackieControlProtocol::punch_in_release (Button &)
1373 {
1374         return session->config.get_punch_in();
1375 }
1376
1377 LedState MackieControlProtocol::punch_out_press (Button &)
1378 {
1379         bool state = !session->config.get_punch_out();
1380         session->config.set_punch_out( state );
1381         return state;
1382 }
1383
1384 LedState MackieControlProtocol::punch_out_release (Button &)
1385 {
1386         return session->config.get_punch_out();
1387 }
1388
1389 LedState MackieControlProtocol::home_press (Button &)
1390 {
1391         session->goto_start();
1392         return on;
1393 }
1394
1395 LedState MackieControlProtocol::home_release (Button &)
1396 {
1397         return off;
1398 }
1399
1400 LedState MackieControlProtocol::end_press (Button &)
1401 {
1402         session->goto_end();
1403         return on;
1404 }
1405
1406 LedState MackieControlProtocol::end_release (Button &)
1407 {
1408         return off;
1409 }
1410
1411 LedState MackieControlProtocol::clicking_press (Button &)
1412 {
1413         bool state = !Config->get_clicking();
1414         Config->set_clicking( state );
1415         return state;
1416 }
1417
1418 LedState MackieControlProtocol::clicking_release (Button &)
1419 {
1420         return Config->get_clicking();
1421 }
1422
1423 LedState MackieControlProtocol::global_solo_press (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 &)
1431 {
1432         return session->soloing();
1433 }
1434
1435 ///////////////////////////////////////////
1436 // Session signals
1437 ///////////////////////////////////////////
1438
1439 void MackieControlProtocol::notify_parameter_changed (std::string const & p)
1440 {
1441         if ( p == "punch-in" )
1442         {
1443                 update_global_button( "punch_in", session->config.get_punch_in() );
1444         }
1445         else if ( p == "punch-out" )
1446         {
1447                 update_global_button( "punch_out", session->config.get_punch_out() );
1448         }
1449         else if ( p == "clicking" )
1450         {
1451                 update_global_button( "clicking", Config->get_clicking() );
1452         }
1453         else
1454         {
1455 #ifdef DEBUG
1456                 cout << "parameter changed: " << p << endl;
1457 #endif
1458         }
1459 }
1460
1461 // RouteList is the set of routes that have just been added
1462 void MackieControlProtocol::notify_route_added( ARDOUR::RouteList & rl )
1463 {
1464         // currently assigned banks are less than the full set of
1465         // strips, so activate the new strip now.
1466         if ( route_signals.size() < route_table.size() )
1467         {
1468                 refresh_current_bank();
1469         }
1470         // otherwise route added, but current bank needs no updating
1471         
1472         // make sure remote id changes in the new route are handled
1473         typedef ARDOUR::RouteList ARS;
1474         for ( ARS::iterator it = rl.begin(); it != rl.end(); ++it )
1475         {
1476                 connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) );
1477         }
1478 }
1479
1480 void MackieControlProtocol::notify_solo_active_changed( bool active )
1481 {
1482         Button * rude_solo = reinterpret_cast<Button*>( surface().controls_by_name["solo"] );
1483         mcu_port().write( builder.build_led( *rude_solo, active ? flashing : off ) );
1484 }
1485
1486 void MackieControlProtocol::notify_remote_id_changed()
1487 {
1488         Sorted sorted = get_sorted_routes();
1489         
1490         // if a remote id has been moved off the end, we need to shift
1491         // the current bank backwards.
1492         if ( sorted.size() - _current_initial_bank < route_signals.size() )
1493         {
1494                 // but don't shift backwards past the zeroth channel
1495                 switch_banks( max((Sorted::size_type) 0, sorted.size() - route_signals.size() ) );
1496         }
1497         // Otherwise just refresh the current bank
1498         else
1499         {
1500                 refresh_current_bank();
1501         }
1502 }
1503
1504 ///////////////////////////////////////////
1505 // Transport signals
1506 ///////////////////////////////////////////
1507
1508 void MackieControlProtocol::notify_record_state_changed()
1509 {
1510         // switch rec button on / off / flashing
1511         Button * rec = reinterpret_cast<Button*>( surface().controls_by_name["record"] );
1512         mcu_port().write( builder.build_led( *rec, record_release( *rec ) ) );
1513 }
1514
1515 void MackieControlProtocol::notify_transport_state_changed()
1516 {
1517         // switch various play and stop buttons on / off
1518         update_global_button( "play", session->transport_rolling() );
1519         update_global_button( "stop", !session->transport_rolling() );
1520         update_global_button( "loop", session->get_play_loop() );
1521         
1522         _transport_previously_rolling = session->transport_rolling();
1523         
1524         // rec is special because it's tristate
1525         Button * rec = reinterpret_cast<Button*>( surface().controls_by_name["record"] );
1526         mcu_port().write( builder.build_led( *rec, record_release( *rec ) ) );
1527 }
1528
1529 /////////////////////////////////////
1530 // Bank Switching
1531 /////////////////////////////////////
1532 LedState MackieControlProtocol::left_press (Button &)
1533 {
1534         Sorted sorted = get_sorted_routes();
1535         if ( sorted.size() > route_table.size() )
1536         {
1537                 int new_initial = _current_initial_bank - route_table.size();
1538                 if ( new_initial < 0 ) new_initial = 0;
1539                 if ( new_initial != int( _current_initial_bank ) )
1540                 {
1541                         session->set_dirty();
1542                         switch_banks( new_initial );
1543                 }
1544                 
1545                 return on;
1546         }
1547         else
1548         {
1549                 return flashing;
1550         }
1551 }
1552
1553 LedState MackieControlProtocol::left_release (Button &)
1554 {
1555         return off;
1556 }
1557
1558 LedState MackieControlProtocol::right_press (Button &)
1559 {
1560         Sorted sorted = get_sorted_routes();
1561         if ( sorted.size() > route_table.size() )
1562         {
1563                 uint32_t delta = sorted.size() - ( route_table.size() + _current_initial_bank );
1564                 if ( delta > route_table.size() ) delta = route_table.size();
1565                 if ( delta > 0 )
1566                 {
1567                         session->set_dirty();
1568                         switch_banks( _current_initial_bank + delta );
1569                 }
1570                 
1571                 return on;
1572         }
1573         else
1574         {
1575                 return flashing;
1576         }
1577 }
1578
1579 LedState MackieControlProtocol::right_release (Button &)
1580 {
1581         return off;
1582 }
1583
1584 LedState MackieControlProtocol::channel_left_press (Button &)
1585 {
1586         Sorted sorted = get_sorted_routes();
1587         if ( sorted.size() > route_table.size() )
1588         {
1589                 prev_track();
1590                 return on;
1591         }
1592         else
1593         {
1594                 return flashing;
1595         }
1596 }
1597
1598 LedState MackieControlProtocol::channel_left_release (Button &)
1599 {
1600         return off;
1601 }
1602
1603 LedState MackieControlProtocol::channel_right_press (Button &)
1604 {
1605         Sorted sorted = get_sorted_routes();
1606         if ( sorted.size() > route_table.size() )
1607         {
1608                 next_track();
1609                 return on;
1610         }
1611         else
1612         {
1613                 return flashing;
1614         }
1615 }
1616
1617 LedState MackieControlProtocol::channel_right_release (Button &)
1618 {
1619         return off;
1620 }
1621
1622 /////////////////////////////////////
1623 // Functions
1624 /////////////////////////////////////
1625 LedState MackieControlProtocol::marker_press (Button &)
1626 {
1627         // cut'n'paste from LocationUI::add_new_location()
1628         string markername;
1629         nframes_t where = session->audible_frame();
1630         session->locations()->next_available_name(markername,"mcu");
1631         Location *location = new Location (where, where, markername, Location::IsMark);
1632         session->begin_reversible_command (_("add marker"));
1633         XMLNode &before = session->locations()->get_state();
1634         session->locations()->add (location, true);
1635         XMLNode &after = session->locations()->get_state();
1636         session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
1637         session->commit_reversible_command ();
1638         return on;
1639 }
1640
1641 LedState MackieControlProtocol::marker_release (Button &)
1642 {
1643         return off;
1644 }
1645
1646 void jog_wheel_state_display( JogWheel::State state, SurfacePort & port )
1647 {
1648         switch( state )
1649         {
1650                 case JogWheel::zoom: port.write( builder.two_char_display( "Zm" ) ); break;
1651                 case JogWheel::scroll: port.write( builder.two_char_display( "Sc" ) ); break;
1652                 case JogWheel::scrub: port.write( builder.two_char_display( "Sb" ) ); break;
1653                 case JogWheel::shuttle: port.write( builder.two_char_display( "Sh" ) ); break;
1654                 case JogWheel::speed: port.write( builder.two_char_display( "Sp" ) ); break;
1655                 case JogWheel::select: port.write( builder.two_char_display( "Se" ) ); break;
1656         }
1657 }
1658
1659 Mackie::LedState MackieControlProtocol::zoom_press( Mackie::Button & )
1660 {
1661         _jog_wheel.zoom_state_toggle();
1662         update_global_button( "scrub", _jog_wheel.jog_wheel_state() == JogWheel::scrub );
1663         jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
1664         return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
1665 }
1666
1667 Mackie::LedState MackieControlProtocol::zoom_release( Mackie::Button & )
1668 {
1669         return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
1670 }
1671
1672 Mackie::LedState MackieControlProtocol::scrub_press( Mackie::Button & )
1673 {
1674         _jog_wheel.scrub_state_cycle();
1675         update_global_button( "zoom", _jog_wheel.jog_wheel_state() == JogWheel::zoom );
1676         jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
1677         return
1678                 _jog_wheel.jog_wheel_state() == JogWheel::scrub
1679                 ||
1680                 _jog_wheel.jog_wheel_state() == JogWheel::shuttle
1681         ;
1682 }
1683
1684 Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & )
1685 {
1686         return
1687                 _jog_wheel.jog_wheel_state() == JogWheel::scrub
1688                 ||
1689                 _jog_wheel.jog_wheel_state() == JogWheel::shuttle
1690         ;
1691 }
1692
1693 LedState MackieControlProtocol::drop_press (Button &)
1694 {
1695         session->remove_last_capture();
1696         return on;
1697 }
1698
1699 LedState MackieControlProtocol::drop_release (Button &)
1700 {
1701         return off;
1702 }
1703
1704 LedState MackieControlProtocol::save_press (Button &)
1705 {
1706         session->save_state( "" );
1707         return on;
1708 }
1709
1710 LedState MackieControlProtocol::save_release (Button &)
1711 {
1712         return off;
1713 }
1714
1715 LedState MackieControlProtocol::smpte_beats_press (Button &)
1716 {
1717         switch ( _timecode_type )
1718         {
1719                 case ARDOUR::AnyTime::BBT:
1720                         _timecode_type = ARDOUR::AnyTime::SMPTE;
1721                         break;
1722                 case ARDOUR::AnyTime::SMPTE:
1723                         _timecode_type = ARDOUR::AnyTime::BBT;
1724                         break;
1725                 default:
1726                         ostringstream os;
1727                         os << "Unknown Anytime::Type " << _timecode_type;
1728                         throw runtime_error( os.str() );
1729         }
1730         update_smpte_beats_led();
1731         return on;
1732 }
1733
1734 LedState MackieControlProtocol::smpte_beats_release( Button & )
1735 {
1736         return off;
1737 }