diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-11-03 21:10:31 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-11-03 21:10:31 +0000 |
commit | e0af0cf5926c9f0c2833cea1b0b96c6df5934fc5 (patch) | |
tree | eb9b249c659e1a84458b1a275ab8fafe5b94cb18 /libs/surfaces | |
parent | c641b92c123ee7539790f9a9a1214d03d305e26c (diff) |
substantial reformatting of code (http://ardour.org/development/styleguide); attempt to rationalize connections made to Config, Session and Route objects; drop master bus in ::close(). MUST BE TESTED BY MCU USERS WITH MULTIPLE SESSIONS PER ARDOUR INSTANCE
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6011 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces')
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.cc | 487 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.h | 160 |
2 files changed, 363 insertions, 284 deletions
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index e55d7b1f44..bf3dc6b514 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -74,7 +74,6 @@ MackieMidiBuilder builder; MackieControlProtocol::MackieControlProtocol (Session& session) : ControlProtocol (session, X_("Mackie")) , _current_initial_bank( 0 ) - , connections_back( _connections ) , _surface( 0 ) , _ports_changed( false ) , _polling( true ) @@ -88,6 +87,9 @@ MackieControlProtocol::MackieControlProtocol (Session& session) #endif // will start reading from ports, as soon as there are some pthread_create_and_store (X_("mackie monitor"), &thread, 0, _monitor_work, this); + + // receive punch-in and punch-out + Config->ParameterChanged.connect ((mem_fun (*this, &MackieControlProtocol::notify_parameter_changed))); } MackieControlProtocol::~MackieControlProtocol() @@ -112,45 +114,41 @@ MackieControlProtocol::~MackieControlProtocol() #endif } -Mackie::Surface & MackieControlProtocol::surface() +Mackie::Surface & +MackieControlProtocol::surface() { - if ( _surface == 0 ) - { + 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 - { + } 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 - { + } 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 ); } @@ -158,32 +156,38 @@ void MackieControlProtocol::prev_track() // 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 ); } } -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(); + + for (vector<sigc::connection>::iterator c = route_connections.begin(); c != route_connections.end(); ++c) { + (*c).disconnect (); + } + route_connections.clear (); + } // 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; } @@ -197,23 +201,21 @@ MackiePort & MackieControlProtocol::port_for_id( uint32_t index ) // 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; @@ -246,12 +248,14 @@ MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes() return sorted; } -void MackieControlProtocol::refresh_current_bank() +void +MackieControlProtocol::refresh_current_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 @@ -269,7 +273,7 @@ void MackieControlProtocol::switch_banks( int initial ) _current_initial_bank = initial; // first clear the signals from old routes - // taken care of by the RouteSignal destructors + // taken care of by the RouteSignal destructors and explicit disconnect from other Route signals such as GoingAway clear_route_signals(); // now set the signals for new routes @@ -295,6 +299,7 @@ void MackieControlProtocol::switch_banks( int initial ) route_table[i] = route; RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i) ); route_signals.push_back( rs ); + route_connections.push_back (route->GoingAway.connect (mem_fun (*this, &MackieControlProtocol::route_deleted))); // update strip from route rs->notify_all(); } @@ -314,7 +319,18 @@ void MackieControlProtocol::switch_banks( int initial ) surface().display_bank_start( mcu_port(), builder, _current_initial_bank ); } -void MackieControlProtocol::zero_all() +void +MackieControlProtocol::route_deleted () +{ + for (vector<sigc::connection>::iterator c = route_connections.begin(); c != route_connections.end(); ++c) { + (*c).disconnect (); + } + route_connections.clear (); + update_surface (); +} + +void +MackieControlProtocol::zero_all() { // TODO turn off SMPTE displays @@ -344,7 +360,8 @@ void MackieControlProtocol::zero_all() surface().zero_all( mcu_port(), builder ); } -int MackieControlProtocol::set_active( bool yn ) +int +MackieControlProtocol::set_active( bool yn ) { if ( yn != _active ) { @@ -391,7 +408,7 @@ int MackieControlProtocol::set_active( bool yn ) // correctly initialised initialize_surface(); connect_session_signals(); - + // yeehah! _active = true; @@ -418,7 +435,8 @@ 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; @@ -460,7 +478,8 @@ bool MackieControlProtocol::handle_strip_button( Control & control, ButtonState 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 ) { @@ -484,7 +503,8 @@ void MackieControlProtocol::update_led( Mackie::Button & button, Mackie::LedStat } } -void MackieControlProtocol::update_smpte_beats_led() +void +MackieControlProtocol::update_smpte_beats_led() { switch ( _timecode_type ) { @@ -503,7 +523,8 @@ void MackieControlProtocol::update_smpte_beats_led() } } -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() ) { @@ -518,7 +539,8 @@ void MackieControlProtocol::update_global_button( const string & name, LedState } } -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() ) { @@ -534,7 +556,8 @@ void MackieControlProtocol::update_global_led( const string & name, LedState ls } // send messages to surface to set controls to correct values -void MackieControlProtocol::update_surface() +void +MackieControlProtocol::update_surface() { if ( _active ) { @@ -542,10 +565,13 @@ void MackieControlProtocol::update_surface() // _current_initial_bank is initialised by set_state switch_banks( _current_initial_bank ); - // create a RouteSignal for the master route + // remove any existing master route RouteSignal by dropping our reference to it + master_route_signal.reset (); + // if appropriate, 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()) ); + master_route_signal.reset (new RouteSignal (mr, *this, master_strip(), mcu_port())); + route_connections.push_back (mr->GoingAway.connect (mem_fun (*this, &MackieControlProtocol::route_deleted))); // update strip from route master_route_signal->notify_all(); } @@ -559,30 +585,37 @@ void MackieControlProtocol::update_surface() update_smpte_beats_led(); } } +void +MackieControlProtocol::disconnect_session_signals () +{ + for (vector<sigc::connection>::iterator i = session_connections.begin(); i != session_connections.end(); ++i) { + (*i).disconnect (); + } + session_connections.clear (); +} -void MackieControlProtocol::connect_session_signals() +void +MackieControlProtocol::connect_session_signals() { // receive routes added - connections_back = session->RouteAdded.connect( ( mem_fun (*this, &MackieControlProtocol::notify_route_added) ) ); + session_connections.push_back (session->RouteAdded.connect (mem_fun (*this, &MackieControlProtocol::notify_route_added))); // receive record state toggled - connections_back = session->RecordStateChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_record_state_changed) ) ); + session_connections.push_back (session->RecordStateChanged.connect (mem_fun (*this, &MackieControlProtocol::notify_record_state_changed))); // receive transport state changed - connections_back = session->TransportStateChange.connect( ( mem_fun (*this, &MackieControlProtocol::notify_transport_state_changed) ) ); - // receive punch-in and punch-out - connections_back = Config->ParameterChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_parameter_changed) ) ); - // receive rude solo changed - connections_back = session->SoloActive.connect( ( mem_fun (*this, &MackieControlProtocol::notify_solo_active_changed) ) ); + session_connections.push_back (session->TransportStateChange.connect (mem_fun (*this, &MackieControlProtocol::notify_transport_state_changed))); + // receive rude solo changed + session_connections.push_back (session->SoloActive.connect (mem_fun (*this, &MackieControlProtocol::notify_solo_active_changed))); // make sure remote id changed signals reach here // see also notify_route_added Sorted sorted = get_sorted_routes(); - for ( Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it ) - { - connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) ); + for ( Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it ) { + session_connections.push_back ((*it)->RemoteControlIDChanged.connect (mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed))); } } -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; @@ -602,32 +635,18 @@ void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number ) MackiePort * sport = new MackiePort( *this, midi_port, number ); _ports.push_back( sport ); - connections_back = sport->init_event.connect( - sigc::bind ( - mem_fun (*this, &MackieControlProtocol::handle_port_init) - , sport - ) - ); - - connections_back = sport->active_event.connect( - sigc::bind ( - mem_fun (*this, &MackieControlProtocol::handle_port_active) - , sport - ) - ); - - connections_back = sport->inactive_event.connect( - sigc::bind ( - mem_fun (*this, &MackieControlProtocol::handle_port_inactive) - , sport - ) - ); + sport->init_event.connect(sigc::bind (mem_fun (*this, &MackieControlProtocol::handle_port_init), sport)); + + sport->active_event.connect(sigc::bind (mem_fun (*this, &MackieControlProtocol::handle_port_active) , sport)); + + sport->inactive_event.connect(sigc::bind (mem_fun (*this, &MackieControlProtocol::handle_port_inactive) , sport)); _ports_changed = true; } } -void MackieControlProtocol::create_ports() +void +MackieControlProtocol::create_ports() { MIDI::Manager * mm = MIDI::Manager::instance(); @@ -656,18 +675,21 @@ void MackieControlProtocol::create_ports() } } -shared_ptr<Route> MackieControlProtocol::master_route() +shared_ptr<Route> +MackieControlProtocol::master_route() { boost::shared_ptr<IO> mo = session->master_out (); return boost::dynamic_pointer_cast<Route>(mo); } -Strip & MackieControlProtocol::master_strip() +Strip & +MackieControlProtocol::master_strip() { return dynamic_cast<Strip&>( *surface().groups["master"] ); } -void MackieControlProtocol::initialize_surface() +void +MackieControlProtocol::initialize_surface() { // set up the route table int strips = 0; @@ -700,11 +722,12 @@ void MackieControlProtocol::initialize_surface() // Connect events. Must be after route table otherwise there will be trouble for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it ) { - connections_back = (*it)->control_event.connect( ( mem_fun (*this, &MackieControlProtocol::handle_control_event) ) ); + (*it)->control_event.connect (mem_fun (*this, &MackieControlProtocol::handle_control_event)); } } -void MackieControlProtocol::close() +void +MackieControlProtocol::close() { // stop polling, and wait for it... // must be before other shutdown otherwise polling loop @@ -715,37 +738,24 @@ void MackieControlProtocol::close() // TODO disconnect port active/inactive signals // Or at least put a lock here - // disconnect global signals from Session - // TODO Since *this is a sigc::trackable, this shouldn't be necessary - // but it is for some reason -#if 0 - for( vector<sigc::connection>::iterator it = _connections.begin(); it != _connections.end(); ++it ) - { - it->disconnect(); - } -#endif - - 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 ) - { + catch (exception & e) { #ifdef DEBUG cout << "MackieControlProtocol::close caught exception: " << e.what() << endl; #endif } - 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 ); @@ -754,40 +764,44 @@ void MackieControlProtocol::close() // Reset (reboot into offline mode) port.write_sysex( 0x63 ); } - catch ( exception & e ) - { + + catch ( exception & e ) { #ifdef DEBUG cout << "MackieControlProtocol::close caught exception: " << e.what() << endl; #endif } } - - // disconnect routes from strips - clear_route_signals(); - + delete _surface; _surface = 0; } + // disconnect routes from strips + clear_route_signals(); + // drop the route signal for the master route, if it exists + master_route_signal.reset (); + // drop per-session signal connections + disconnect_session_signals (); // 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; + delete [] pfd; pfd = 0; nfds = 0; } -void* MackieControlProtocol::_monitor_work (void* arg) +void* +MackieControlProtocol::_monitor_work (void* arg) { return static_cast<MackieControlProtocol*>(arg)->monitor_work (); } -XMLNode & MackieControlProtocol::get_state() +XMLNode & +MackieControlProtocol::get_state() { #ifdef DEBUG cout << "MackieControlProtocol::get_state" << endl; @@ -805,7 +819,8 @@ XMLNode & MackieControlProtocol::get_state() return *node; } -int MackieControlProtocol::set_state( const XMLNode & node ) +int +MackieControlProtocol::set_state( const XMLNode & node ) { #ifdef DEBUG cout << "MackieControlProtocol::set_state: active " << _active << endl; @@ -813,17 +828,14 @@ int MackieControlProtocol::set_state( const XMLNode & node ) int retval = 0; // fetch current bank - if ( node.property( X_("bank") ) != 0 ) - { + if (node.property( X_("bank") ) != 0) { string bank = node.property( X_("bank") )->value(); - try - { + 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 ) - { + catch ( exception & e ) { #ifdef DEBUG cout << "exception in MackieControlProtocol::set_state: " << e.what() << endl; #endif @@ -834,18 +846,15 @@ int MackieControlProtocol::set_state( const XMLNode & node ) 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 - { + } else { uint32_t index = control.ordinal() - 1 + ( port.number() * port.strips() ); if ( index < route_table.size() ) route = route_table[index]; @@ -857,8 +866,7 @@ 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 @@ -958,7 +966,8 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control & // 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 { @@ -971,7 +980,8 @@ void MackieControlProtocol::notify_solo_changed( RouteSignal * route_signal ) } } -void MackieControlProtocol::notify_mute_changed( RouteSignal * route_signal ) +void +MackieControlProtocol::notify_mute_changed( RouteSignal * route_signal ) { try { @@ -984,7 +994,8 @@ void MackieControlProtocol::notify_mute_changed( RouteSignal * route_signal ) } } -void MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_signal ) +void +MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_signal ) { try { @@ -997,7 +1008,8 @@ void MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_si } } -void MackieControlProtocol::notify_active_changed( RouteSignal * route_signal ) +void +MackieControlProtocol::notify_active_changed( RouteSignal * route_signal ) { try { @@ -1012,7 +1024,8 @@ void MackieControlProtocol::notify_active_changed( RouteSignal * route_signal ) } } -void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, bool force_update ) +void +MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, bool force_update ) { try { @@ -1034,7 +1047,8 @@ void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, boo } } -void MackieControlProtocol::notify_name_changed( void *, RouteSignal * route_signal ) +void +MackieControlProtocol::notify_name_changed( void *, RouteSignal * route_signal ) { try { @@ -1064,7 +1078,8 @@ void MackieControlProtocol::notify_name_changed( void *, RouteSignal * route_sig } } -void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, bool force_update ) +void +MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, bool force_update ) { try { @@ -1098,7 +1113,8 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, b } // TODO handle plugin automation polling -void MackieControlProtocol::update_automation( RouteSignal & rs ) +void +MackieControlProtocol::update_automation( RouteSignal & rs ) { ARDOUR::AutoState gain_state = rs.route()->gain_automation_state(); if ( gain_state == Touch || gain_state == Play ) @@ -1114,7 +1130,8 @@ void MackieControlProtocol::update_automation( RouteSignal & rs ) _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 ); @@ -1143,7 +1160,8 @@ string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame ) return os.str(); } -string MackieControlProtocol::format_smpte_timecode( nframes_t now_frame ) +string +MackieControlProtocol::format_smpte_timecode( nframes_t now_frame ) { SMPTE::Time smpte; session->smpte_time( now_frame, smpte ); @@ -1160,7 +1178,8 @@ string MackieControlProtocol::format_smpte_timecode( nframes_t now_frame ) return os.str(); } -void MackieControlProtocol::update_timecode_display() +void +MackieControlProtocol::update_timecode_display() { if ( surface().has_timecode_display() ) { @@ -1192,7 +1211,8 @@ void MackieControlProtocol::update_timecode_display() } } -void MackieControlProtocol::poll_session_data() +void +MackieControlProtocol::poll_session_data() { if ( _active && _automation_last.elapsed() >= 20 ) { @@ -1218,7 +1238,8 @@ void MackieControlProtocol::poll_session_data() // Transport Buttons ///////////////////////////////////// -LedState MackieControlProtocol::frm_left_press( Button & button ) +LedState +MackieControlProtocol::frm_left_press( Button & button ) { // can use first_mark_before/after as well unsigned long elapsed = _frm_left_last.restart(); @@ -1246,12 +1267,14 @@ LedState MackieControlProtocol::frm_left_press( Button & button ) return on; } -LedState MackieControlProtocol::frm_left_release( Button & button ) +LedState +MackieControlProtocol::frm_left_release( Button & button ) { return off; } -LedState MackieControlProtocol::frm_right_press( Button & button ) +LedState +MackieControlProtocol::frm_right_press( Button & button ) { // can use first_mark_before/after as well Location * loc = session->locations()->first_location_after ( @@ -1261,34 +1284,40 @@ LedState MackieControlProtocol::frm_right_press( Button & button ) return on; } -LedState MackieControlProtocol::frm_right_release( Button & button ) +LedState +MackieControlProtocol::frm_right_release( Button & button ) { return off; } -LedState MackieControlProtocol::stop_press( Button & button ) +LedState +MackieControlProtocol::stop_press( Button & button ) { session->request_stop(); return on; } -LedState MackieControlProtocol::stop_release( Button & button ) +LedState +MackieControlProtocol::stop_release( Button & button ) { return session->transport_stopped(); } -LedState MackieControlProtocol::play_press( Button & button ) +LedState +MackieControlProtocol::play_press( Button & button ) { session->request_transport_speed( 1.0 ); return on; } -LedState MackieControlProtocol::play_release( Button & button ) +LedState +MackieControlProtocol::play_release( Button & button ) { return session->transport_rolling(); } -LedState MackieControlProtocol::record_press( Button & button ) +LedState +MackieControlProtocol::record_press( Button & button ) { if ( session->get_record_enabled() ) session->disable_record( false ); @@ -1297,7 +1326,8 @@ LedState MackieControlProtocol::record_press( Button & button ) return on; } -LedState MackieControlProtocol::record_release( Button & button ) +LedState +MackieControlProtocol::record_release( Button & button ) { if ( session->get_record_enabled() ) { @@ -1310,7 +1340,8 @@ LedState MackieControlProtocol::record_release( Button & button ) return off; } -LedState MackieControlProtocol::rewind_press( Button & button ) +LedState +MackieControlProtocol::rewind_press( Button & button ) { _jog_wheel.push( JogWheel::speed ); _jog_wheel.transport_direction( -1 ); @@ -1318,7 +1349,8 @@ LedState MackieControlProtocol::rewind_press( Button & button ) return on; } -LedState MackieControlProtocol::rewind_release( Button & button ) +LedState +MackieControlProtocol::rewind_release( Button & button ) { _jog_wheel.pop(); _jog_wheel.transport_direction( 0 ); @@ -1329,7 +1361,8 @@ LedState MackieControlProtocol::rewind_release( Button & button ) return off; } -LedState MackieControlProtocol::ffwd_press( Button & button ) +LedState +MackieControlProtocol::ffwd_press( Button & button ) { _jog_wheel.push( JogWheel::speed ); _jog_wheel.transport_direction( 1 ); @@ -1337,7 +1370,8 @@ LedState MackieControlProtocol::ffwd_press( Button & button ) return on; } -LedState MackieControlProtocol::ffwd_release( Button & button ) +LedState +MackieControlProtocol::ffwd_release( Button & button ) { _jog_wheel.pop(); _jog_wheel.transport_direction( 0 ); @@ -1348,83 +1382,97 @@ LedState MackieControlProtocol::ffwd_release( Button & button ) return off; } -LedState MackieControlProtocol::loop_press( Button & button ) +LedState +MackieControlProtocol::loop_press( Button & button ) { session->request_play_loop( !session->get_play_loop() ); return on; } -LedState MackieControlProtocol::loop_release( Button & button ) +LedState +MackieControlProtocol::loop_release( Button & button ) { return session->get_play_loop(); } -LedState MackieControlProtocol::punch_in_press( Button & button ) +LedState +MackieControlProtocol::punch_in_press( Button & button ) { bool state = !Config->get_punch_in(); Config->set_punch_in( state ); return state; } -LedState MackieControlProtocol::punch_in_release( Button & button ) +LedState +MackieControlProtocol::punch_in_release( Button & button ) { return Config->get_punch_in(); } -LedState MackieControlProtocol::punch_out_press( Button & button ) +LedState +MackieControlProtocol::punch_out_press( Button & button ) { bool state = !Config->get_punch_out(); Config->set_punch_out( state ); return state; } -LedState MackieControlProtocol::punch_out_release( Button & button ) +LedState +MackieControlProtocol::punch_out_release( Button & button ) { return Config->get_punch_out(); } -LedState MackieControlProtocol::home_press( Button & button ) +LedState +MackieControlProtocol::home_press( Button & button ) { session->goto_start(); return on; } -LedState MackieControlProtocol::home_release( Button & button ) +LedState +MackieControlProtocol::home_release( Button & button ) { return off; } -LedState MackieControlProtocol::end_press( Button & button ) +LedState +MackieControlProtocol::end_press( Button & button ) { session->goto_end(); return on; } -LedState MackieControlProtocol::end_release( Button & button ) +LedState +MackieControlProtocol::end_release( Button & button ) { return off; } -LedState MackieControlProtocol::clicking_press( Button & button ) +LedState +MackieControlProtocol::clicking_press( Button & button ) { bool state = !Config->get_clicking(); Config->set_clicking( state ); return state; } -LedState MackieControlProtocol::clicking_release( Button & button ) +LedState +MackieControlProtocol::clicking_release( Button & button ) { return Config->get_clicking(); } -LedState MackieControlProtocol::global_solo_press( Button & button ) +LedState +MackieControlProtocol::global_solo_press( Button & button ) { bool state = !session->soloing(); session->set_all_solo ( state ); return state; } -LedState MackieControlProtocol::global_solo_release( Button & button ) +LedState +MackieControlProtocol::global_solo_release( Button & button ) { return session->soloing(); } @@ -1433,7 +1481,8 @@ LedState MackieControlProtocol::global_solo_release( Button & button ) // Session signals /////////////////////////////////////////// -void MackieControlProtocol::notify_parameter_changed( const char * name_str ) +void +MackieControlProtocol::notify_parameter_changed( const char * name_str ) { string name( name_str ); if ( name == "punch-in" ) @@ -1457,31 +1506,35 @@ void MackieControlProtocol::notify_parameter_changed( const char * name_str ) } // RouteList is the set of routes that have just been added -void MackieControlProtocol::notify_route_added( ARDOUR::Session::RouteList & rl ) +void +MackieControlProtocol::notify_route_added( ARDOUR::Session::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(); } + // otherwise route added, but current bank needs no updating // make sure remote id changes in the new route are handled + typedef ARDOUR::Session::RouteList ARS; - for ( ARS::iterator it = rl.begin(); it != rl.end(); ++it ) - { - connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) ); + for ( ARS::iterator it = rl.begin(); it != rl.end(); ++it ) { + session_connections.push_back ((*it)->RemoteControlIDChanged.connect (( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed)))); } } -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 ) ); } -void MackieControlProtocol::notify_remote_id_changed() +void +MackieControlProtocol::notify_remote_id_changed() { Sorted sorted = get_sorted_routes(); @@ -1503,14 +1556,16 @@ 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 ) ) ); } -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() ); @@ -1527,7 +1582,8 @@ void MackieControlProtocol::notify_transport_state_changed() ///////////////////////////////////// // Bank Switching ///////////////////////////////////// -LedState MackieControlProtocol::left_press( Button & button ) +LedState +MackieControlProtocol::left_press( Button & button ) { Sorted sorted = get_sorted_routes(); if ( sorted.size() > route_table.size() ) @@ -1548,12 +1604,14 @@ LedState MackieControlProtocol::left_press( Button & button ) } } -LedState MackieControlProtocol::left_release( Button & button ) +LedState +MackieControlProtocol::left_release( Button & button ) { return off; } -LedState MackieControlProtocol::right_press( Button & button ) +LedState +MackieControlProtocol::right_press( Button & button ) { Sorted sorted = get_sorted_routes(); if ( sorted.size() > route_table.size() ) @@ -1574,12 +1632,14 @@ LedState MackieControlProtocol::right_press( Button & button ) } } -LedState MackieControlProtocol::right_release( Button & button ) +LedState +MackieControlProtocol::right_release( Button & button ) { return off; } -LedState MackieControlProtocol::channel_left_press( Button & button ) +LedState +MackieControlProtocol::channel_left_press( Button & button ) { Sorted sorted = get_sorted_routes(); if ( sorted.size() > route_table.size() ) @@ -1593,12 +1653,14 @@ LedState MackieControlProtocol::channel_left_press( Button & button ) } } -LedState MackieControlProtocol::channel_left_release( Button & button ) +LedState +MackieControlProtocol::channel_left_release( Button & button ) { return off; } -LedState MackieControlProtocol::channel_right_press( Button & button ) +LedState +MackieControlProtocol::channel_right_press( Button & button ) { Sorted sorted = get_sorted_routes(); if ( sorted.size() > route_table.size() ) @@ -1612,7 +1674,8 @@ LedState MackieControlProtocol::channel_right_press( Button & button ) } } -LedState MackieControlProtocol::channel_right_release( Button & button ) +LedState +MackieControlProtocol::channel_right_release( Button & button ) { return off; } @@ -1620,7 +1683,8 @@ LedState MackieControlProtocol::channel_right_release( Button & button ) ///////////////////////////////////// // Functions ///////////////////////////////////// -LedState MackieControlProtocol::marker_press( Button & button ) +LedState +MackieControlProtocol::marker_press( Button & button ) { // cut'n'paste from LocationUI::add_new_location() string markername; @@ -1636,7 +1700,8 @@ LedState MackieControlProtocol::marker_press( Button & button ) return on; } -LedState MackieControlProtocol::marker_release( Button & button ) +LedState +MackieControlProtocol::marker_release( Button & button ) { return off; } @@ -1654,7 +1719,8 @@ void jog_wheel_state_display( JogWheel::State state, SurfacePort & port ) } } -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 ); @@ -1662,12 +1728,14 @@ Mackie::LedState MackieControlProtocol::zoom_press( Mackie::Button & ) 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 ); @@ -1679,7 +1747,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 @@ -1688,29 +1757,34 @@ Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & ) ; } -LedState MackieControlProtocol::drop_press( Button & button ) +LedState +MackieControlProtocol::drop_press( Button & button ) { session->remove_last_capture(); return on; } -LedState MackieControlProtocol::drop_release( Button & button ) +LedState +MackieControlProtocol::drop_release( Button & button ) { return off; } -LedState MackieControlProtocol::save_press( Button & button ) +LedState +MackieControlProtocol::save_press( Button & button ) { session->save_state( "" ); return on; } -LedState MackieControlProtocol::save_release( Button & button ) +LedState +MackieControlProtocol::save_release( Button & button ) { return off; } -LedState MackieControlProtocol::smpte_beats_press( Button & ) +LedState +MackieControlProtocol::smpte_beats_press( Button & ) { switch ( _timecode_type ) { @@ -1729,7 +1803,8 @@ LedState MackieControlProtocol::smpte_beats_press( Button & ) return on; } -LedState MackieControlProtocol::smpte_beats_release( Button & ) +LedState +MackieControlProtocol::smpte_beats_release( Button & ) { return off; } diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index d93f9c4c02..94b2a70742 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -49,32 +49,31 @@ namespace Mackie { } /** - This handles the plugin duties, and the midi encoding and decoding, - and the signal callbacks, mostly from ARDOUR::Route. - - The model of the control surface is handled by classes in controls.h - - What happens is that each strip on the control surface has - a corresponding route in ControlProtocol::route_table. When - an incoming midi message is signaled, the correct route - is looked up, and the relevant changes made to it. - - For each route currently in route_table, there's a RouteSignal object - which encapsulates the signals that indicate that there are changes - to be sent to the surface. The signals are handled by this class. - - Calls to signal handlers pass a Route object which is used to look - up the relevant Strip in Surface. Then the state is retrieved from - the Route and encoded as the correct midi message. + This handles the plugin duties, and the midi encoding and decoding, + and the signal callbacks, mostly from ARDOUR::Route. + + The model of the control surface is handled by classes in controls.h + + What happens is that each strip on the control surface has + a corresponding route in ControlProtocol::route_table. When + an incoming midi message is signaled, the correct route + is looked up, and the relevant changes made to it. + + For each route currently in route_table, there's a RouteSignal object + which encapsulates the signals that indicate that there are changes + to be sent to the surface. The signals are handled by this class. + + Calls to signal handlers pass a Route object which is used to look + 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 & ); virtual ~MackieControlProtocol(); - + int set_active (bool yn); XMLNode& get_state (); @@ -84,10 +83,10 @@ class MackieControlProtocol Mackie::Surface & surface(); - // control events - void handle_control_event( Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state ); - - // strip/route related stuff + // control events + void handle_control_event( Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state ); + + // strip/route related stuff public: /// Signal handler for Route::solo void notify_solo_changed( Mackie::RouteSignal * ); @@ -109,35 +108,35 @@ class MackieControlProtocol 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_transport_state_changed(); + // mainly to pick up punch-in and punch-out void notify_parameter_changed( const char * ); - void notify_solo_active_changed( bool ); - + void notify_solo_active_changed( bool ); + /// Turn smpte on and beats off, or vice versa, depending /// on state of _timecode_type void update_smpte_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_global_button( const std::string & name, Mackie::LedState ); void update_global_led( const std::string & name, Mackie::LedState ); - - // transport button handler methods from MackieButtonHandler + + // 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 stop_press( Mackie::Button & ); virtual Mackie::LedState stop_release( Mackie::Button & ); @@ -207,7 +206,7 @@ class MackieControlProtocol 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(); @@ -226,44 +225,52 @@ 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(); + + // disconnect all connections made in connect_session_signals () + std::vector<sigc::connection> session_connections; + void disconnect_session_signals (); + + // handle deletion of a route + std::vector<sigc::connection> route_connections; + void route_deleted (); + + // 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(); - - // delete all RouteSignal objects connecting Routes to Strips - void clear_route_signals(); - typedef std::vector<Mackie::RouteSignal*> RouteSignals; + // 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(); + + typedef std::list<Mackie::RouteSignal*> RouteSignals; RouteSignals route_signals; - // return which of the ports a particular route_table - // index belongs to + // 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); @@ -282,9 +289,9 @@ class MackieControlProtocol 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(); @@ -298,9 +305,9 @@ class MackieControlProtocol std::string format_smpte_timecode( 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 * ); @@ -316,7 +323,7 @@ class MackieControlProtocol 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 vector<Mackie::MackiePort*> MackiePorts; @@ -325,23 +332,20 @@ 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 + // 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, and polling structures Glib::Mutex update_mutex; /// Protects set_active, and allows waiting on the poll thread Glib::Cond update_cond; - // because sigc::trackable doesn't seem to be working - std::vector<sigc::connection> _connections; - std::back_insert_iterator<std::vector<sigc::connection> > connections_back; - /// The representation of the physical controls on the surface. + /// The representation of the physical controls on the surface. Mackie::Surface * _surface; /// If a port is opened or closed, this will be |