major design changes: use glib event loop for MIDI thread/UI; rework design of BaseUI...
[ardour.git] / libs / surfaces / mackie / mackie_control_protocol.cc
index 6902b3406d11d3e0d8bf8c73c69fd533d46258b5..6e65308f33597da4c94044dde356c832d48472f8 100644 (file)
 
 #include <boost/shared_array.hpp>
 
-#include <midi++/types.h>
-#include <midi++/port.h>
-#include <midi++/manager.h>
-#include <pbd/pthread_utils.h>
-#include <pbd/error.h>
-#include <pbd/memento_command.h>
-#include <pbd/convert.h>
-
-#include <ardour/route.h>
-#include <ardour/session.h>
-#include <ardour/location.h>
-#include <ardour/dB.h>
-#include <ardour/panner.h>
-#include <ardour/tempo.h>
-#include <ardour/types.h>
+#include "midi++/types.h"
+#include "midi++/port.h"
+#include "midi++/manager.h"
+#include "pbd/pthread_utils.h"
+#include "pbd/error.h"
+#include "pbd/memento_command.h"
+#include "pbd/convert.h"
+
+#include "ardour/session.h"
+#include "ardour/route.h"
+#include "ardour/location.h"
+#include "ardour/dB.h"
+#include "ardour/panner.h"
+#include "ardour/tempo.h"
+#include "ardour/types.h"
 
 #include "mackie_control_protocol.h"
 
@@ -87,7 +87,7 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
        cout << "MackieControlProtocol::MackieControlProtocol" << endl;
 #endif
        // will start reading from ports, as soon as there are some
-       pthread_create_and_store (X_("mackie monitor"), &thread, 0, _monitor_work, this);
+       pthread_create_and_store (X_("mackie monitor"), &thread, _monitor_work, this);
 }
 
 MackieControlProtocol::~MackieControlProtocol()
@@ -187,7 +187,7 @@ MackiePort & MackieControlProtocol::port_for_id( uint32_t index )
                current_max += (*it)->strips();
                if ( index < current_max ) return **it;
        }
-       
+
        // oops - no matching port
        ostringstream os;
        os << "No port for index " << index;
@@ -216,15 +216,15 @@ struct RouteByRemoteId
 MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes()
 {
        Sorted sorted;
-       
+
        // fetch all routes
        boost::shared_ptr<RouteList> routes = session->get_routes();
        set<uint32_t> remote_ids;
-       
+
        // routes with remote_id 0 should never be added
        // TODO verify this with ardour devs
        // remote_ids.insert( 0 );
-       
+
        // sort in remote_id order, and exclude master, control and hidden routes
        // and any routes that are already set.
        for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it )
@@ -255,7 +255,7 @@ void MackieControlProtocol::switch_banks( int initial )
 {
        // DON'T prevent bank switch if initial == _current_initial_bank
        // because then this method can't be used as a refresh
-       
+
        // sanity checking
        Sorted sorted = get_sorted_routes();
        int delta = sorted.size() - route_table.size();
@@ -267,11 +267,11 @@ void MackieControlProtocol::switch_banks( int initial )
                return;
        }
        _current_initial_bank = initial;
-       
+
        // first clear the signals from old routes
        // taken care of by the RouteSignal destructors
        clear_route_signals();
-       
+
        // now set the signals for new routes
        if ( _current_initial_bank <= sorted.size() )
        {
@@ -282,7 +282,7 @@ void MackieControlProtocol::switch_banks( int initial )
 #ifdef DEBUG
                cout << "switch to " << _current_initial_bank << ", " << end_pos << endl;
 #endif
-               
+
                // link routes to strips
                uint32_t i = 0;
                for ( ; it != end && it != sorted.end(); ++it, ++i )
@@ -298,7 +298,7 @@ void MackieControlProtocol::switch_banks( int initial )
                        // update strip from route
                        rs->notify_all();
                }
-               
+
                // create dead strips if there aren't enough routes to
                // fill a bank
                for ( ; i < route_table.size(); ++i )
@@ -309,25 +309,25 @@ void MackieControlProtocol::switch_banks( int initial )
                        port.write( builder.zero_strip( port, strip ) );
                }
        }
-       
+
        // display the current start bank.
        surface().display_bank_start( mcu_port(), builder, _current_initial_bank );
 }
 
 void MackieControlProtocol::zero_all()
 {
-       // TODO turn off SMPTE displays
-       
+       // TODO turn off Timecode displays
+
        // zero all strips
        for ( Surface::Strips::iterator it = surface().strips.begin(); it != surface().strips.end(); ++it )
        {
                MackiePort & port = port_for_id( (*it)->index() );
                port.write( builder.zero_strip( port, **it ) );
        }
-       
+
        // and the master strip
        mcu_port().write( builder.zero_strip( dynamic_cast<MackiePort&>( mcu_port() ), master_strip() ) );
-       
+
        // turn off global buttons and leds
        // global buttons are only ever on mcu_port, so we don't have
        // to figure out which port.
@@ -355,29 +355,29 @@ int MackieControlProtocol::set_active( bool yn )
                        if ( yn )
                        {
                                // TODO what happens if this fails half way?
-                               
+
                                // create MackiePorts
                                {
                                        Glib::Mutex::Lock lock( update_mutex );
                                        create_ports();
                                }
-                               
+
                                // make sure the ports are being listened to
                                update_ports();
-                               
+
                                // wait until poll thread is running, with ports to poll
                                // the mutex is only there because conditions require a mutex
                                {
                                        Glib::Mutex::Lock lock( update_mutex );
                                        while ( nfds == 0 ) update_cond.wait( update_mutex );
                                }
-                               
+
                                // now initialise MackiePorts - ie exchange sysex messages
                                for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
                                {
                                        (*it)->open();
                                }
-                               
+
                                // wait until all ports are active
                                // TODO a more sophisticated approach would
                                // allow things to start up with only an MCU, even if
@@ -386,15 +386,15 @@ int MackieControlProtocol::set_active( bool yn )
                                {
                                        (*it)->wait_for_init();
                                }
-                               
+
                                // create surface object. This depends on the ports being
                                // correctly initialised
                                initialize_surface();
                                connect_session_signals();
-                               
+
                                // yeehah!
                                _active = true;
-                               
+
                                // send current control positions to surface
                                // must come after _active = true otherwise it won't run
                                update_surface();
@@ -450,13 +450,13 @@ bool MackieControlProtocol::handle_strip_button( Control & control, ButtonState
                        //state = default_button_press( dynamic_cast<Button&>( control ) );
                }
        }
-       
+
        if ( control.name() == "fader_touch" )
        {
                state = bs == press;
                control.strip().gain().in_use( state );
        }
-       
+
        return state;
 }
 
@@ -484,16 +484,16 @@ void MackieControlProtocol::update_led( Mackie::Button & button, Mackie::LedStat
        }
 }
 
-void MackieControlProtocol::update_smpte_beats_led()
+void MackieControlProtocol::update_timecode_beats_led()
 {
        switch ( _timecode_type )
        {
                case ARDOUR::AnyTime::BBT:
                        update_global_led( "beats", on );
-                       update_global_led( "smpte", off );
+                       update_global_led( "timecode", off );
                        break;
-               case ARDOUR::AnyTime::SMPTE:
-                       update_global_led( "smpte", on );
+               case ARDOUR::AnyTime::Timecode:
+                       update_global_led( "timecode", on );
                        update_global_led( "beats", off );
                        break;
                default:
@@ -541,7 +541,7 @@ void MackieControlProtocol::update_surface()
                // do the initial bank switch to connect signals
                // _current_initial_bank is initialised by set_state
                switch_banks( _current_initial_bank );
-               
+
                // create a RouteSignal for the master route
 
                boost::shared_ptr<Route> mr = master_route ();
@@ -550,14 +550,14 @@ void MackieControlProtocol::update_surface()
                        // update strip from route
                        master_route_signal->notify_all();
                }
-              
+
                // sometimes the jog wheel is a pot
                surface().blank_jog_ring( mcu_port(), builder );
-               
+
                // update global buttons and displays
                notify_record_state_changed();
                notify_transport_state_changed();
-               update_smpte_beats_led();
+               update_timecode_beats_led();
        }
 }
 
@@ -574,7 +574,7 @@ void MackieControlProtocol::connect_session_signals()
        session->config.ParameterChanged.connect ( ( mem_fun (*this, &MackieControlProtocol::notify_parameter_changed) ) );
        // receive rude solo changed
        connections_back = session->SoloActive.connect( ( mem_fun (*this, &MackieControlProtocol::notify_solo_active_changed) ) );
-       
+
        // make sure remote id changed signals reach here
        // see also notify_route_added
        Sorted sorted = get_sorted_routes();
@@ -591,7 +591,7 @@ void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
        cout << "MIDI::Port::ALSA_Sequencer " << MIDI::Port::ALSA_Sequencer << endl;
        cout << "MIDI::Port::Unknown " << MIDI::Port::Unknown << endl;
 #endif
-       if ( string( midi_port.device() ) == string( "ardour" ) )
+       if ( string( midi_port.device() ) == string( "ardour" ) && midi_port.type() == MIDI::Port::ALSA_Sequencer )
        {
                throw MackieControlException( "The Mackie MCU driver will not use a port with device=ardour" );
        }
@@ -603,7 +603,7 @@ void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
        {
                MackiePort * sport = new MackiePort( *this, midi_port, number );
                _ports.push_back( sport );
-               
+
                connections_back = sport->init_event.connect(
                        sigc::bind (
                                mem_fun (*this, &MackieControlProtocol::handle_port_init)
@@ -624,7 +624,7 @@ void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
                                , sport
                        )
                );
-               
+
                _ports_changed = true;
        }
 }
@@ -645,7 +645,7 @@ void MackieControlProtocol::create_ports()
                }
                add_port( *midi_port, 0 );
        }
-       
+
        // open extender ports. Up to 9. Should be enough.
        // could also use mm->get_midi_ports()
        string ext_port_base = "mcu_xt_";
@@ -660,8 +660,7 @@ void MackieControlProtocol::create_ports()
 
 shared_ptr<Route> MackieControlProtocol::master_route()
 {
-       boost::shared_ptr<IO> mo = session->master_out ();
-       return boost::dynamic_pointer_cast<Route>(mo);
+       return session->master_out ();
 }
 
 Strip & MackieControlProtocol::master_strip()
@@ -677,9 +676,9 @@ void MackieControlProtocol::initialize_surface()
        {
                strips += (*it)->strips();
        }
-       
+
        set_route_table_size( strips );
-       
+
        // TODO same as code in mackie_port.cc
        string emulation = ARDOUR::Config->get_mackie_emulation();
        if ( emulation == "bcf" )
@@ -698,7 +697,7 @@ void MackieControlProtocol::initialize_surface()
        }
 
        _surface->init();
-       
+
        // Connect events. Must be after route table otherwise there will be trouble
        for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
        {
@@ -713,10 +712,10 @@ void MackieControlProtocol::close()
        // calls methods on objects that are deleted
        _polling = false;
        pthread_join( thread, 0 );
-       
+
        // TODO disconnect port active/inactive signals
        // Or at least put a lock here
-       
+
        // disconnect global signals from Session
        // TODO Since *this is a sigc::trackable, this shouldn't be necessary
        // but it is for some reason
@@ -726,7 +725,7 @@ void MackieControlProtocol::close()
                it->disconnect();
        }
 #endif
-       
+
        if ( _surface != 0 )
        {
                // These will fail if the port has gone away.
@@ -743,7 +742,7 @@ void MackieControlProtocol::close()
                        cout << "MackieControlProtocol::close caught exception: " << e.what() << endl;
 #endif
                }
-               
+
                for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
                {
                        try
@@ -763,21 +762,21 @@ void MackieControlProtocol::close()
 #endif
                        }
                }
-               
+
                // disconnect routes from strips
                clear_route_signals();
-               
+
                delete _surface;
                _surface = 0;
        }
-       
+
        // shut down MackiePorts
        for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
        {
                delete *it;
        }
        _ports.clear();
-       
+
        // this is done already in monitor_work. But it's here so we know.
        delete[] pfd;
        pfd = 0;
@@ -794,26 +793,26 @@ XMLNode & MackieControlProtocol::get_state()
 #ifdef DEBUG
        cout << "MackieControlProtocol::get_state" << endl;
 #endif
-       
+
        // add name of protocol
        XMLNode* node = new XMLNode( X_("Protocol") );
        node->add_property( X_("name"), _name );
-       
+
        // add current bank
        ostringstream os;
        os << _current_initial_bank;
        node->add_property( X_("bank"), os.str() );
-       
+
        return *node;
 }
 
-int MackieControlProtocol::set_state( const XMLNode & node )
+int MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
 {
 #ifdef DEBUG
        cout << "MackieControlProtocol::set_state: active " << _active << endl;
 #endif
        int retval = 0;
-       
+
        // fetch current bank
        if ( node.property( X_("bank") ) != 0 )
        {
@@ -832,7 +831,7 @@ int MackieControlProtocol::set_state( const XMLNode & node )
                        return -1;
                }
        }
-       
+
        return retval;
 }
 
@@ -855,7 +854,7 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
                                cerr << "Warning: index is " << index << " which is not in the route table, size: " << route_table.size() << endl;
                }
        }
-       
+
        // This handles control element events from the surface
        // the state of the controls on the surface is usually updated
        // from UI events.
@@ -868,14 +867,14 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
                        if ( route != 0 )
                        {
                                route->gain_control()->set_value( state.pos );
-                               
+
                                // must echo bytes back to slider now, because
                                // the notifier only works if the fader is not being
                                // touched. Which it is if we're getting input.
                                port.write( builder.build_fader( (Fader&)control, state.pos ) );
                        }
                        break;
-                       
+
                case Control::type_button:
                        if ( control.group().is_strip() )
                        {
@@ -905,7 +904,7 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
                                surface().handle_button( *this, state.button_state, dynamic_cast<Button&>( control ) );
                        }
                        break;
-                       
+
                // pot (jog wheel, external control)
                case Control::type_pot:
                        if ( control.group().is_strip() )
@@ -918,14 +917,14 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
                                                // assume pan for now
                                                float xpos;
                                                route->panner()->streampanner (0).get_effective_position (xpos);
-                                               
+
                                                // calculate new value, and trim
                                                xpos += state.delta * state.sign;
                                                if ( xpos > 1.0 )
                                                        xpos = 1.0;
                                                else if ( xpos < 0.0 )
                                                        xpos = 0.0;
-                                               
+
                                                route->panner()->streampanner (0).set_position( xpos );
                                        }
                                }
@@ -947,7 +946,7 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
                                }
                        }
                        break;
-                       
+
                default:
                        cout << "Control::type not handled: " << control.type() << endl;
        }
@@ -999,7 +998,7 @@ void MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_si
        }
 }
 
-void MackieControlProtocol::notify_active_changed( RouteSignal * route_signal )
+void MackieControlProtocol::notify_active_changed (RouteSignal *)
 {
        try
        {
@@ -1013,7 +1012,7 @@ void MackieControlProtocol::notify_active_changed( RouteSignal * route_signal )
                cout << e.what() << endl;
        }
 }
-       
+
 void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, bool force_update )
 {
        try
@@ -1045,7 +1044,7 @@ void MackieControlProtocol::notify_name_changed( RouteSignal * route_signal )
                {
                        string line1;
                        string fullname = route_signal->route()->name();
-                       
+
                        if ( fullname.length() <= 6 )
                        {
                                line1 = fullname;
@@ -1054,7 +1053,7 @@ void MackieControlProtocol::notify_name_changed( RouteSignal * route_signal )
                        {
                                line1 = PBD::short_version( fullname, 6 );
                        }
-                       
+
                        SurfacePort & port = route_signal->port();
                        port.write( builder.strip_display( port, strip, 0, line1 ) );
                        port.write( builder.strip_display_blank( port, strip, 1 ) );
@@ -1072,11 +1071,11 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, b
        {
                Pot & pot = route_signal->strip().vpot();
                boost::shared_ptr<Panner> panner = route_signal->route()->panner();
-               if ( panner && panner->npanners() == 1 || ( panner->npanners() == 2 && panner->linked() ) )
+               if ( (panner && panner->npanners() == 1) || ( panner->npanners() == 2 && panner->linked() ) )
                {
                        float pos;
                        route_signal->route()->panner()->streampanner(0).get_effective_position( pos );
-                       
+
                        // cache the MidiByteArray here, because the mackie led control is much lower
                        // resolution than the panner control. So we save lots of byte
                        // sends in spite of more work on the comparison
@@ -1107,7 +1106,7 @@ void MackieControlProtocol::update_automation( RouteSignal & rs )
        {
                notify_gain_changed( &rs, false );
        }
-       
+
        if ( rs.route()->panner() ) {
                ARDOUR::AutoState panner_state = rs.route()->panner()->automation_state();
                if ( panner_state == Touch || panner_state == Play )
@@ -1122,14 +1121,14 @@ string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
 {
        BBT_Time bbt_time;
        session->bbt_time( now_frame, bbt_time );
-       
+
        // According to the Logic docs
        // digits: 888/88/88/888
        // BBT mode: Bars/Beats/Subdivisions/Ticks
        ostringstream os;
        os << setw(3) << setfill('0') << bbt_time.bars;
        os << setw(2) << setfill('0') << bbt_time.beats;
-       
+
        // figure out subdivisions per beat
        const Meter & meter = session->tempo_map().meter_at( now_frame );
        int subdiv = 2;
@@ -1137,30 +1136,30 @@ string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
        {
                subdiv = 3;
        }
-       
+
        uint32_t subdivisions = bbt_time.ticks / uint32_t( Meter::ticks_per_beat / subdiv );
        uint32_t ticks = bbt_time.ticks % uint32_t( Meter::ticks_per_beat / subdiv );
-       
+
        os << setw(2) << setfill('0') << subdivisions + 1;
        os << setw(3) << setfill('0') << ticks;
-       
+
        return os.str();
 }
 
-string MackieControlProtocol::format_smpte_timecode( nframes_t now_frame )
+string MackieControlProtocol::format_timecode_timecode( nframes_t now_frame )
 {
-       SMPTE::Time smpte;
-       session->smpte_time( now_frame, smpte );
+       Timecode::Time timecode;
+       session->timecode_time( now_frame, timecode );
 
        // According to the Logic docs
        // digits: 888/88/88/888
-       // SMPTE mode: Hours/Minutes/Seconds/Frames
+       // Timecode mode: Hours/Minutes/Seconds/Frames
        ostringstream os;
-       os << setw(3) << setfill('0') << smpte.hours;
-       os << setw(2) << setfill('0') << smpte.minutes;
-       os << setw(2) << setfill('0') << smpte.seconds;
-       os << setw(3) << setfill('0') << smpte.frames;
-       
+       os << setw(3) << setfill('0') << timecode.hours;
+       os << setw(2) << setfill('0') << timecode.minutes;
+       os << setw(2) << setfill('0') << timecode.seconds;
+       os << setw(3) << setfill('0') << timecode.frames;
+
        return os.str();
 }
 
@@ -1171,21 +1170,21 @@ void MackieControlProtocol::update_timecode_display()
                // do assignment here so current_frame is fixed
                nframes_t current_frame = session->transport_frame();
                string timecode;
-               
+
                switch ( _timecode_type )
                {
                        case ARDOUR::AnyTime::BBT:
                                timecode = format_bbt_timecode( current_frame );
                                break;
-                       case ARDOUR::AnyTime::SMPTE:
-                               timecode = format_smpte_timecode( current_frame );
+                       case ARDOUR::AnyTime::Timecode:
+                               timecode = format_timecode_timecode( current_frame );
                                break;
                        default:
                                ostringstream os;
                                os << "Unknown timecode: " << _timecode_type;
                                throw runtime_error( os.str() );
-               }       
-               
+               }
+
                // only write the timecode string to the MCU if it's changed
                // since last time. This is to reduce midi bandwidth used.
                if ( timecode != _timecode_last )
@@ -1205,15 +1204,15 @@ void MackieControlProtocol::poll_session_data()
                {
                        update_automation( **it );
                }
-               
+
                // and the master strip
                if ( master_route_signal != 0 )
                {
                        update_automation( *master_route_signal );
                }
-               
+
                update_timecode_display();
-               
+
                _automation_last.start();
        }
 }
@@ -1222,16 +1221,16 @@ void MackieControlProtocol::poll_session_data()
 // Transport Buttons
 /////////////////////////////////////
 
-LedState MackieControlProtocol::frm_left_press( Button & button )
+LedState MackieControlProtocol::frm_left_press (Button &)
 {
        // can use first_mark_before/after as well
        unsigned long elapsed = _frm_left_last.restart();
-       
+
        Location * loc = session->locations()->first_location_before (
                session->transport_frame()
        );
-       
-       // allow a quick double to go past a previous mark 
+
+       // allow a quick double to go past a previous mark
        if ( session->transport_rolling() && elapsed < 500 && loc != 0 )
        {
                Location * loc_two_back = session->locations()->first_location_before ( loc->start() );
@@ -1240,22 +1239,22 @@ LedState MackieControlProtocol::frm_left_press( Button & button )
                        loc = loc_two_back;
                }
        }
-       
+
        // move to the location, if it's valid
        if ( loc != 0 )
        {
                session->request_locate( loc->start(), session->transport_rolling() );
        }
-       
+
        return on;
 }
 
-LedState MackieControlProtocol::frm_left_release( Button & button )
+LedState MackieControlProtocol::frm_left_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::frm_right_press( Button & button )
+LedState MackieControlProtocol::frm_right_press (Button &)
 {
        // can use first_mark_before/after as well
        Location * loc = session->locations()->first_location_after (
@@ -1265,34 +1264,34 @@ LedState MackieControlProtocol::frm_right_press( Button & button )
        return on;
 }
 
-LedState MackieControlProtocol::frm_right_release( Button & button )
+LedState MackieControlProtocol::frm_right_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::stop_press( Button & button )
+LedState MackieControlProtocol::stop_press (Button &)
 {
        session->request_stop();
        return on;
 }
 
-LedState MackieControlProtocol::stop_release( Button & button )
+LedState MackieControlProtocol::stop_release (Button &)
 {
        return session->transport_stopped();
 }
 
-LedState MackieControlProtocol::play_press( Button & button )
+LedState MackieControlProtocol::play_press (Button &)
 {
        session->request_transport_speed( 1.0 );
        return on;
 }
 
-LedState MackieControlProtocol::play_release( Button & button )
+LedState MackieControlProtocol::play_release (Button &)
 {
        return session->transport_rolling();
 }
 
-LedState MackieControlProtocol::record_press( Button & button )
+LedState MackieControlProtocol::record_press (Button &)
 {
        if ( session->get_record_enabled() )
                session->disable_record( false );
@@ -1301,7 +1300,7 @@ LedState MackieControlProtocol::record_press( Button & button )
        return on;
 }
 
-LedState MackieControlProtocol::record_release( Button & button )
+LedState MackieControlProtocol::record_release (Button &)
 {
        if ( session->get_record_enabled() )
        {
@@ -1314,7 +1313,7 @@ LedState MackieControlProtocol::record_release( Button & button )
                return off;
 }
 
-LedState MackieControlProtocol::rewind_press( Button & button )
+LedState MackieControlProtocol::rewind_press (Button &)
 {
        _jog_wheel.push( JogWheel::speed );
        _jog_wheel.transport_direction( -1 );
@@ -1322,7 +1321,7 @@ LedState MackieControlProtocol::rewind_press( Button & button )
        return on;
 }
 
-LedState MackieControlProtocol::rewind_release( Button & button )
+LedState MackieControlProtocol::rewind_release (Button &)
 {
        _jog_wheel.pop();
        _jog_wheel.transport_direction( 0 );
@@ -1333,7 +1332,7 @@ LedState MackieControlProtocol::rewind_release( Button & button )
        return off;
 }
 
-LedState MackieControlProtocol::ffwd_press( Button & button )
+LedState MackieControlProtocol::ffwd_press (Button &)
 {
        _jog_wheel.push( JogWheel::speed );
        _jog_wheel.transport_direction( 1 );
@@ -1341,7 +1340,7 @@ LedState MackieControlProtocol::ffwd_press( Button & button )
        return on;
 }
 
-LedState MackieControlProtocol::ffwd_release( Button & button )
+LedState MackieControlProtocol::ffwd_release (Button &)
 {
        _jog_wheel.pop();
        _jog_wheel.transport_direction( 0 );
@@ -1352,83 +1351,83 @@ LedState MackieControlProtocol::ffwd_release( Button & button )
        return off;
 }
 
-LedState MackieControlProtocol::loop_press( Button & button )
+LedState MackieControlProtocol::loop_press (Button &)
 {
        session->request_play_loop( !session->get_play_loop() );
        return on;
 }
 
-LedState MackieControlProtocol::loop_release( Button & button )
+LedState MackieControlProtocol::loop_release (Button &)
 {
        return session->get_play_loop();
 }
 
-LedState MackieControlProtocol::punch_in_press( Button & button )
+LedState MackieControlProtocol::punch_in_press (Button &)
 {
        bool state = !session->config.get_punch_in();
        session->config.set_punch_in( state );
        return state;
 }
 
-LedState MackieControlProtocol::punch_in_release( Button & button )
+LedState MackieControlProtocol::punch_in_release (Button &)
 {
        return session->config.get_punch_in();
 }
 
-LedState MackieControlProtocol::punch_out_press( Button & button )
+LedState MackieControlProtocol::punch_out_press (Button &)
 {
        bool state = !session->config.get_punch_out();
        session->config.set_punch_out( state );
        return state;
 }
 
-LedState MackieControlProtocol::punch_out_release( Button & button )
+LedState MackieControlProtocol::punch_out_release (Button &)
 {
        return session->config.get_punch_out();
 }
 
-LedState MackieControlProtocol::home_press( Button & button )
+LedState MackieControlProtocol::home_press (Button &)
 {
        session->goto_start();
        return on;
 }
 
-LedState MackieControlProtocol::home_release( Button & button )
+LedState MackieControlProtocol::home_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::end_press( Button & button )
+LedState MackieControlProtocol::end_press (Button &)
 {
        session->goto_end();
        return on;
 }
 
-LedState MackieControlProtocol::end_release( Button & button )
+LedState MackieControlProtocol::end_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::clicking_press( Button & button )
+LedState MackieControlProtocol::clicking_press (Button &)
 {
        bool state = !Config->get_clicking();
        Config->set_clicking( state );
        return state;
 }
 
-LedState MackieControlProtocol::clicking_release( Button & button )
+LedState MackieControlProtocol::clicking_release (Button &)
 {
        return Config->get_clicking();
 }
 
-LedState MackieControlProtocol::global_solo_press( Button & button )
+LedState MackieControlProtocol::global_solo_press (Button &)
 {
        bool state = !session->soloing();
-       session->set_all_solo ( state );
+       session->set_solo (session->get_routes(), state);
        return state;
 }
 
-LedState MackieControlProtocol::global_solo_release( Button & button )
+LedState MackieControlProtocol::global_solo_release (Button &)
 {
        return session->soloing();
 }
@@ -1469,7 +1468,7 @@ void MackieControlProtocol::notify_route_added( ARDOUR::RouteList & rl )
                refresh_current_bank();
        }
        // otherwise route added, but current bank needs no updating
-       
+
        // make sure remote id changes in the new route are handled
        typedef ARDOUR::RouteList ARS;
        for ( ARS::iterator it = rl.begin(); it != rl.end(); ++it )
@@ -1487,7 +1486,7 @@ void MackieControlProtocol::notify_solo_active_changed( bool active )
 void MackieControlProtocol::notify_remote_id_changed()
 {
        Sorted sorted = get_sorted_routes();
-       
+
        // if a remote id has been moved off the end, we need to shift
        // the current bank backwards.
        if ( sorted.size() - _current_initial_bank < route_signals.size() )
@@ -1519,9 +1518,9 @@ void MackieControlProtocol::notify_transport_state_changed()
        update_global_button( "play", session->transport_rolling() );
        update_global_button( "stop", !session->transport_rolling() );
        update_global_button( "loop", session->get_play_loop() );
-       
+
        _transport_previously_rolling = session->transport_rolling();
-       
+
        // rec is special because it's tristate
        Button * rec = reinterpret_cast<Button*>( surface().controls_by_name["record"] );
        mcu_port().write( builder.build_led( *rec, record_release( *rec ) ) );
@@ -1530,7 +1529,7 @@ void MackieControlProtocol::notify_transport_state_changed()
 /////////////////////////////////////
 // Bank Switching
 /////////////////////////////////////
-LedState MackieControlProtocol::left_press( Button & button )
+LedState MackieControlProtocol::left_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
        if ( sorted.size() > route_table.size() )
@@ -1542,7 +1541,7 @@ LedState MackieControlProtocol::left_press( Button & button )
                        session->set_dirty();
                        switch_banks( new_initial );
                }
-               
+
                return on;
        }
        else
@@ -1551,12 +1550,12 @@ LedState MackieControlProtocol::left_press( Button & button )
        }
 }
 
-LedState MackieControlProtocol::left_release( Button & button )
+LedState MackieControlProtocol::left_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::right_press( Button & button )
+LedState MackieControlProtocol::right_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
        if ( sorted.size() > route_table.size() )
@@ -1568,7 +1567,7 @@ LedState MackieControlProtocol::right_press( Button & button )
                        session->set_dirty();
                        switch_banks( _current_initial_bank + delta );
                }
-               
+
                return on;
        }
        else
@@ -1577,12 +1576,12 @@ LedState MackieControlProtocol::right_press( Button & button )
        }
 }
 
-LedState MackieControlProtocol::right_release( Button & button )
+LedState MackieControlProtocol::right_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::channel_left_press( Button & button )
+LedState MackieControlProtocol::channel_left_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
        if ( sorted.size() > route_table.size() )
@@ -1596,12 +1595,12 @@ LedState MackieControlProtocol::channel_left_press( Button & button )
        }
 }
 
-LedState MackieControlProtocol::channel_left_release( Button & button )
+LedState MackieControlProtocol::channel_left_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::channel_right_press( Button & button )
+LedState MackieControlProtocol::channel_right_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
        if ( sorted.size() > route_table.size() )
@@ -1615,7 +1614,7 @@ LedState MackieControlProtocol::channel_right_press( Button & button )
        }
 }
 
-LedState MackieControlProtocol::channel_right_release( Button & button )
+LedState MackieControlProtocol::channel_right_release (Button &)
 {
        return off;
 }
@@ -1623,7 +1622,7 @@ LedState MackieControlProtocol::channel_right_release( Button & button )
 /////////////////////////////////////
 // Functions
 /////////////////////////////////////
-LedState MackieControlProtocol::marker_press( Button & button )
+LedState MackieControlProtocol::marker_press (Button &)
 {
        // cut'n'paste from LocationUI::add_new_location()
        string markername;
@@ -1639,7 +1638,7 @@ LedState MackieControlProtocol::marker_press( Button & button )
        return on;
 }
 
-LedState MackieControlProtocol::marker_release( Button & button )
+LedState MackieControlProtocol::marker_release (Button &)
 {
        return off;
 }
@@ -1691,36 +1690,36 @@ Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & )
        ;
 }
 
-LedState MackieControlProtocol::drop_press( Button & button )
+LedState MackieControlProtocol::drop_press (Button &)
 {
        session->remove_last_capture();
        return on;
 }
 
-LedState MackieControlProtocol::drop_release( Button & button )
+LedState MackieControlProtocol::drop_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::save_press( Button & button )
+LedState MackieControlProtocol::save_press (Button &)
 {
        session->save_state( "" );
        return on;
 }
 
-LedState MackieControlProtocol::save_release( Button & button )
+LedState MackieControlProtocol::save_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::smpte_beats_press( Button & )
+LedState MackieControlProtocol::timecode_beats_press (Button &)
 {
        switch ( _timecode_type )
        {
                case ARDOUR::AnyTime::BBT:
-                       _timecode_type = ARDOUR::AnyTime::SMPTE;
+                       _timecode_type = ARDOUR::AnyTime::Timecode;
                        break;
-               case ARDOUR::AnyTime::SMPTE:
+               case ARDOUR::AnyTime::Timecode:
                        _timecode_type = ARDOUR::AnyTime::BBT;
                        break;
                default:
@@ -1728,11 +1727,11 @@ LedState MackieControlProtocol::smpte_beats_press( Button & )
                        os << "Unknown Anytime::Type " << _timecode_type;
                        throw runtime_error( os.str() );
        }
-       update_smpte_beats_led();
+       update_timecode_beats_led();
        return on;
 }
 
-LedState MackieControlProtocol::smpte_beats_release( Button & )
+LedState MackieControlProtocol::timecode_beats_release( Button & )
 {
        return off;
 }