substantial overhaul of MCU code - no more separate thread, just connect to signals...
authorPaul Davis <paul@linuxaudiosystems.com>
Sun, 20 Dec 2009 16:49:55 +0000 (16:49 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sun, 20 Dec 2009 16:49:55 +0000 (16:49 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6377 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/surfaces/mackie/controls.h
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/mackie_control_protocol_poll.cc
libs/surfaces/mackie/mackie_port.cc

index 8a7740598f2d0703dbc434a9cc4c8ea62f12b951..398d7e689aec4925ae60a3fe07b876d616eb387d 100644 (file)
@@ -228,7 +228,7 @@ public:
        virtual unsigned int in_use_timeout() { return _in_use_timeout; }
 
        /// Keep track of the timeout so it can be updated with more incoming events
-       PBD::ScopedConnection in_use_connection;
+       sigc::connection in_use_connection;
        
 private:
        int _id;
index 9698b299b9c153f6c2173a345b43199b08ca2e5c..9f4ffb10c066f2cfdb1031ecb526a5ff08a3bb17 100644 (file)
@@ -8,7 +8,7 @@
 
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
        GNU General Public License for more details.
 
        You should have received a copy of the GNU General Public License
 #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/debug.h"
+#include "ardour/location.h"
 #include "ardour/panner.h"
+#include "ardour/route.h"
+#include "ardour/session.h"
 #include "ardour/tempo.h"
 #include "ardour/types.h"
 
@@ -71,105 +72,89 @@ using boost::shared_ptr;
 MackieMidiBuilder builder;
 
 MackieControlProtocol::MackieControlProtocol (Session& session)
-       : ControlProtocol  (session, X_("Mackie"))
-       , _current_initial_bank( 0 )
-       , _surface( 0 )
-       , _ports_changed( false )
-       , _polling( true )
-       , pfd( 0 )
-       , nfds( 0 )
-       , _jog_wheel( *this )
-       , _timecode_type( ARDOUR::AnyTime::BBT )
-{
-#ifdef DEBUG
-       cout << "MackieControlProtocol::MackieControlProtocol" << endl;
-#endif
-       // will start reading from ports, as soon as there are some
-       pthread_create_and_store (X_("mackie monitor"), &thread, _monitor_work, this);
+       : ControlProtocol (session, X_("Mackie"))
+       , _current_initial_bank (0)
+       , _surface (0)
+       , _jog_wheel (*this)
+       , _timecode_type (ARDOUR::AnyTime::BBT)
+{
+       DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
 }
 
 MackieControlProtocol::~MackieControlProtocol()
 {
-#ifdef DEBUG
-       cout << "~MackieControlProtocol::MackieControlProtocol" << endl;
-#endif
-       try
-       {
+       DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol\n");
+
+       try {
                close();
        }
-       catch ( exception & e )
-       {
+       catch (exception & e) {
                cout << "~MackieControlProtocol caught " << e.what() << endl;
        }
-       catch ( ... )
-       {
+       catch (...) {
                cout << "~MackieControlProtocol caught unknown" << endl;
        }
-#ifdef DEBUG
-       cout << "finished ~MackieControlProtocol::MackieControlProtocol" << endl;
-#endif
+
+       DEBUG_TRACE (DEBUG::MackieControl, "finished ~MackieControlProtocol::MackieControlProtocol\n");
 }
 
-Mackie::Surface & MackieControlProtocol::surface()
+Mackie::Surface& 
+MackieControlProtocol::surface()
 {
-       if ( _surface == 0 )
-       {
-               throw MackieControlException( "_surface is 0 in MackieControlProtocol::surface" );
+       if (_surface == 0) {
+               throw MackieControlException ("_surface is 0 in MackieControlProtocol::surface");
        }
        return *_surface;
 }
 
-const Mackie::SurfacePort & MackieControlProtocol::mcu_port() const
+const Mackie::SurfacePort& 
+MackieControlProtocol::mcu_port() const
 {
-       if ( _ports.size() < 1 )
-       {
+       if (_ports.size() < 1) {
                return _dummy_port;
-       }
-       else
-       {
-               return dynamic_cast<const MackiePort &>( *_ports[0] );
+       } else {
+               return dynamic_cast<const MackiePort &> (*_ports[0]);
        }
 }
 
-Mackie::SurfacePort & MackieControlProtocol::mcu_port()
+Mackie::SurfacePort& 
+MackieControlProtocol::mcu_port()
 {
-       if ( _ports.size() < 1 )
-       {
+       if (_ports.size() < 1) {
                return _dummy_port;
-       }
-       else
-       {
-               return dynamic_cast<MackiePort &>( *_ports[0] );
+       } else {
+               return dynamic_cast<MackiePort &> (*_ports[0]);
        }
 }
 
 // go to the previous track.
 // Assume that get_sorted_routes().size() > route_table.size()
-void MackieControlProtocol::prev_track()
+void 
+MackieControlProtocol::prev_track()
 {
-       if ( _current_initial_bank >= 1 )
-       {
+       if (_current_initial_bank >= 1) {
                session->set_dirty();
-               switch_banks( _current_initial_bank - 1 );
+               switch_banks (_current_initial_bank - 1);
        }
 }
 
 // go to the next track.
 // Assume that get_sorted_routes().size() > route_table.size()
-void MackieControlProtocol::next_track()
+void 
+MackieControlProtocol::next_track()
 {
        Sorted sorted = get_sorted_routes();
-       if ( _current_initial_bank + route_table.size() < sorted.size() )
+       if (_current_initial_bank + route_table.size() < sorted.size())
        {
                session->set_dirty();
-               switch_banks( _current_initial_bank + 1 );
+               switch_banks (_current_initial_bank + 1);
        }
 }
 
-void MackieControlProtocol::clear_route_signals()
+void 
+MackieControlProtocol::clear_route_signals()
 {
-       for( RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it )
-       {
+       for (RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it) {
                delete *it;
        }
        route_signals.clear();
@@ -177,41 +162,42 @@ void MackieControlProtocol::clear_route_signals()
 
 // return the port for a given id - 0 based
 // throws an exception if no port found
-MackiePort & MackieControlProtocol::port_for_id( uint32_t index )
+MackiePort& 
+MackieControlProtocol::port_for_id (uint32_t index)
 {
        uint32_t current_max = 0;
-       for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
-       {
+       for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
                current_max += (*it)->strips();
-               if ( index < current_max ) return **it;
+               if (index < current_max) return **it;
        }
 
        // oops - no matching port
        ostringstream os;
        os << "No port for index " << index;
-       throw MackieControlException( os.str() );
+       throw MackieControlException (os.str());
 }
 
 // predicate for sort call in get_sorted_routes
 struct RouteByRemoteId
 {
-       bool operator () ( const shared_ptr<Route> & a, const shared_ptr<Route> & b ) const
+       bool operator () (const shared_ptr<Route> & a, const shared_ptr<Route> & b) const
        {
                return a->remote_control_id() < b->remote_control_id();
        }
 
-       bool operator () ( const Route & a, const Route & b ) const
+       bool operator () (const Route & a, const Route & b) const
        {
                return a.remote_control_id() < b.remote_control_id();
        }
 
-       bool operator () ( const Route * a, const Route * b ) const
+       bool operator () (const Route * a, const Route * b) const
        {
                return a->remote_control_id() < b->remote_control_id();
        }
 };
 
-MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes()
+MackieControlProtocol::Sorted 
+MackieControlProtocol::get_sorted_routes()
 {
        Sorted sorted;
 
@@ -221,11 +207,11 @@ MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes()
 
        // routes with remote_id 0 should never be added
        // TODO verify this with ardour devs
-       // remote_ids.insert( 0 );
+       // 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 )
+       for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it)
        {
                Route & route = **it;
                if (
@@ -233,23 +219,25 @@ MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes()
                                && !route.is_master()
                                && !route.is_hidden()
                                && !route.is_control()
-                               && remote_ids.find( route.remote_control_id() ) == remote_ids.end()
+                               && remote_ids.find (route.remote_control_id()) == remote_ids.end()
                )
                {
-                       sorted.push_back( *it );
-                       remote_ids.insert( route.remote_control_id() );
+                       sorted.push_back (*it);
+                       remote_ids.insert (route.remote_control_id());
                }
        }
-       sort( sorted.begin(), sorted.end(), RouteByRemoteId() );
+       sort (sorted.begin(), sorted.end(), RouteByRemoteId());
        return sorted;
 }
 
-void MackieControlProtocol::refresh_current_bank()
+void 
+MackieControlProtocol::refresh_current_bank()
 {
-       switch_banks( _current_initial_bank );
+       switch_banks (_current_initial_bank);
 }
 
-void MackieControlProtocol::switch_banks( int initial )
+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
@@ -257,11 +245,9 @@ void MackieControlProtocol::switch_banks( int initial )
        // sanity checking
        Sorted sorted = get_sorted_routes();
        int delta = sorted.size() - route_table.size();
-       if ( initial < 0 || ( delta > 0 && initial > delta ) )
+       if (initial < 0 || (delta > 0 && initial > delta))
        {
-#ifdef DEBUG
-               cout << "not switching to " << initial << endl;
-#endif
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
                return;
        }
        _current_initial_bank = initial;
@@ -271,108 +257,98 @@ void MackieControlProtocol::switch_banks( int initial )
        clear_route_signals();
 
        // now set the signals for new routes
-       if ( _current_initial_bank <= sorted.size() )
+       if (_current_initial_bank <= sorted.size())
        {
                // fetch the bank start and end to switch to
-               uint32_t end_pos = min( route_table.size(), sorted.size() );
+               uint32_t end_pos = min (route_table.size(), sorted.size());
                Sorted::iterator it = sorted.begin() + _current_initial_bank;
                Sorted::iterator end = sorted.begin() + _current_initial_bank + end_pos;
-#ifdef DEBUG
-               cout << "switch to " << _current_initial_bank << ", " << end_pos << endl;
-#endif
+
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to %1, %2\n", _current_initial_bank, end_pos));
 
                // link routes to strips
                uint32_t i = 0;
-               for ( ; it != end && it != sorted.end(); ++it, ++i )
+               for (; it != end && it != sorted.end(); ++it, ++i)
                {
                        boost::shared_ptr<Route> route = *it;
                        Strip & strip = *surface().strips[i];
-#ifdef DEBUG
-                       cout << "remote id " << route->remote_control_id() << " connecting " << route->name() << " to " << strip.name() << " with port " << port_for_id(i) << endl;
-#endif
+
+                       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("remote id %1 connecting %2 to %3 with port %4\n", 
+                                                                          route->remote_control_id(), route->name(), strip.name(), port_for_id(i)));
                        route_table[i] = route;
-                       RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i) );
-                       route_signals.push_back( rs );
+                       RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i));
+                       route_signals.push_back (rs);
                        // 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 )
+               for (; i < route_table.size(); ++i)
                {
                        Strip & strip = *surface().strips[i];
                        // send zero for this strip
                        MackiePort & port = port_for_id(i);
-                       port.write( builder.zero_strip( port, strip ) );
+                       port.write (builder.zero_strip (port, strip));
                }
        }
 
        // display the current start bank.
-       surface().display_bank_start( mcu_port(), builder, _current_initial_bank );
+       surface().display_bank_start (mcu_port(), builder, _current_initial_bank);
 }
 
-void MackieControlProtocol::zero_all()
+void 
+MackieControlProtocol::zero_all()
 {
        // TODO turn off Timecode displays
 
        // zero all strips
-       for ( Surface::Strips::iterator it = surface().strips.begin(); it != surface().strips.end(); ++it )
+       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 ) );
+               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() ) );
+       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.
-       for ( Surface::Controls::iterator it = surface().controls.begin(); it != surface().controls.end(); ++it )
+       for (Surface::Controls::iterator it = surface().controls.begin(); it != surface().controls.end(); ++it)
        {
                Control & control = **it;
-               if ( !control.group().is_strip() && control.accepts_feedback() )
+               if (!control.group().is_strip() && control.accepts_feedback())
                {
-                       mcu_port().write( builder.zero_control( control ) );
+                       mcu_port().write (builder.zero_control (control));
                }
        }
 
        // any hardware-specific stuff
-       surface().zero_all( mcu_port(), builder );
+       surface().zero_all (mcu_port(), builder);
 }
 
-int MackieControlProtocol::set_active( bool yn )
+int 
+MackieControlProtocol::set_active (bool yn)
 {
-       if ( yn != _active )
+       if (yn != _active)
        {
                try
                {
                        // the reason for the locking and unlocking is that
                        // glibmm can't do a condition wait on a RecMutex
-                       if ( yn )
+                       if (yn)
                        {
                                // TODO what happens if this fails half way?
 
                                // create MackiePorts
                                {
-                                       Glib::Mutex::Lock lock( update_mutex );
+                                       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 )
-                               {
+                               for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
                                        (*it)->open();
                                }
 
@@ -380,8 +356,7 @@ int MackieControlProtocol::set_active( bool yn )
                                // TODO a more sophisticated approach would
                                // allow things to start up with only an MCU, even if
                                // extenders were specified but not responding.
-                               for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
-                               {
+                               for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
                                        (*it)->wait_for_init();
                                }
 
@@ -396,18 +371,14 @@ int MackieControlProtocol::set_active( bool yn )
                                // send current control positions to surface
                                // must come after _active = true otherwise it won't run
                                update_surface();
-                       }
-                       else
-                       {
+                       } else {
                                close();
                                _active = false;
                        }
                }
-               catch( exception & e )
-               {
-#ifdef DEBUG
-                       cout << "set_active to false because exception caught: " << e.what() << endl;
-#endif
+
+               catch (exception & e) {
+                       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("set_active to false because exception caught: %1\n", e.what()));
                        _active = false;
                        throw;
                }
@@ -416,141 +387,143 @@ int MackieControlProtocol::set_active( bool yn )
        return 0;
 }
 
-bool MackieControlProtocol::handle_strip_button( Control & control, ButtonState bs, boost::shared_ptr<Route> route )
+bool 
+MackieControlProtocol::handle_strip_button (Control & control, ButtonState bs, boost::shared_ptr<Route> route)
 {
        bool state = false;
 
-       if ( bs == press )
+       if (bs == press)
        {
-               if ( control.name() == "recenable" )
+               if (control.name() == "recenable")
                {
                        state = !route->record_enabled();
-                       route->set_record_enable( state, this );
+                       route->set_record_enable (state, this);
                }
-               else if ( control.name() == "mute" )
+               else if (control.name() == "mute")
                {
                        state = !route->muted();
-                       route->set_mute( state, this );
+                       route->set_mute (state, this);
                }
-               else if ( control.name() == "solo" )
+               else if (control.name() == "solo")
                {
                        state = !route->soloed();
-                       route->set_solo( state, this );
+                       route->set_solo (state, this);
                }
-               else if ( control.name() == "select" )
+               else if (control.name() == "select")
                {
                        // TODO make the track selected. Whatever that means.
-                       //state = default_button_press( dynamic_cast<Button&>( control ) );
+                       //state = default_button_press (dynamic_cast<Button&> (control));
                }
-               else if ( control.name() == "vselect" )
+               else if (control.name() == "vselect")
                {
                        // TODO could be used to select different things to apply the pot to?
-                       //state = default_button_press( dynamic_cast<Button&>( control ) );
+                       //state = default_button_press (dynamic_cast<Button&> (control));
                }
        }
 
-       if ( control.name() == "fader_touch" )
+       if (control.name() == "fader_touch")
        {
                state = bs == press;
-               control.strip().gain().in_use( state );
+               control.strip().gain().in_use (state);
        }
 
        return state;
 }
 
-void MackieControlProtocol::update_led( Mackie::Button & button, Mackie::LedState ls )
+void 
+MackieControlProtocol::update_led (Mackie::Button & button, Mackie::LedState ls)
 {
-       if ( ls != none )
+       if (ls != none)
        {
                SurfacePort * port = 0;
-               if ( button.group().is_strip() )
+               if (button.group().is_strip())
                {
-                       if ( button.group().is_master() )
+                       if (button.group().is_master())
                        {
                                port = &mcu_port();
                        }
                        else
                        {
-                               port = &port_for_id( dynamic_cast<const Strip&>( button.group() ).index() );
+                               port = &port_for_id (dynamic_cast<const Strip&> (button.group()).index());
                        }
                }
                else
                {
                        port = &mcu_port();
                }
-               port->write( builder.build_led( button, ls ) );
+               port->write (builder.build_led (button, ls));
        }
 }
 
-void MackieControlProtocol::update_timecode_beats_led()
+void 
+MackieControlProtocol::update_timecode_beats_led()
 {
-       switch ( _timecode_type )
+       switch (_timecode_type)
        {
                case ARDOUR::AnyTime::BBT:
-                       update_global_led( "beats", on );
-                       update_global_led( "timecode", off );
+                       update_global_led ("beats", on);
+                       update_global_led ("timecode", off);
                        break;
                case ARDOUR::AnyTime::Timecode:
-                       update_global_led( "timecode", on );
-                       update_global_led( "beats", off );
+                       update_global_led ("timecode", on);
+                       update_global_led ("beats", off);
                        break;
                default:
                        ostringstream os;
                        os << "Unknown Anytime::Type " << _timecode_type;
-                       throw runtime_error( os.str() );
+                       throw runtime_error (os.str());
        }
 }
 
-void MackieControlProtocol::update_global_button( const string & name, LedState ls )
+void 
+MackieControlProtocol::update_global_button (const string & name, LedState ls)
 {
-       if ( surface().controls_by_name.find( name ) != surface().controls_by_name.end() )
+       if (surface().controls_by_name.find (name) != surface().controls_by_name.end())
        {
-               Button * button = dynamic_cast<Button*>( surface().controls_by_name[name] );
-               mcu_port().write( builder.build_led( button->led(), ls ) );
+               Button * button = dynamic_cast<Button*> (surface().controls_by_name[name]);
+               mcu_port().write (builder.build_led (button->led(), ls));
        }
        else
        {
-#ifdef DEBUG
-               cout << "Button " << name << " not found" << endl;
-#endif
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Button %1 not found\n", name));
        }
 }
 
-void MackieControlProtocol::update_global_led( const string & name, LedState ls )
+void 
+MackieControlProtocol::update_global_led (const string & name, LedState ls)
 {
-       if ( surface().controls_by_name.find( name ) != surface().controls_by_name.end() )
+       if (surface().controls_by_name.find (name) != surface().controls_by_name.end())
        {
-               Led * led = dynamic_cast<Led*>( surface().controls_by_name[name] );
-               mcu_port().write( builder.build_led( *led, ls ) );
+               Led * led = dynamic_cast<Led*> (surface().controls_by_name[name]);
+               mcu_port().write (builder.build_led (*led, ls));
        }
        else
        {
-#ifdef DEBUG
-               cout << "Led " << name << " not found" << endl;
-#endif
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Led %1 not found\n", name));
        }
 }
 
 // send messages to surface to set controls to correct values
-void MackieControlProtocol::update_surface()
+void 
+MackieControlProtocol::update_surface()
 {
-       if ( _active )
+       if (_active)
        {
                // do the initial bank switch to connect signals
                // _current_initial_bank is initialised by set_state
-               switch_banks( _current_initial_bank );
+               switch_banks (_current_initial_bank);
 
                // create a RouteSignal for the master route
 
              boost::shared_ptr<Route> mr = master_route ();
              if (mr) {
                      master_route_signal = shared_ptr<RouteSignal> (new RouteSignal (mr, *this, master_strip(), mcu_port()) );
                      // update strip from route
                      master_route_signal->notify_all();
              }
+ boost::shared_ptr<Route> mr = master_route ();
+ if (mr) {
master_route_signal = shared_ptr<RouteSignal> (new RouteSignal (mr, *this, master_strip(), mcu_port()));
+ // update strip from route
+ master_route_signal->notify_all();
+ }
 
                // sometimes the jog wheel is a pot
-               surface().blank_jog_ring( mcu_port(), builder );
+               surface().blank_jog_ring (mcu_port(), builder);
 
                // update global buttons and displays
                notify_record_state_changed();
@@ -559,7 +532,8 @@ void MackieControlProtocol::update_surface()
        }
 }
 
-void MackieControlProtocol::connect_session_signals()
+void 
+MackieControlProtocol::connect_session_signals()
 {
        // receive routes added
        session->RouteAdded.connect(session_connections, boost::bind (&MackieControlProtocol::notify_route_added, this, _1));
@@ -576,230 +550,202 @@ void MackieControlProtocol::connect_session_signals()
        // make sure remote id changed signals reach here
        // see also notify_route_added
        Sorted sorted = get_sorted_routes();
-       for ( Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it )
-       {
+
+       for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
                ((*it)->RemoteControlIDChanged.connect (route_connections, boost::bind(&MackieControlProtocol::notify_remote_id_changed, this)));
        }
 }
 
-void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
+void 
+MackieControlProtocol::add_port (MIDI::Port & midi_port, int number)
 {
-#ifdef DEBUG
-       cout << "add port " << midi_port.name() << ", " << midi_port.device() << ", " << midi_port.type() << endl;
-       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" ) && midi_port.type() == MIDI::Port::ALSA_Sequencer )
-       {
-               throw MackieControlException( "The Mackie MCU driver will not use a port with device=ardour" );
-       }
-       else if ( midi_port.type() == MIDI::Port::ALSA_Sequencer )
-       {
-               throw MackieControlException( "alsa/sequencer ports don't work with the Mackie MCU driver right now" );
-       }
-       else
-       {
-               MackiePort * sport = new MackiePort( *this, midi_port, number );
-               _ports.push_back( sport );
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("add port %1,%2,%3\n", midi_port.name(), midi_port.device(), midi_port.type()));
+
+       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");
+       } else if (midi_port.type() == MIDI::Port::ALSA_Sequencer) {
+               throw MackieControlException ("alsa/sequencer ports don't work with the Mackie MCU driver right now");
+       } else {
+               MackiePort * sport = new MackiePort (*this, midi_port, number);
+               _ports.push_back (sport);
                
                sport->init_event.connect (port_connections, boost::bind (&MackieControlProtocol::handle_port_init, this, sport));
                sport->active_event.connect (port_connections, boost::bind (&MackieControlProtocol::handle_port_active, this, sport));
                sport->inactive_event.connect (port_connections, boost::bind (&MackieControlProtocol::handle_port_inactive, this, sport));
-               
-               _ports_changed = true;
        }
 }
 
-void MackieControlProtocol::create_ports()
+void 
+MackieControlProtocol::create_ports()
 {
        MIDI::Manager * mm = MIDI::Manager::instance();
+       MIDI::Port * midi_port = mm->port (default_port_name);
 
-       // open main port
-       {
-               MIDI::Port * midi_port = mm->port( default_port_name );
+       // open main port               
 
-               if ( midi_port == 0 ) {
-                       ostringstream os;
-                       os << string_compose( _("no MIDI port named \"%1\" exists - Mackie control disabled"), default_port_name );
-                       error << os.str() << endmsg;
-                       throw MackieControlException( os.str() );
-               }
-               add_port( *midi_port, 0 );
+       if (midi_port == 0) {
+               ostringstream os;
+               os << string_compose (_("no MIDI port named \"%1\" exists - Mackie control disabled"), default_port_name);
+               error << os.str() << endmsg;
+               throw MackieControlException (os.str());
        }
 
+       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_";
-       for ( int index = 1; index <= 9; ++index )
-       {
+
+       for (int index = 1; index <= 9; ++index) {
                ostringstream os;
                os << ext_port_base << index;
-               MIDI::Port * midi_port = mm->port( os.str() );
-               if ( midi_port != 0 ) add_port( *midi_port, index );
+               MIDI::Port * midi_port = mm->port (os.str());
+               if (midi_port != 0) {
+                       add_port (*midi_port, index);
+               }
        }
 }
 
-shared_ptr<Route> MackieControlProtocol::master_route()
+shared_ptr<Route> 
+MackieControlProtocol::master_route()
 {
        return session->master_out ();
 }
 
-Strip & MackieControlProtocol::master_strip()
+Strip& 
+MackieControlProtocol::master_strip()
 {
-       return dynamic_cast<Strip&>( *surface().groups["master"] );
+       return dynamic_cast<Strip&> (*surface().groups["master"]);
 }
 
-void MackieControlProtocol::initialize_surface()
+void 
+MackieControlProtocol::initialize_surface()
 {
        // set up the route table
        int strips = 0;
-       for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
-       {
+       for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
                strips += (*it)->strips();
        }
 
-       set_route_table_size( strips );
+       set_route_table_size (strips);
 
        // TODO same as code in mackie_port.cc
        string emulation = ARDOUR::Config->get_mackie_emulation();
-       if ( emulation == "bcf" )
+       if (emulation == "bcf")
        {
-               _surface = new BcfSurface( strips );
+               _surface = new BcfSurface (strips);
        }
-       else if ( emulation == "mcu" )
+       else if (emulation == "mcu")
        {
-               _surface = new MackieSurface( strips );
+               _surface = new MackieSurface (strips);
        }
        else
        {
                ostringstream os;
                os << "no Surface class found for emulation: " << emulation;
-               throw MackieControlException( os.str() );
+               throw MackieControlException (os.str());
        }
 
        _surface->init();
 
        // Connect events. Must be after route table otherwise there will be trouble
 
-       for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it ) {
+       for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
                (*it)->control_event.connect (port_connections, boost::bind (&MackieControlProtocol::handle_control_event, this, _1, _2, _3));
        }
 }
 
-void MackieControlProtocol::close()
+void 
+MackieControlProtocol::close()
 {
-       // stop polling, and wait for it...
+
        // must be before other shutdown otherwise polling loop
        // calls methods on objects that are deleted
-       _polling = false;
-       pthread_join( thread, 0 );
 
        port_connections.drop_connections ();
        session_connections.drop_connections ();
        route_connections.drop_connections ();
 
-       if ( _surface != 0 )
-       {
+       if (_surface != 0) {
                // These will fail if the port has gone away.
                // So catch the exception and do the rest of the
                // close afterwards
                // because the bcf doesn't respond to the next 3 sysex messages
-               try
-               {
+               try {
                        zero_all();
                }
-               catch ( exception & e )
-               {
-#ifdef DEBUG
-                       cout << "MackieControlProtocol::close caught exception: " << e.what() << endl;
-#endif
+
+               catch (exception & e) {
+                       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::close caught exception: %1\n", e.what()));
                }
 
-               for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
-               {
-                       try
-                       {
+               for (MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it) {
+                       try {
                                MackiePort & port = **it;
                                // faders to minimum
-                               port.write_sysex( 0x61 );
+                               port.write_sysex (0x61);
                                // All LEDs off
-                               port.write_sysex( 0x62 );
+                               port.write_sysex (0x62);
                                // Reset (reboot into offline mode)
-                               port.write_sysex( 0x63 );
+                               port.write_sysex (0x63);
                        }
-                       catch ( exception & e )
-                       {
-#ifdef DEBUG
-                               cout << "MackieControlProtocol::close caught exception: " << e.what() << endl;
-#endif
+                       catch (exception & e) {
+                               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::close caught exception: %1\n", e.what()));
                        }
                }
 
                // disconnect routes from strips
                clear_route_signals();
-
                delete _surface;
                _surface = 0;
        }
 
        // shut down MackiePorts
-       for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
-       {
+       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;
-       nfds = 0;
-}
 
-void* MackieControlProtocol::_monitor_work (void* arg)
-{
-       return static_cast<MackieControlProtocol*>(arg)->monitor_work ();
+       _ports.clear();
 }
 
-XMLNode & MackieControlProtocol::get_state()
+XMLNode& 
+MackieControlProtocol::get_state()
 {
-#ifdef DEBUG
-       cout << "MackieControlProtocol::get_state" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state\n");
 
        // add name of protocol
-       XMLNode* node = new XMLNode( X_("Protocol") );
-       node->add_property( X_("name"), _name );
+       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() );
+       node->add_property (X_("bank"), os.str());
 
        return *node;
 }
 
-int MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
+int 
+MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
 {
-#ifdef DEBUG
-       cout << "MackieControlProtocol::set_state: active " << _active << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", _active));
+
        int retval = 0;
 
        // fetch current bank
-       if ( node.property( X_("bank") ) != 0 )
-       {
-               string bank = node.property( X_("bank") )->value();
-               try
-               {
-                       set_active( true );
-                       uint32_t new_bank = atoi( bank.c_str() );
-                       if ( _current_initial_bank != new_bank ) switch_banks( new_bank );
+
+       if (node.property (X_("bank")) != 0) {
+               string bank = node.property (X_("bank"))->value();
+               try {
+                       set_active (true);
+                       uint32_t new_bank = atoi (bank.c_str());
+                       if (_current_initial_bank != new_bank) {
+                               switch_banks (new_bank);
+                       }
                }
-               catch ( exception & e )
-               {
-#ifdef DEBUG
-                       cout << "exception in MackieControlProtocol::set_state: " << e.what() << endl;
-#endif
+               catch (exception & e) {
+                       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("exception in MackieControlProtocol::set_state: %1\n", e.what()));
                        return -1;
                }
        }
@@ -807,20 +753,17 @@ int MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
        return retval;
 }
 
-void MackieControlProtocol::handle_control_event( SurfacePort & port, Control & control, const ControlState & state )
+void 
+MackieControlProtocol::handle_control_event (SurfacePort & port, Control & control, const ControlState & state)
 {
        // find the route for the control, if there is one
        boost::shared_ptr<Route> route;
-       if ( control.group().is_strip() )
-       {
-               if ( control.group().is_master() )
-               {
+       if (control.group().is_strip()) {
+               if (control.group().is_master()) {
                        route = master_route();
-               }
-               else
-               {
-                       uint32_t index = control.ordinal() - 1 + ( port.number() * port.strips() );
-                       if ( index < route_table.size() )
+               } else {
+                       uint32_t index = control.ordinal() - 1 + (port.number() * port.strips());
+                       if (index < route_table.size())
                                route = route_table[index];
                        else
                                cerr << "Warning: index is " << index << " which is not in the route table, size: " << route_table.size() << endl;
@@ -830,61 +773,50 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
        // This handles control element events from the surface
        // the state of the controls on the surface is usually updated
        // from UI events.
-       switch ( control.type() )
-       {
+       switch (control.type()) {
                case Control::type_fader:
                        // find the route in the route table for the id
                        // if the route isn't available, skip it
                        // at which point the fader should just reset itself
-                       if ( route != 0 )
+                       if (route != 0)
                        {
-                               route->gain_control()->set_value( state.pos );
+                               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 ) );
+                               port.write (builder.build_fader ((Fader&)control, state.pos));
                        }
                        break;
 
                case Control::type_button:
-                       if ( control.group().is_strip() )
-                       {
+                       if (control.group().is_strip()) {
                                // strips
-                               if ( route != 0 )
-                               {
-                                       handle_strip_button( control, state.button_state, route );
-                               }
-                               else
-                               {
+                               if (route != 0) {
+                                       handle_strip_button (control, state.button_state, route);
+                               } else {
                                        // no route so always switch the light off
                                        // because no signals will be emitted by a non-route
-                                       port.write( builder.build_led( control.led(), off ) );
+                                       port.write (builder.build_led (control.led(), off));
                                }
-                       }
-                       else if ( control.group().is_master() )
-                       {
+                       } else if (control.group().is_master()) {
                                // master fader touch
-                               if ( route != 0 )
-                               {
-                                       handle_strip_button( control, state.button_state, route );
+                               if (route != 0) {
+                                       handle_strip_button (control, state.button_state, route);
                                }
-                       }
-                       else
-                       {
+                       } else {
                                // handle all non-strip buttons
-                               surface().handle_button( *this, state.button_state, dynamic_cast<Button&>( 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() )
-                       {
-                               if ( route != 0 && route->panner() )
+                       if (control.group().is_strip()) {
+                               if (route != 0 && route->panner())
                                {
                                        // pan for mono input routes, or stereo linked panners
-                                       if ( route->panner()->npanners() == 1 || ( route->panner()->npanners() == 2 && route->panner()->linked() ) )
+                                       if (route->panner()->npanners() == 1 || (route->panner()->npanners() == 2 && route->panner()->linked()))
                                        {
                                                // assume pan for now
                                                float xpos;
@@ -892,25 +824,25 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
 
                                                // calculate new value, and trim
                                                xpos += state.delta * state.sign;
-                                               if ( xpos > 1.0 )
+                                               if (xpos > 1.0)
                                                        xpos = 1.0;
-                                               else if ( xpos < 0.0 )
+                                               else if (xpos < 0.0)
                                                        xpos = 0.0;
 
-                                               route->panner()->streampanner (0).set_position( xpos );
+                                               route->panner()->streampanner (0).set_position (xpos);
                                        }
                                }
                                else
                                {
                                        // it's a pot for an umnapped route, so turn all the lights off
-                                       port.write( builder.build_led_ring( dynamic_cast<Pot &>( control ), off ) );
+                                       port.write (builder.build_led_ring (dynamic_cast<Pot &> (control), off));
                                }
                        }
                        else
                        {
-                               if ( control.is_jog() )
+                               if (control.is_jog())
                                {
-                                       _jog_wheel.jog_event( port, control, state );
+                                       _jog_wheel.jog_event (port, control, state);
                                }
                                else
                                {
@@ -927,44 +859,47 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
 /////////////////////////////////////////////////
 // handlers for Route signals
 // TODO should these be part of RouteSignal?
-// They started off as sigc handlers for signals
+// They started off as signal/slot handlers for signals
 // from Route, but they're also used in polling for automation
 /////////////////////////////////////////////////
 
-void MackieControlProtocol::notify_solo_changed( RouteSignal * route_signal )
+void 
+MackieControlProtocol::notify_solo_changed (RouteSignal * route_signal)
 {
        try
        {
                Button & button = route_signal->strip().solo();
-               route_signal->port().write( builder.build_led( button, route_signal->route()->soloed() ) );
+               route_signal->port().write (builder.build_led (button, route_signal->route()->soloed()));
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
 }
 
-void MackieControlProtocol::notify_mute_changed( RouteSignal * route_signal )
+void 
+MackieControlProtocol::notify_mute_changed (RouteSignal * route_signal)
 {
        try
        {
                Button & button = route_signal->strip().mute();
-               route_signal->port().write( builder.build_led( button, route_signal->route()->muted() ) );
+               route_signal->port().write (builder.build_led (button, route_signal->route()->muted()));
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
 }
 
-void MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_signal )
+void 
+MackieControlProtocol::notify_record_enable_changed (RouteSignal * route_signal)
 {
        try
        {
                Button & button = route_signal->strip().recenable();
-               route_signal->port().write( builder.build_led( button, route_signal->route()->record_enabled() ) );
+               route_signal->port().write (builder.build_led (button, route_signal->route()->record_enabled()));
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
@@ -974,125 +909,128 @@ void MackieControlProtocol::notify_active_changed (RouteSignal *)
 {
        try
        {
-#ifdef DEBUG
-               cout << "MackieControlProtocol::notify_active_changed" << endl;
-#endif
+               DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::notify_active_changed\n");
                refresh_current_bank();
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
 }
 
-void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, bool force_update )
+void 
+MackieControlProtocol::notify_gain_changed (RouteSignal * route_signal, bool force_update)
 {
        try
        {
                Fader & fader = route_signal->strip().gain();
-               if ( !fader.in_use() )
+               if (!fader.in_use())
                {
                        float gain_value = route_signal->route()->gain_control()->get_value();
                        // check that something has actually changed
-                       if ( force_update || gain_value != route_signal->last_gain_written() )
+                       if (force_update || gain_value != route_signal->last_gain_written())
                        {
-                               route_signal->port().write( builder.build_fader( fader, gain_value ) );
-                               route_signal->last_gain_written( gain_value );
+                               route_signal->port().write (builder.build_fader (fader, gain_value));
+                               route_signal->last_gain_written (gain_value);
                        }
                }
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
 }
 
-void MackieControlProtocol::notify_name_changed( RouteSignal * route_signal )
+void 
+MackieControlProtocol::notify_name_changed (RouteSignal * route_signal)
 {
        try
        {
                Strip & strip = route_signal->strip();
-               if ( !strip.is_master() )
+               if (!strip.is_master())
                {
                        string line1;
                        string fullname = route_signal->route()->name();
 
-                       if ( fullname.length() <= 6 )
+                       if (fullname.length() <= 6)
                        {
                                line1 = fullname;
                        }
                        else
                        {
-                               line1 = PBD::short_version( fullname, 6 );
+                               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 ) );
+                       port.write (builder.strip_display (port, strip, 0, line1));
+                       port.write (builder.strip_display_blank (port, strip, 1));
                }
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
 }
 
-void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, bool force_update )
+void 
+MackieControlProtocol::notify_panner_changed (RouteSignal * route_signal, bool force_update)
 {
        try
        {
                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 );
+                       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
-                       MidiByteArray bytes = builder.build_led_ring( pot, ControlState( on, pos ), MackieMidiBuilder::midi_pot_mode_dot );
+                       MidiByteArray bytes = builder.build_led_ring (pot, ControlState (on, pos), MackieMidiBuilder::midi_pot_mode_dot);
                        // check that something has actually changed
-                       if ( force_update || bytes != route_signal->last_pan_written() )
+                       if (force_update || bytes != route_signal->last_pan_written())
                        {
-                               route_signal->port().write( bytes );
-                               route_signal->last_pan_written( bytes );
+                               route_signal->port().write (bytes);
+                               route_signal->last_pan_written (bytes);
                        }
                }
                else
                {
-                       route_signal->port().write( builder.zero_control( pot ) );
+                       route_signal->port().write (builder.zero_control (pot));
                }
        }
-       catch( exception & e )
+       catch (exception & e)
        {
                cout << e.what() << endl;
        }
 }
 
 // TODO handle plugin automation polling
-void MackieControlProtocol::update_automation( RouteSignal & rs )
+void 
+MackieControlProtocol::update_automation (RouteSignal & rs)
 {
        ARDOUR::AutoState gain_state = rs.route()->gain_control()->automation_state();
-       if ( gain_state == Touch || gain_state == Play )
+
+       if (gain_state == Touch || gain_state == Play)
        {
-               notify_gain_changed( &rs, false );
+               notify_gain_changed (&rs, false);
        }
 
-       if ( rs.route()->panner() ) {
+       if (rs.route()->panner()) {
                ARDOUR::AutoState panner_state = rs.route()->panner()->automation_state();
-               if ( panner_state == Touch || panner_state == Play )
+               if (panner_state == Touch || panner_state == Play)
                {
-                       notify_panner_changed( &rs, false );
+                       notify_panner_changed (&rs, false);
                }
        }
-       _automation_last.start();
 }
 
-string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
+string 
+MackieControlProtocol::format_bbt_timecode (nframes_t now_frame)
 {
        BBT_Time bbt_time;
-       session->bbt_time( now_frame, bbt_time );
+       session->bbt_time (now_frame, bbt_time);
 
        // According to the Logic docs
        // digits: 888/88/88/888
@@ -1102,15 +1040,15 @@ string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
        os << setw(2) << setfill('0') << bbt_time.beats;
 
        // figure out subdivisions per beat
-       const Meter & meter = session->tempo_map().meter_at( now_frame );
+       const Meter & meter = session->tempo_map().meter_at (now_frame);
        int subdiv = 2;
-       if ( meter.note_divisor() == 8 && (meter.beats_per_bar() == 12.0 || meter.beats_per_bar() == 9.0 || meter.beats_per_bar() == 6.0) )
+       if (meter.note_divisor() == 8 && (meter.beats_per_bar() == 12.0 || meter.beats_per_bar() == 9.0 || meter.beats_per_bar() == 6.0))
        {
                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 );
+       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;
@@ -1118,10 +1056,11 @@ string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
        return os.str();
 }
 
-string MackieControlProtocol::format_timecode_timecode( nframes_t now_frame )
+string 
+MackieControlProtocol::format_timecode_timecode (nframes_t now_frame)
 {
        Timecode::Time timecode;
-       session->timecode_time( now_frame, timecode );
+       session->timecode_time (now_frame, timecode);
 
        // According to the Logic docs
        // digits: 888/88/88/888
@@ -1135,57 +1074,56 @@ string MackieControlProtocol::format_timecode_timecode( nframes_t now_frame )
        return os.str();
 }
 
-void MackieControlProtocol::update_timecode_display()
+void 
+MackieControlProtocol::update_timecode_display()
 {
-       if ( surface().has_timecode_display() )
+       if (surface().has_timecode_display())
        {
                // do assignment here so current_frame is fixed
                nframes_t current_frame = session->transport_frame();
                string timecode;
 
-               switch ( _timecode_type )
+               switch (_timecode_type)
                {
                        case ARDOUR::AnyTime::BBT:
-                               timecode = format_bbt_timecode( current_frame );
+                               timecode = format_bbt_timecode (current_frame);
                                break;
                        case ARDOUR::AnyTime::Timecode:
-                               timecode = format_timecode_timecode( current_frame );
+                               timecode = format_timecode_timecode (current_frame);
                                break;
                        default:
                                ostringstream os;
                                os << "Unknown timecode: " << _timecode_type;
-                               throw runtime_error( os.str() );
+                               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 )
+               if (timecode != _timecode_last)
                {
-                       surface().display_timecode( mcu_port(), builder, timecode, _timecode_last );
+                       surface().display_timecode (mcu_port(), builder, timecode, _timecode_last);
                        _timecode_last = timecode;
                }
        }
 }
 
-void MackieControlProtocol::poll_session_data()
+void 
+MackieControlProtocol::poll_session_data()
 {
-       if ( _active && _automation_last.elapsed() >= 20 )
-       {
+       // XXX need to attach this to a timer in the MIDI UI event loop (20msec)
+
+       if (_active) {
                // do all currently mapped routes
-               for( RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it )
-               {
-                       update_automation( **it );
+               for (RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it) {
+                       update_automation (**it);
                }
 
                // and the master strip
-               if ( master_route_signal != 0 )
-               {
-                       update_automation( *master_route_signal );
+               if (master_route_signal != 0) {
+                       update_automation (*master_route_signal);
                }
 
                update_timecode_display();
-
-               _automation_last.start();
        }
 }
 
@@ -1193,7 +1131,8 @@ void MackieControlProtocol::poll_session_data()
 // Transport Buttons
 /////////////////////////////////////
 
-LedState MackieControlProtocol::frm_left_press (Button &)
+LedState 
+MackieControlProtocol::frm_left_press (Button &)
 {
        // can use first_mark_before/after as well
        unsigned long elapsed = _frm_left_last.restart();
@@ -1203,191 +1142,217 @@ LedState MackieControlProtocol::frm_left_press (Button &)
        );
 
        // allow a quick double to go past a previous mark
-       if ( session->transport_rolling() && elapsed < 500 && loc != 0 )
+       if (session->transport_rolling() && elapsed < 500 && loc != 0)
        {
-               Location * loc_two_back = session->locations()->first_location_before ( loc->start() );
-               if ( loc_two_back != 0 )
+               Location * loc_two_back = session->locations()->first_location_before (loc->start());
+               if (loc_two_back != 0)
                {
                        loc = loc_two_back;
                }
        }
 
        // move to the location, if it's valid
-       if ( loc != 0 )
+       if (loc != 0)
        {
-               session->request_locate( loc->start(), session->transport_rolling() );
+               session->request_locate (loc->start(), session->transport_rolling());
        }
 
        return on;
 }
 
-LedState MackieControlProtocol::frm_left_release (Button &)
+LedState 
+MackieControlProtocol::frm_left_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::frm_right_press (Button &)
+LedState 
+MackieControlProtocol::frm_right_press (Button &)
 {
        // can use first_mark_before/after as well
        Location * loc = session->locations()->first_location_after (
                session->transport_frame()
        );
-       if ( loc != 0 ) session->request_locate( loc->start(), session->transport_rolling() );
+       if (loc != 0) session->request_locate (loc->start(), session->transport_rolling());
        return on;
 }
 
-LedState MackieControlProtocol::frm_right_release (Button &)
+LedState 
+MackieControlProtocol::frm_right_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::stop_press (Button &)
+LedState 
+MackieControlProtocol::stop_press (Button &)
 {
        session->request_stop();
        return on;
 }
 
-LedState MackieControlProtocol::stop_release (Button &)
+LedState 
+MackieControlProtocol::stop_release (Button &)
 {
        return session->transport_stopped();
 }
 
-LedState MackieControlProtocol::play_press (Button &)
+LedState 
+MackieControlProtocol::play_press (Button &)
 {
-       session->request_transport_speed( 1.0 );
+       session->request_transport_speed (1.0);
        return on;
 }
 
-LedState MackieControlProtocol::play_release (Button &)
+LedState 
+MackieControlProtocol::play_release (Button &)
 {
        return session->transport_rolling();
 }
 
-LedState MackieControlProtocol::record_press (Button &)
+LedState 
+MackieControlProtocol::record_press (Button &)
 {
-       if ( session->get_record_enabled() )
-               session->disable_record( false );
-       else
+       if (session->get_record_enabled()) {
+               session->disable_record (false);
+       } else {
                session->maybe_enable_record();
+       }
        return on;
 }
 
-LedState MackieControlProtocol::record_release (Button &)
+LedState 
+MackieControlProtocol::record_release (Button &)
 {
-       if ( session->get_record_enabled() )
-       {
-               if ( session->transport_rolling() )
+       if (session->get_record_enabled()) {
+               if (session->transport_rolling()) {
                        return on;
-               else
+               } else {
                        return flashing;
-       }
-       else
+               }
+       } else {
                return off;
+       }
 }
 
-LedState MackieControlProtocol::rewind_press (Button &)
+LedState 
+MackieControlProtocol::rewind_press (Button &)
 {
-       _jog_wheel.push( JogWheel::speed );
-       _jog_wheel.transport_direction( -1 );
-       session->request_transport_speed( -_jog_wheel.transport_speed() );
+       _jog_wheel.push (JogWheel::speed);
+       _jog_wheel.transport_direction (-1);
+       session->request_transport_speed (-_jog_wheel.transport_speed());
        return on;
 }
 
-LedState MackieControlProtocol::rewind_release (Button &)
+LedState 
+MackieControlProtocol::rewind_release (Button &)
 {
        _jog_wheel.pop();
-       _jog_wheel.transport_direction( 0 );
-       if ( _transport_previously_rolling )
-               session->request_transport_speed( 1.0 );
+       _jog_wheel.transport_direction (0);
+       if (_transport_previously_rolling)
+               session->request_transport_speed (1.0);
        else
                session->request_stop();
        return off;
 }
 
-LedState MackieControlProtocol::ffwd_press (Button &)
+LedState 
+MackieControlProtocol::ffwd_press (Button &)
 {
-       _jog_wheel.push( JogWheel::speed );
-       _jog_wheel.transport_direction( 1 );
-       session->request_transport_speed( _jog_wheel.transport_speed() );
+       _jog_wheel.push (JogWheel::speed);
+       _jog_wheel.transport_direction (1);
+       session->request_transport_speed (_jog_wheel.transport_speed());
        return on;
 }
 
-LedState MackieControlProtocol::ffwd_release (Button &)
+LedState 
+MackieControlProtocol::ffwd_release (Button &)
 {
        _jog_wheel.pop();
-       _jog_wheel.transport_direction( 0 );
-       if ( _transport_previously_rolling )
-               session->request_transport_speed( 1.0 );
+       _jog_wheel.transport_direction (0);
+       if (_transport_previously_rolling)
+               session->request_transport_speed (1.0);
        else
                session->request_stop();
        return off;
 }
 
-LedState MackieControlProtocol::loop_press (Button &)
+LedState 
+MackieControlProtocol::loop_press (Button &)
 {
-       session->request_play_loop( !session->get_play_loop() );
+       session->request_play_loop (!session->get_play_loop());
        return on;
 }
 
-LedState MackieControlProtocol::loop_release (Button &)
+LedState 
+MackieControlProtocol::loop_release (Button &)
 {
        return session->get_play_loop();
 }
 
-LedState MackieControlProtocol::punch_in_press (Button &)
+LedState 
+MackieControlProtocol::punch_in_press (Button &)
 {
        bool state = !session->config.get_punch_in();
-       session->config.set_punch_in( state );
+       session->config.set_punch_in (state);
        return state;
 }
 
-LedState MackieControlProtocol::punch_in_release (Button &)
+LedState 
+MackieControlProtocol::punch_in_release (Button &)
 {
        return session->config.get_punch_in();
 }
 
-LedState MackieControlProtocol::punch_out_press (Button &)
+LedState 
+MackieControlProtocol::punch_out_press (Button &)
 {
        bool state = !session->config.get_punch_out();
-       session->config.set_punch_out( state );
+       session->config.set_punch_out (state);
        return state;
 }
 
-LedState MackieControlProtocol::punch_out_release (Button &)
+LedState 
+MackieControlProtocol::punch_out_release (Button &)
 {
        return session->config.get_punch_out();
 }
 
-LedState MackieControlProtocol::home_press (Button &)
+LedState 
+MackieControlProtocol::home_press (Button &)
 {
        session->goto_start();
        return on;
 }
 
-LedState MackieControlProtocol::home_release (Button &)
+LedState 
+MackieControlProtocol::home_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::end_press (Button &)
+LedState 
+MackieControlProtocol::end_press (Button &)
 {
        session->goto_end();
        return on;
 }
 
-LedState MackieControlProtocol::end_release (Button &)
+LedState 
+MackieControlProtocol::end_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::clicking_press (Button &)
+LedState 
+MackieControlProtocol::clicking_press (Button &)
 {
        bool state = !Config->get_clicking();
-       Config->set_clicking( state );
+       Config->set_clicking (state);
        return state;
 }
 
-LedState MackieControlProtocol::clicking_release (Button &)
+LedState 
+MackieControlProtocol::clicking_release (Button &)
 {
        return Config->get_clicking();
 }
@@ -1410,32 +1375,31 @@ LedState MackieControlProtocol::global_solo_release (Button &)
 
 void MackieControlProtocol::notify_parameter_changed (std::string const & p)
 {
-       if ( p == "punch-in" )
+       if (p == "punch-in")
        {
-               update_global_button( "punch_in", session->config.get_punch_in() );
+               update_global_button ("punch_in", session->config.get_punch_in());
        }
-       else if ( p == "punch-out" )
+       else if (p == "punch-out")
        {
-               update_global_button( "punch_out", session->config.get_punch_out() );
+               update_global_button ("punch_out", session->config.get_punch_out());
        }
-       else if ( p == "clicking" )
+       else if (p == "clicking")
        {
-               update_global_button( "clicking", Config->get_clicking() );
+               update_global_button ("clicking", Config->get_clicking());
        }
        else
        {
-#ifdef DEBUG
-               cout << "parameter changed: " << p << endl;
-#endif
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("parameter changed: %1\n", p));
        }
 }
 
 // RouteList is the set of routes that have just been added
-void MackieControlProtocol::notify_route_added( ARDOUR::RouteList & rl )
+void 
+MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
 {
        // currently assigned banks are less than the full set of
        // strips, so activate the new strip now.
-       if ( route_signals.size() < route_table.size() )
+       if (route_signals.size() < route_table.size())
        {
                refresh_current_bank();
        }
@@ -1449,22 +1413,24 @@ void MackieControlProtocol::notify_route_added( ARDOUR::RouteList & rl )
        }
 }
 
-void MackieControlProtocol::notify_solo_active_changed( bool active )
+void 
+MackieControlProtocol::notify_solo_active_changed (bool active)
 {
-       Button * rude_solo = reinterpret_cast<Button*>( surface().controls_by_name["solo"] );
-       mcu_port().write( builder.build_led( *rude_solo, active ? flashing : off ) );
+       Button * rude_solo = reinterpret_cast<Button*> (surface().controls_by_name["solo"]);
+       mcu_port().write (builder.build_led (*rude_solo, active ? flashing : off));
 }
 
-void MackieControlProtocol::notify_remote_id_changed()
+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() )
+       if (sorted.size() - _current_initial_bank < route_signals.size())
        {
                // but don't shift backwards past the zeroth channel
-               switch_banks( max((Sorted::size_type) 0, sorted.size() - route_signals.size() ) );
+               switch_banks (max((Sorted::size_type) 0, sorted.size() - route_signals.size()));
        }
        // Otherwise just refresh the current bank
        else
@@ -1477,41 +1443,44 @@ void MackieControlProtocol::notify_remote_id_changed()
 // Transport signals
 ///////////////////////////////////////////
 
-void MackieControlProtocol::notify_record_state_changed()
+void 
+MackieControlProtocol::notify_record_state_changed()
 {
        // switch rec button on / off / flashing
-       Button * rec = reinterpret_cast<Button*>( surface().controls_by_name["record"] );
-       mcu_port().write( builder.build_led( *rec, record_release( *rec ) ) );
+       Button * rec = reinterpret_cast<Button*> (surface().controls_by_name["record"]);
+       mcu_port().write (builder.build_led (*rec, record_release (*rec)));
 }
 
-void MackieControlProtocol::notify_transport_state_changed()
+void 
+MackieControlProtocol::notify_transport_state_changed()
 {
        // switch various play and stop buttons on / off
-       update_global_button( "play", session->transport_rolling() );
-       update_global_button( "stop", !session->transport_rolling() );
-       update_global_button( "loop", session->get_play_loop() );
+       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 ) ) );
+       Button * rec = reinterpret_cast<Button*> (surface().controls_by_name["record"]);
+       mcu_port().write (builder.build_led (*rec, record_release (*rec)));
 }
 
 /////////////////////////////////////
 // Bank Switching
 /////////////////////////////////////
-LedState MackieControlProtocol::left_press (Button &)
+LedState 
+MackieControlProtocol::left_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
-       if ( sorted.size() > route_table.size() )
+       if (sorted.size() > route_table.size())
        {
                int new_initial = _current_initial_bank - route_table.size();
-               if ( new_initial < 0 ) new_initial = 0;
-               if ( new_initial != int( _current_initial_bank ) )
+               if (new_initial < 0) new_initial = 0;
+               if (new_initial != int (_current_initial_bank))
                {
                        session->set_dirty();
-                       switch_banks( new_initial );
+                       switch_banks (new_initial);
                }
 
                return on;
@@ -1522,41 +1491,41 @@ LedState MackieControlProtocol::left_press (Button &)
        }
 }
 
-LedState MackieControlProtocol::left_release (Button &)
+LedState 
+MackieControlProtocol::left_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::right_press (Button &)
+LedState 
+MackieControlProtocol::right_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
-       if ( sorted.size() > route_table.size() )
-       {
-               uint32_t delta = sorted.size() - ( route_table.size() + _current_initial_bank );
-               if ( delta > route_table.size() ) delta = route_table.size();
-               if ( delta > 0 )
-               {
+       if (sorted.size() > route_table.size()) {
+               uint32_t delta = sorted.size() - (route_table.size() + _current_initial_bank);
+               if (delta > route_table.size()) delta = route_table.size();
+               if (delta > 0) {
                        session->set_dirty();
-                       switch_banks( _current_initial_bank + delta );
+                       switch_banks (_current_initial_bank + delta);
                }
 
                return on;
-       }
-       else
-       {
+       } else {
                return flashing;
        }
 }
 
-LedState MackieControlProtocol::right_release (Button &)
+LedState 
+MackieControlProtocol::right_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::channel_left_press (Button &)
+LedState 
+MackieControlProtocol::channel_left_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
-       if ( sorted.size() > route_table.size() )
+       if (sorted.size() > route_table.size())
        {
                prev_track();
                return on;
@@ -1567,15 +1536,17 @@ LedState MackieControlProtocol::channel_left_press (Button &)
        }
 }
 
-LedState MackieControlProtocol::channel_left_release (Button &)
+LedState 
+MackieControlProtocol::channel_left_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::channel_right_press (Button &)
+LedState 
+MackieControlProtocol::channel_right_press (Button &)
 {
        Sorted sorted = get_sorted_routes();
-       if ( sorted.size() > route_table.size() )
+       if (sorted.size() > route_table.size())
        {
                next_track();
                return on;
@@ -1586,7 +1557,8 @@ LedState MackieControlProtocol::channel_right_press (Button &)
        }
 }
 
-LedState MackieControlProtocol::channel_right_release (Button &)
+LedState 
+MackieControlProtocol::channel_right_release (Button &)
 {
        return off;
 }
@@ -1594,7 +1566,8 @@ LedState MackieControlProtocol::channel_right_release (Button &)
 /////////////////////////////////////
 // Functions
 /////////////////////////////////////
-LedState MackieControlProtocol::marker_press (Button &)
+LedState 
+MackieControlProtocol::marker_press (Button &)
 {
        // cut'n'paste from LocationUI::add_new_location()
        string markername;
@@ -1610,42 +1583,47 @@ LedState MackieControlProtocol::marker_press (Button &)
        return on;
 }
 
-LedState MackieControlProtocol::marker_release (Button &)
+LedState 
+MackieControlProtocol::marker_release (Button &)
 {
        return off;
 }
 
-void jog_wheel_state_display( JogWheel::State state, SurfacePort & port )
+void 
+jog_wheel_state_display (JogWheel::State state, SurfacePort & port)
 {
-       switch( state )
+       switch (state)
        {
-               case JogWheel::zoom: port.write( builder.two_char_display( "Zm" ) ); break;
-               case JogWheel::scroll: port.write( builder.two_char_display( "Sc" ) ); break;
-               case JogWheel::scrub: port.write( builder.two_char_display( "Sb" ) ); break;
-               case JogWheel::shuttle: port.write( builder.two_char_display( "Sh" ) ); break;
-               case JogWheel::speed: port.write( builder.two_char_display( "Sp" ) ); break;
-               case JogWheel::select: port.write( builder.two_char_display( "Se" ) ); break;
+               case JogWheel::zoom: port.write (builder.two_char_display ("Zm")); break;
+               case JogWheel::scroll: port.write (builder.two_char_display ("Sc")); break;
+               case JogWheel::scrub: port.write (builder.two_char_display ("Sb")); break;
+               case JogWheel::shuttle: port.write (builder.two_char_display ("Sh")); break;
+               case JogWheel::speed: port.write (builder.two_char_display ("Sp")); break;
+               case JogWheel::select: port.write (builder.two_char_display ("Se")); break;
        }
 }
 
-Mackie::LedState MackieControlProtocol::zoom_press( Mackie::Button & )
+Mackie::LedState 
+MackieControlProtocol::zoom_press (Mackie::Button &)
 {
        _jog_wheel.zoom_state_toggle();
-       update_global_button( "scrub", _jog_wheel.jog_wheel_state() == JogWheel::scrub );
-       jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
+       update_global_button ("scrub", _jog_wheel.jog_wheel_state() == JogWheel::scrub);
+       jog_wheel_state_display (_jog_wheel.jog_wheel_state(), mcu_port());
        return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
 }
 
-Mackie::LedState MackieControlProtocol::zoom_release( Mackie::Button & )
+Mackie::LedState 
+MackieControlProtocol::zoom_release (Mackie::Button &)
 {
        return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
 }
 
-Mackie::LedState MackieControlProtocol::scrub_press( Mackie::Button & )
+Mackie::LedState 
+MackieControlProtocol::scrub_press (Mackie::Button &)
 {
        _jog_wheel.scrub_state_cycle();
-       update_global_button( "zoom", _jog_wheel.jog_wheel_state() == JogWheel::zoom );
-       jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
+       update_global_button ("zoom", _jog_wheel.jog_wheel_state() == JogWheel::zoom);
+       jog_wheel_state_display (_jog_wheel.jog_wheel_state(), mcu_port());
        return
                _jog_wheel.jog_wheel_state() == JogWheel::scrub
                ||
@@ -1653,7 +1631,8 @@ Mackie::LedState MackieControlProtocol::scrub_press( Mackie::Button & )
        ;
 }
 
-Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & )
+Mackie::LedState 
+MackieControlProtocol::scrub_release (Mackie::Button &)
 {
        return
                _jog_wheel.jog_wheel_state() == JogWheel::scrub
@@ -1662,31 +1641,36 @@ Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & )
        ;
 }
 
-LedState MackieControlProtocol::drop_press (Button &)
+LedState 
+MackieControlProtocol::drop_press (Button &)
 {
        session->remove_last_capture();
        return on;
 }
 
-LedState MackieControlProtocol::drop_release (Button &)
+LedState 
+MackieControlProtocol::drop_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::save_press (Button &)
+LedState 
+MackieControlProtocol::save_press (Button &)
 {
-       session->save_state( "" );
+       session->save_state ("");
        return on;
 }
 
-LedState MackieControlProtocol::save_release (Button &)
+LedState 
+MackieControlProtocol::save_release (Button &)
 {
        return off;
 }
 
-LedState MackieControlProtocol::timecode_beats_press (Button &)
+LedState 
+MackieControlProtocol::timecode_beats_press (Button &)
 {
-       switch ( _timecode_type )
+       switch (_timecode_type)
        {
                case ARDOUR::AnyTime::BBT:
                        _timecode_type = ARDOUR::AnyTime::Timecode;
@@ -1697,13 +1681,15 @@ LedState MackieControlProtocol::timecode_beats_press (Button &)
                default:
                        ostringstream os;
                        os << "Unknown Anytime::Type " << _timecode_type;
-                       throw runtime_error( os.str() );
+                       throw runtime_error (os.str());
        }
        update_timecode_beats_led();
        return on;
 }
 
-LedState MackieControlProtocol::timecode_beats_release( Button & )
+LedState 
+MackieControlProtocol::timecode_beats_release (Button &)
 {
        return off;
 }
+
index 58d05f7b7fa0e99796ec29ca8bba26d09b339ccf..14be7b437080dce071b2beb84f7aab4979453882 100644 (file)
@@ -1,20 +1,21 @@
 /*
-       Copyright (C) 2006,2007 John Anderson
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+    Copyright (C) 2006,2007 John Anderson
+    
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+    
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+    
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
+
 #ifndef ardour_mackie_control_protocol_h
 #define ardour_mackie_control_protocol_h
 
@@ -26,6 +27,7 @@
 #include <glibmm/thread.h>
 
 #include "ardour/types.h"
+#include "ardour/midi_ui.h"
 #include "midi++/types.h"
 
 #include "control_protocol/control_protocol.h"
@@ -40,7 +42,6 @@
 
 namespace MIDI {
        class Port;
-       class Parser;
 }
 
 namespace Mackie {
@@ -66,12 +67,13 @@ namespace Mackie {
        up the relevant Strip in Surface. Then the state is retrieved from
        the Route and encoded as the correct midi message.
 */
-class MackieControlProtocol
-: public ARDOUR::ControlProtocol
-, public Mackie::MackieButtonHandler
+
+class MackieControlProtocol 
+       : public ARDOUR::ControlProtocol
+       , public Mackie::MackieButtonHandler
 {
   public:
-       MackieControlProtocol( ARDOUR::Session & );
+       MackieControlProtocol(ARDOUR::Session &);
        virtual ~MackieControlProtocol();
 
        int set_active (bool yn);
@@ -83,130 +85,131 @@ class MackieControlProtocol
        
        Mackie::Surface & surface();
 
-   // control events
-   void handle_control_event( Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state );
+       // control events
+       void handle_control_event(Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state);
 
-  // strip/route related stuff
+       // strip/route related stuff
   public:      
        /// Signal handler for Route::solo
-       void notify_solo_changed( Mackie::RouteSignal * );
+       void notify_solo_changed(Mackie::RouteSignal *);
        /// Signal handler for Route::mute
-       void notify_mute_changed( Mackie::RouteSignal * );
+       void notify_mute_changed(Mackie::RouteSignal *);
        /// Signal handler for Route::record_enable_changed
-       void notify_record_enable_changed( Mackie::RouteSignal * );
-       /// Signal handler for Route::gain_changed ( from IO )
-       void notify_gain_changed( Mackie::RouteSignal *, bool force_update = true );
+       void notify_record_enable_changed(Mackie::RouteSignal *);
+       /// Signal handler for Route::gain_changed (from IO)
+       void notify_gain_changed(Mackie::RouteSignal *, bool force_update = true);
        /// Signal handler for Route::name_change
-       void notify_name_changed( Mackie::RouteSignal * );
+       void notify_name_changed(Mackie::RouteSignal *);
        /// Signal handler from Panner::Change
-       void notify_panner_changed( Mackie::RouteSignal *, bool force_update = true );
+       void notify_panner_changed(Mackie::RouteSignal *, bool force_update = true);
        /// Signal handler for new routes added
-       void notify_route_added( ARDOUR::RouteList & );
+       void notify_route_added(ARDOUR::RouteList &);
        /// Signal handler for Route::active_changed
-       void notify_active_changed( Mackie::RouteSignal * );
+       void notify_active_changed(Mackie::RouteSignal *);
  
        void notify_remote_id_changed();
 
        /// rebuild the current bank. Called on route added/removed and
-   /// remote id changed.
+       /// remote id changed.
        void refresh_current_bank();
 
-  // global buttons (ie button not part of strips)
+       // global buttons (ie button not part of strips)
+
   public:
-   // button-related signals
+       // button-related signals
        void notify_record_state_changed();
-   void notify_transport_state_changed();
-   // mainly to pick up punch-in and punch-out
-       void notify_parameter_changed( std::string const & );
-   void notify_solo_active_changed( bool );
+       void notify_transport_state_changed();
+       // mainly to pick up punch-in and punch-out
+       void notify_parameter_changed(std::string const &);
+       void notify_solo_active_changed(bool);
 
        /// Turn timecode on and beats off, or vice versa, depending
        /// on state of _timecode_type
        void update_timecode_beats_led();
   
        /// this is called to generate the midi to send in response to a button press.
-       void update_led( Mackie::Button & button, Mackie::LedState );
+       void update_led(Mackie::Button & button, Mackie::LedState);
   
-       void update_global_button( const std::string & name, Mackie::LedState );
-       void update_global_led( const std::string & name, Mackie::LedState );
+       void update_global_button(const std::string & name, Mackie::LedState);
+       void update_global_led(const std::string & name, Mackie::LedState);
   
-   // transport button handler methods from MackieButtonHandler
-       virtual Mackie::LedState frm_left_press( Mackie::Button & );
-       virtual Mackie::LedState frm_left_release( Mackie::Button & );
+       // transport button handler methods from MackieButtonHandler
+       virtual Mackie::LedState frm_left_press(Mackie::Button &);
+       virtual Mackie::LedState frm_left_release(Mackie::Button &);
 
-       virtual Mackie::LedState frm_right_press( Mackie::Button & );
-       virtual Mackie::LedState frm_right_release( Mackie::Button & );
+       virtual Mackie::LedState frm_right_press(Mackie::Button &);
+       virtual Mackie::LedState frm_right_release(Mackie::Button &);
 
-       virtual Mackie::LedState stop_press( Mackie::Button & );
-       virtual Mackie::LedState stop_release( Mackie::Button & );
+       virtual Mackie::LedState stop_press(Mackie::Button &);
+       virtual Mackie::LedState stop_release(Mackie::Button &);
 
-       virtual Mackie::LedState play_press( Mackie::Button & );
-       virtual Mackie::LedState play_release( Mackie::Button & );
+       virtual Mackie::LedState play_press(Mackie::Button &);
+       virtual Mackie::LedState play_release(Mackie::Button &);
 
-       virtual Mackie::LedState record_press( Mackie::Button & );
-       virtual Mackie::LedState record_release( Mackie::Button & );
+       virtual Mackie::LedState record_press(Mackie::Button &);
+       virtual Mackie::LedState record_release(Mackie::Button &);
 
-       virtual Mackie::LedState loop_press( Mackie::Button & );
-       virtual Mackie::LedState loop_release( Mackie::Button & );
+       virtual Mackie::LedState loop_press(Mackie::Button &);
+       virtual Mackie::LedState loop_release(Mackie::Button &);
 
-       virtual Mackie::LedState punch_in_press( Mackie::Button & );
-       virtual Mackie::LedState punch_in_release( Mackie::Button & );
+       virtual Mackie::LedState punch_in_press(Mackie::Button &);
+       virtual Mackie::LedState punch_in_release(Mackie::Button &);
 
-       virtual Mackie::LedState punch_out_press( Mackie::Button & );
-       virtual Mackie::LedState punch_out_release( Mackie::Button & );
+       virtual Mackie::LedState punch_out_press(Mackie::Button &);
+       virtual Mackie::LedState punch_out_release(Mackie::Button &);
 
-       virtual Mackie::LedState home_press( Mackie::Button & );
-       virtual Mackie::LedState home_release( Mackie::Button & );
+       virtual Mackie::LedState home_press(Mackie::Button &);
+       virtual Mackie::LedState home_release(Mackie::Button &);
 
-       virtual Mackie::LedState end_press( Mackie::Button & );
-       virtual Mackie::LedState end_release( Mackie::Button & );
+       virtual Mackie::LedState end_press(Mackie::Button &);
+       virtual Mackie::LedState end_release(Mackie::Button &);
        
-       virtual Mackie::LedState rewind_press( Mackie::Button & button );
-       virtual Mackie::LedState rewind_release( Mackie::Button & button );
+       virtual Mackie::LedState rewind_press(Mackie::Button & button);
+       virtual Mackie::LedState rewind_release(Mackie::Button & button);
 
-       virtual Mackie::LedState ffwd_press( Mackie::Button & button );
-       virtual Mackie::LedState ffwd_release( Mackie::Button & button );
+       virtual Mackie::LedState ffwd_press(Mackie::Button & button);
+       virtual Mackie::LedState ffwd_release(Mackie::Button & button);
 
        // bank switching button handler methods from MackieButtonHandler
-       virtual Mackie::LedState left_press( Mackie::Button & );
-       virtual Mackie::LedState left_release( Mackie::Button & );
+       virtual Mackie::LedState left_press(Mackie::Button &);
+       virtual Mackie::LedState left_release(Mackie::Button &);
 
-       virtual Mackie::LedState right_press( Mackie::Button & );
-       virtual Mackie::LedState right_release( Mackie::Button & );
+       virtual Mackie::LedState right_press(Mackie::Button &);
+       virtual Mackie::LedState right_release(Mackie::Button &);
 
-       virtual Mackie::LedState channel_left_press( Mackie::Button & );
-       virtual Mackie::LedState channel_left_release( Mackie::Button & );
+       virtual Mackie::LedState channel_left_press(Mackie::Button &);
+       virtual Mackie::LedState channel_left_release(Mackie::Button &);
 
-       virtual Mackie::LedState channel_right_press( Mackie::Button & );
-       virtual Mackie::LedState channel_right_release( Mackie::Button & );
+       virtual Mackie::LedState channel_right_press(Mackie::Button &);
+       virtual Mackie::LedState channel_right_release(Mackie::Button &);
        
-       virtual Mackie::LedState clicking_press( Mackie::Button & );
-       virtual Mackie::LedState clicking_release( Mackie::Button & );
+       virtual Mackie::LedState clicking_press(Mackie::Button &);
+       virtual Mackie::LedState clicking_release(Mackie::Button &);
        
-       virtual Mackie::LedState global_solo_press( Mackie::Button & );
-       virtual Mackie::LedState global_solo_release( Mackie::Button & );
+       virtual Mackie::LedState global_solo_press(Mackie::Button &);
+       virtual Mackie::LedState global_solo_release(Mackie::Button &);
        
        // function buttons
-       virtual Mackie::LedState marker_press( Mackie::Button & );
-       virtual Mackie::LedState marker_release( Mackie::Button & );
+       virtual Mackie::LedState marker_press(Mackie::Button &);
+       virtual Mackie::LedState marker_release(Mackie::Button &);
 
-       virtual Mackie::LedState drop_press( Mackie::Button & );
-       virtual Mackie::LedState drop_release( Mackie::Button & );
+       virtual Mackie::LedState drop_press(Mackie::Button &);
+       virtual Mackie::LedState drop_release(Mackie::Button &);
 
-       virtual Mackie::LedState save_press( Mackie::Button & );
-       virtual Mackie::LedState save_release( Mackie::Button & );
+       virtual Mackie::LedState save_press(Mackie::Button &);
+       virtual Mackie::LedState save_release(Mackie::Button &);
 
-       virtual Mackie::LedState timecode_beats_press( Mackie::Button & );
-       virtual Mackie::LedState timecode_beats_release( Mackie::Button & );
+       virtual Mackie::LedState timecode_beats_press(Mackie::Button &);
+       virtual Mackie::LedState timecode_beats_release(Mackie::Button &);
 
        // jog wheel states
-       virtual Mackie::LedState zoom_press( Mackie::Button & );
-       virtual Mackie::LedState zoom_release( Mackie::Button & );
+       virtual Mackie::LedState zoom_press(Mackie::Button &);
+       virtual Mackie::LedState zoom_release(Mackie::Button &);
 
-       virtual Mackie::LedState scrub_press( Mackie::Button & );
-       virtual Mackie::LedState scrub_release( Mackie::Button & );
+       virtual Mackie::LedState scrub_press(Mackie::Button &);
+       virtual Mackie::LedState scrub_release(Mackie::Button &);
        
-   /// This is the main MCU port, ie not an extender port
+       /// This is the main MCU port, ie not an extender port
        /// Only for use by JogWheel
        const Mackie::SurfacePort & mcu_port() const;
        Mackie::SurfacePort & mcu_port();
@@ -225,98 +228,83 @@ class MackieControlProtocol
        void initialize_surface();
   
        // This sets up the notifications and sets the
-   // controls to the correct values
+       // controls to the correct values
        void update_surface();
-  
-   // connects global (not strip) signals from the Session to here
-   // so the surface can be notified of changes from the other UIs.
-   void connect_session_signals();
-  
-   // set all controls to their zero position
+       
+       // connects global (not strip) signals from the Session to here
+       // so the surface can be notified of changes from the other UIs.
+       void connect_session_signals();
+       
+       // set all controls to their zero position
        void zero_all();
        
        /**
-               Fetch the set of routes to be considered for control by the
-               surface. Excluding master, hidden and control routes, and inactive routes
+          Fetch the set of routes to be considered for control by the
+          surface. Excluding master, hidden and control routes, and inactive routes
        */
        typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
        Sorted get_sorted_routes();
   
-   // bank switching
-   void switch_banks( int initial );
-   void prev_track();
-   void next_track();
+       // bank switching
+       void switch_banks(int initial);
+       void prev_track();
+       void next_track();
   
-   // delete all RouteSignal objects connecting Routes to Strips
-   void clear_route_signals();
+       // delete all RouteSignal objects connecting Routes to Strips
+       void clear_route_signals();
        
        typedef std::vector<Mackie::RouteSignal*> RouteSignals;
        RouteSignals route_signals;
        
-   // return which of the ports a particular route_table
-   // index belongs to
-       Mackie::MackiePort & port_for_id( uint32_t index );
+       // return which of the ports a particular route_table
+       // index belongs to
+       Mackie::MackiePort & port_for_id(uint32_t index);
 
        /**
-               Handle a button press for the control and return whether
-               the corresponding light should be on or off.
+          Handle a button press for the control and return whether
+          the corresponding light should be on or off.
        */
-       bool handle_strip_button( Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route> );
-
-       /// thread started. Calls monitor_work.
-       static void* _monitor_work (void* arg);
-       
-       /// Polling midi port(s) for incoming messages
-       void* monitor_work ();
-       
-       /// rebuild the set of ports for this surface
-       void update_ports();
-       
-       /// Returns true if there is pending data, false otherwise
-       bool poll_ports();
-       
-       /// Trigger the MIDI::Parser
-       void read_ports();
+       bool handle_strip_button(Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
 
-       void add_port( MIDI::Port &, int number );
+       void add_port(MIDI::Port &, int number);
 
        /**
-               Read session data and send to surface. Includes
-               automation from the currently active routes and
-               timecode displays.
+          Read session data and send to surface. Includes
+          automation from the currently active routes and
+          timecode displays.
        */
        void poll_session_data();
        
        // called from poll_automation to figure out which automations need to be sent
-       void update_automation( Mackie::RouteSignal & );
+       void update_automation(Mackie::RouteSignal &);
        
        // also called from poll_automation to update timecode display
        void update_timecode_display();
 
-       std::string format_bbt_timecode (ARDOUR::nframes_t now_frame );
-       std::string format_timecode_timecode (ARDOUR::nframes_t now_frame );
+       std::string format_bbt_timecode (ARDOUR::nframes_t now_frame);
+       std::string format_timecode_timecode (ARDOUR::nframes_t now_frame);
        
        /**
-               notification that the port is about to start it's init sequence.
-               We must make sure that before this exits, the port is being polled
-               for new data.
+          notification that the port is about to start it's init sequence.
+          We must make sure that before this exits, the port is being polled
+          for new data.
        */
-       void handle_port_init( Mackie::SurfacePort * );
+       void handle_port_init(Mackie::SurfacePort *);
 
        /// notification from a MackiePort that it's now active
-       void handle_port_active( Mackie::SurfacePort * );
+       void handle_port_active(Mackie::SurfacePort *);
        
        /// notification from a MackiePort that it's now inactive
-       void handle_port_inactive( Mackie::SurfacePort * );
+       void handle_port_inactive(Mackie::SurfacePort *);
        
        boost::shared_ptr<ARDOUR::Route> master_route();
        Mackie::Strip & master_strip();
 
   private:
        boost::shared_ptr<Mackie::RouteSignal> master_route_signal;
-  
-   static const char * default_port_name;
-  
+       
+       static const char * default_port_name;
+       
        /// The Midi port(s) connected to the units
        typedef std::vector<Mackie::MackiePort*> MackiePorts;
        MackiePorts _ports;
@@ -324,18 +312,12 @@ class MackieControlProtocol
        /// Sometimes the real port goes away, and we want to contain the breakage
        Mackie::DummyPort _dummy_port;
   
-   // the thread that polls the ports for incoming midi data
-       pthread_t thread;
-  
        /// The initial remote_id of the currently switched in bank.
-   uint32_t _current_initial_bank;
+       uint32_t _current_initial_bank;
        
-   /// protects the port list, and polling structures
+       /// protects the port list
        Glib::Mutex update_mutex;
   
-       /// Protects set_active, and allows waiting on the poll thread
-       Glib::Cond update_cond;
-       
        PBD::ScopedConnectionList session_connections;
        PBD::ScopedConnectionList port_connections;
        PBD::ScopedConnectionList route_connections;
@@ -343,14 +325,6 @@ class MackieControlProtocol
        /// The representation of the physical controls on the surface.
        Mackie::Surface * _surface;
        
-       /// If a port is opened or closed, this will be
-       /// true until the port configuration is updated;
-       bool _ports_changed;
-
-       bool _polling;
-       struct pollfd * pfd;
-       int nfds;
-       
        bool _transport_previously_rolling;
        
        // timer for two quick marker left presses
@@ -358,9 +332,6 @@ class MackieControlProtocol
        
        Mackie::JogWheel _jog_wheel;
        
-       // Timer for controlling midi bandwidth used by automation polls
-       Mackie::Timer _automation_last;
-       
        // last written timecode string
        std::string _timecode_last;
        
index f6171c7f0e7d0fcc8d99304800895a2dc52e891e..6392a91c4f6abe36ff7432dfb98186326bd1291f 100644 (file)
@@ -29,151 +29,14 @@ const char * MackieControlProtocol::default_port_name = "mcu";
 
 bool MackieControlProtocol::probe()
 {
-       if ( MIDI::Manager::instance()->port( default_port_name ) == 0 )
-       {
+       if ( MIDI::Manager::instance()->port(default_port_name)  == 0 ) {
                info << "Mackie: No MIDI port called " << default_port_name << endmsg;
                return false;
-       }
-       else
-       {
+       } else {
                return true;
        }
 }
 
-void * MackieControlProtocol::monitor_work()
-{
-       register_thread (X_("MCU"));
-
-       pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
-       pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
-
-       // read from midi ports
-       while ( _polling )
-       {
-               try
-               {
-                       if ( poll_ports() )
-                       {
-                               try { read_ports(); }
-                               catch ( exception & e ) {
-                                       cout << "MackieControlProtocol::poll_ports caught exception: " << e.what() << endl;
-                                       _ports_changed = true;
-                                       update_ports();
-                               }
-                       }
-                       // poll for session data that needs to go to the unit
-                       poll_session_data();
-               }
-               catch ( exception & e )
-               {
-                       cout << "caught exception in MackieControlProtocol::monitor_work " << e.what() << endl;
-               }
-       }
-
-       // TODO ports and pfd and nfds should be in a separate class
-       delete[] pfd;
-       pfd = 0;
-       nfds = 0;
-
-       return (void*) 0;
-}
-
-void MackieControlProtocol::update_ports()
-{
-#ifdef DEBUG
-       cout << "MackieControlProtocol::update_ports" << endl;
-#endif
-       if ( _ports_changed )
-       {
-               Glib::Mutex::Lock ul( update_mutex );
-               // yes, this is a double-test locking paradigm, or whatever it's called
-               // because we don't *always* need to acquire the lock for the first test
-#ifdef DEBUG
-               cout << "MackieControlProtocol::update_ports lock acquired" << endl;
-#endif
-               if ( _ports_changed )
-               {
-                       // create new pollfd structures
-                       delete[] pfd;
-                       pfd = new pollfd[_ports.size()];
-#ifdef DEBUG
-                       cout << "pfd: " << pfd << endl;
-#endif
-                       nfds = 0;
-                       for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
-                       {
-                               // add the port any handler
-                               (*it)->connect_any();
-#ifdef DEBUG
-                               cout << "adding pollfd for port " << (*it)->port().name() << " to pollfd " << nfds << endl;
-#endif
-                               pfd[nfds].fd = (*it)->port().selectable();
-                               pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
-                               ++nfds;
-                       }
-                       _ports_changed = false;
-               }
-#ifdef DEBUG
-               cout << "MackieControlProtocol::update_ports signal" << endl;
-#endif
-               update_cond.signal();
-       }
-#ifdef DEBUG
-       cout << "MackieControlProtocol::update_ports finish" << endl;
-#endif
-}
-
-void MackieControlProtocol::read_ports()
-{
-       /* now read any data on the ports */
-       Glib::Mutex::Lock lock( update_mutex );
-       for ( int p = 0; p < nfds; ++p )
-       {
-               // this will cause handle_midi_any in the MackiePort to be triggered
-               // for alsa/raw ports
-               // alsa/sequencer ports trigger the midi parser off poll
-               if ( (pfd[p].revents & POLLIN) > 0 )
-               {
-                       // avoid deadlocking?
-                       // doesn't seem to make a difference
-                       //lock.release();
-                       _ports[p]->read();
-                       //lock.acquire();
-               }
-       }
-}
-
-bool MackieControlProtocol::poll_ports()
-{
-       int timeout = 10; // milliseconds
-       int no_ports_sleep = 1000; // milliseconds
-
-       Glib::Mutex::Lock lock( update_mutex );
-       // if there are no ports
-       if ( nfds < 1 )
-       {
-               lock.release();
-#ifdef DEBUG
-               cout << "poll_ports no ports" << endl;
-#endif
-               usleep( no_ports_sleep * 1000 );
-               return false;
-       }
-
-       int retval = ::poll( pfd, nfds, timeout );
-       if ( retval < 0 )
-       {
-               // gdb at work, perhaps
-               if ( errno != EINTR )
-               {
-                       error << string_compose(_("Mackie MIDI thread poll failed (%1)"), strerror( errno ) ) << endmsg;
-               }
-               return false;
-       }
-       
-       return retval > 0;
-}
-
 void MackieControlProtocol::handle_port_inactive( SurfacePort * port )
 {
        // port gone away. So stop polling it ASAP
@@ -187,9 +50,7 @@ void MackieControlProtocol::handle_port_inactive( SurfacePort * port )
                        _ports.erase( it );
                }
        }
-       _ports_changed = true;
-       update_ports();
-       
+
        // TODO all the rebuilding of surfaces and so on
 }
 
@@ -219,8 +80,6 @@ void MackieControlProtocol::handle_port_init (Mackie::SurfacePort *)
 #ifdef DEBUG
        cout << "MackieControlProtocol::handle_port_init" << endl;
 #endif
-       _ports_changed = true;
-       update_ports();
 #ifdef DEBUG
        cout << "MackieControlProtocol::handle_port_init finish" << endl;
 #endif
index 8cf69585e3a393477e1d6fcea053d14863ae2827..069ad9abb43095fad0839f28b7312ebb0bcf5909 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "midi++/types.h"
 #include "midi++/port.h"
+
+#include "ardour/debug.h"
 #include "ardour/rc_configuration.h"
 
 #include "i18n.h"
@@ -37,6 +39,7 @@
 
 using namespace std;
 using namespace Mackie;
+using namespace ARDOUR;
 
 // The MCU sysex header
 MidiByteArray mackie_sysex_hdr ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10 );
@@ -45,26 +48,20 @@ MidiByteArray mackie_sysex_hdr ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10 );
 MidiByteArray mackie_sysex_hdr_xt ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x11 );
 
 MackiePort::MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int number, port_type_t port_type )
-: SurfacePort( port, number )
-, _mcp( mcp )
-, _port_type( port_type )
-, _emulation( none )
-, _initialising( true )
+  : SurfacePort( port, number )
+  , _mcp( mcp )
+  , _port_type( port_type )
+  , _emulation( none )
+  , _initialising( true )
 {
-#ifdef PORT_DEBUG
-       cout << "MackiePort::MackiePort" <<endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::MackiePort\n");
 }
 
 MackiePort::~MackiePort()
 {
-#ifdef PORT_DEBUG
-       cout << "~MackiePort" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::~MackiePort\n");
        close();
-#ifdef PORT_DEBUG
-       cout << "~MackiePort finished" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "~MackiePort finished\n");
 }
 
 int MackiePort::strips() const
@@ -91,29 +88,23 @@ int MackiePort::strips() const
 // should really be in MackiePort
 void MackiePort::open()
 {
-#ifdef PORT_DEBUG
-       cout << "MackiePort::open " << *this << endl;
-#endif
-       port().input()->sysex.connect (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::open %1\n", *this));
        
+       port().input()->sysex.connect (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
+                    
        // make sure the device is connected
        init();
 }
 
 void MackiePort::close()
 {
-#ifdef PORT_DEBUG
-       cout << "MackiePort::close" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::close\n");
        
        // disconnect signals
        any_connection.disconnect();
        sysex_connection.disconnect();
        
        // TODO emit a "closing" signal?
-#ifdef PORT_DEBUG
-       cout << "MackiePort::close finished" << endl;
-#endif
 }
 
 const MidiByteArray & MackiePort::sysex_hdr() const
@@ -149,9 +140,7 @@ MidiByteArray calculate_challenge_response( MidiByteArray::iterator begin, MidiB
 MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
 {
        // handle host connection query
-#ifdef PORT_DEBUG
-       cout << "host connection query: " << bytes << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host connection query: %1\n", bytes));
        
        if ( bytes.size() != 18 )
        {
@@ -172,9 +161,7 @@ MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
 // not used right now
 MidiByteArray MackiePort::host_connection_confirmation( const MidiByteArray & bytes )
 {
-#ifdef PORT_DEBUG
-       cout << "host_connection_confirmation: " << bytes << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host_connection_confirmation: %1\n", bytes));
        
        // decode host connection confirmation
        if ( bytes.size() != 14 )
@@ -213,15 +200,13 @@ void MackiePort::probe_emulation (const MidiByteArray &)
 
 void MackiePort::init()
 {
-#ifdef PORT_DEBUG
-       cout << "MackiePort::init" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl,  "MackiePort::init\n");
+
        init_mutex.lock();
        _initialising = true;
-       
-#ifdef PORT_DEBUG
-       cout << "MackiePort::init lock acquired" << endl;
-#endif
+
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::init lock acquired\n");
+
        // emit pre-init signal
        init_event();
        
@@ -237,9 +222,8 @@ void MackiePort::init()
 
 void MackiePort::finalise_init( bool yn )
 {
-#ifdef PORT_DEBUG
-       cout << "MackiePort::finalise_init" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::finalise_init\n");
+
        bool emulation_ok = false;
        
        // probing doesn't work very well, so just use a config variable
@@ -271,19 +255,18 @@ void MackiePort::finalise_init( bool yn )
        
        SurfacePort::active( yn );
 
-       if ( yn )
-       {
+       if (yn) {
                active_event();
                
                // start handling messages from controls
                connect_any();
        }
+
        _initialising = false;
        init_cond.signal();
        init_mutex.unlock();
-#ifdef PORT_DEBUG
-       cout << "MackiePort::finalise_init lock released" << endl;
-#endif
+
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::finalise_init lock released\n");
 }
 
 void MackiePort::connect_any()
@@ -296,44 +279,36 @@ void MackiePort::connect_any()
 bool MackiePort::wait_for_init()
 {
        Glib::Mutex::Lock lock( init_mutex );
-       while ( _initialising )
-       {
-#ifdef PORT_DEBUG
-               cout << "MackiePort::wait_for_active waiting" << endl;
-#endif
+       while (_initialising) {
+               DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active waiting\n");
                init_cond.wait( init_mutex );
-#ifdef PORT_DEBUG
-               cout << "MackiePort::wait_for_active released" << endl;
-#endif
+               DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active released\n");
        }
-#ifdef PORT_DEBUG
-       cout << "MackiePort::wait_for_active returning" << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active returning\n");
        return SurfacePort::active();
 }
 
 void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
 {
        MidiByteArray bytes( count, raw_bytes );
-#ifdef PORT_DEBUG
-       cout << "handle_midi_sysex: " << bytes << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handle_midi_sysex: %1\n", bytes));
+
        switch( bytes[5] )
        {
                case 0x01:
                        // not used right now
-                       write_sysex( host_connection_query( bytes ) );
+                       write_sysex (host_connection_query (bytes));
                        break;
                case 0x03:
                        // not used right now
-                       write_sysex( host_connection_confirmation( bytes ) );
+                       write_sysex (host_connection_confirmation (bytes));
                        break;
                case 0x04:
-                       inactive_event();
+                       inactive_event ();
                        cout << "host connection error" << bytes << endl;
                        break;
                case 0x14:
-                       probe_emulation( bytes );
+                       probe_emulation (bytes);
                        break;
                default:
                        cout << "unknown sysex: " << bytes << endl;
@@ -345,10 +320,11 @@ Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
        // Don't instantiate a MidiByteArray here unless it's needed for exceptions.
        // Reason being that this method is called for every single incoming
        // midi event, and it needs to be as efficient as possible.
+
        Control * control = 0;
        MIDI::byte midi_type = bytes[0] & 0xf0; //0b11110000
-       switch( midi_type )
-       {
+
+       switch (midi_type) {
                // fader
                case MackieMidiBuilder::midi_fader_id:
                {
@@ -413,18 +389,16 @@ bool MackiePort::handle_control_timeout_event ( Control * control )
 // because they have similar logic flows.
 void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
 {
-#ifdef DEBUG
        MidiByteArray bytes( count, raw_bytes );
-       cout << "MackiePort::handle_midi_any " << bytes << endl;
-#endif
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::handle_midi_any %1\n", bytes));
+
        try
        {
                // ignore sysex messages
                if ( raw_bytes[0] == MIDI::sysex ) return;
 
                // sanity checking
-               if ( count != 3 )
-               {
+               if (count != 3) {
                        ostringstream os;
                        MidiByteArray mba( count, raw_bytes );
                        os << "MackiePort::handle_midi_any needs 3 bytes, but received " << mba;
@@ -436,8 +410,7 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
                
                // This handles incoming bytes. Outgoing bytes
                // are sent by the signal handlers.
-               switch ( control.type() )
-               {
+               switch (control.type()) {
                        // fader
                        case Control::type_fader:
                        {
@@ -484,17 +457,15 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
                                // first disconnect any previous timeouts
                                control.in_use_connection.disconnect();
                                
-#if 0 // BOOSTSIGNALS
                                // now connect a new timeout to call handle_control_timeout_event
-                               sigc::slot<bool> timeout_slot = sigc::bind (
-                                       mem_fun( *this, &MackiePort::handle_control_timeout_event )
-                                       , &control
-                               );
-                               control.in_use_connection = Glib::signal_timeout().connect(
-                                       timeout_slot
-                                       , control.in_use_timeout()
-                               );
-#endif                         
+                               // XXX should this use the GUI event loop (default) or the
+                               // MIDI UI event loop ?
+
+                               sigc::slot<bool> timeout_slot = sigc::bind 
+                                       (sigc::mem_fun( *this, &MackiePort::handle_control_timeout_event), &control);
+
+                               control.in_use_connection = Glib::signal_timeout().connect (timeout_slot , control.in_use_timeout());
+
                                // emit the control event
                                control_event( *this, control, state );
                                break;
@@ -503,12 +474,11 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
                                cerr << "Do not understand control type " << control;
                }
        }
-       catch( MackieControlException & e )
-       {
+
+       catch( MackieControlException & e ) {
                MidiByteArray bytes( count, raw_bytes );
                cout << bytes << ' ' << e.what() << endl;
        }
-#ifdef DEBUG
-       cout << "finished MackiePort::handle_midi_any " << bytes << endl;
-#endif
+
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("finished MackiePort::handle_midi_any %1\n", bytes));
 }