Fix angle bracket project-local include paths.
[ardour.git] / libs / surfaces / mackie / mackie_control_protocol.h
index 4116264c56ddde7025d479e0c66da8c4e0131620..1a6412667a3812bdecba7a4c57dd837162cb2a8a 100644 (file)
 
 #include <glibmm/thread.h>
 
-#include <ardour/types.h>
-#include <ardour/session.h>
-#include <midi++/types.h>
+#include "ardour/types.h"
+#include "ardour/session.h"
+#include "midi++/types.h"
 
-#include <control_protocol/control_protocol.h>
+#include "control_protocol/control_protocol.h"
 #include "midi_byte_array.h"
 #include "controls.h"
+#include "dummy_port.h"
 #include "route_signal.h"
 #include "mackie_button_handler.h"
 #include "mackie_port.h"
+#include "mackie_jog_wheel.h"
+#include "timer.h"
 
 namespace MIDI {
        class Port;
@@ -75,7 +78,7 @@ class MackieControlProtocol
        int set_active (bool yn);
 
        XMLNode& get_state ();
-       int set_state (const XMLNode&);
+       int set_state (const XMLNode&, int version);
   
        static bool probe();
        
@@ -87,21 +90,25 @@ class MackieControlProtocol
   // strip/route related stuff
   public:      
        /// Signal handler for Route::solo
-       void notify_solo_changed( ARDOUR::Route *, Mackie::MackiePort * );
+       void notify_solo_changed( Mackie::RouteSignal * );
        /// Signal handler for Route::mute
-       void notify_mute_changed( ARDOUR::Route *, Mackie::MackiePort * );
+       void notify_mute_changed( Mackie::RouteSignal * );
        /// Signal handler for Route::record_enable_changed
-       void notify_record_enable_changed( ARDOUR::Route *, Mackie::MackiePort * );
+       void notify_record_enable_changed( Mackie::RouteSignal * );
        /// Signal handler for Route::gain_changed ( from IO )
-       void notify_gain_changed( ARDOUR::Route *, Mackie::MackiePort * );
+       void notify_gain_changed( Mackie::RouteSignal *, bool force_update = true );
        /// Signal handler for Route::name_change
-       void notify_name_changed( void *, ARDOUR::Route *, Mackie::MackiePort * );
+       void notify_name_changed( Mackie::RouteSignal * );
        /// Signal handler from Panner::Change
-       void notify_panner_changed( ARDOUR::Route *, Mackie::MackiePort * );
+       void notify_panner_changed( Mackie::RouteSignal *, bool force_update = true );
        /// Signal handler for new routes added
-       void notify_route_added( ARDOUR::Session::RouteList & );
+       void notify_route_added( ARDOUR::RouteList & );
+       /// Signal handler for Route::active_changed
+       void notify_active_changed( Mackie::RouteSignal * );
+       void notify_remote_id_changed();
 
-   /// rebuild the current bank. Called on route added/removed and
+       /// rebuild the current bank. Called on route added/removed and
    /// remote id changed.
        void refresh_current_bank();
 
@@ -111,22 +118,25 @@ class MackieControlProtocol
        void notify_record_state_changed();
    void notify_transport_state_changed();
    // mainly to pick up punch-in and punch-out
-       void notify_parameter_changed( const char * );
+       void notify_parameter_changed( std::string const & );
    void notify_solo_active_changed( bool );
 
-       // this is called to generate the midi to send in response to
-   // a button press.
+       /// 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 );
   
-       // calls update_led, but looks up the button by name
        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 rewind_press( Mackie::Button & );
-       virtual Mackie::LedState rewind_release( Mackie::Button & );
+       virtual Mackie::LedState frm_left_press( Mackie::Button & );
+       virtual Mackie::LedState frm_left_release( Mackie::Button & );
 
-       virtual Mackie::LedState ffwd_press( Mackie::Button & );
-       virtual Mackie::LedState ffwd_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 & );
@@ -152,7 +162,13 @@ class MackieControlProtocol
        virtual Mackie::LedState end_press( Mackie::Button & );
        virtual Mackie::LedState end_release( Mackie::Button & );
        
-   // bank switching button handler methods from MackieButtonHandler
+       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 );
+
+       // bank switching button handler methods from MackieButtonHandler
        virtual Mackie::LedState left_press( Mackie::Button & );
        virtual Mackie::LedState left_release( Mackie::Button & );
 
@@ -165,6 +181,38 @@ class MackieControlProtocol
        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 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 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 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 scrub_press( Mackie::Button & );
+       virtual Mackie::LedState scrub_release( Mackie::Button & );
+       
+   /// 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();
+       ARDOUR::Session & get_session() { return *session; }
   protected:
        // create instances of MackiePort, depending on what's found in ardour.rc
        void create_ports();
@@ -203,10 +251,6 @@ class MackieControlProtocol
    // delete all RouteSignal objects connecting Routes to Strips
    void clear_route_signals();
        
-   /// This is the main MCU port, ie not an extender port
-       const Mackie::MackiePort & mcu_port() const;
-       Mackie::MackiePort & mcu_port();
        typedef std::vector<Mackie::RouteSignal*> RouteSignals;
        RouteSignals route_signals;
        
@@ -220,26 +264,38 @@ class MackieControlProtocol
        */
        bool handle_strip_button( Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route> );
 
-       // Polling midi port(s) for incoming messages
+       /// 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();
 
        void add_port( MIDI::Port &, int number );
-       
+
        /**
-               used by the notify_XXX methods to find
-               a strip corresponding to the Route passed in.
+               Read session data and send to surface. Includes
+               automation from the currently active routes and
+               timecode displays.
        */
-       Mackie::Strip & strip_from_route( ARDOUR::Route * route );
+       void poll_session_data();
+       
+       // called from poll_automation to figure out which automations need to be sent
+       void update_automation( Mackie::RouteSignal & );
        
-       /// notification from the MackiePorts that their status has changed
-       void handle_port_changed( Mackie::SurfacePort *, bool active );
+       // 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 );
        
        /**
                notification that the port is about to start it's init sequence.
@@ -247,6 +303,12 @@ class MackieControlProtocol
                for new data.
        */
        void handle_port_init( Mackie::SurfacePort * );
+
+       /// notification from a MackiePort that it's now active
+       void handle_port_active( Mackie::SurfacePort * );
+       
+       /// notification from a MackiePort that it's now inactive
+       void handle_port_inactive( Mackie::SurfacePort * );
        
        boost::shared_ptr<ARDOUR::Route> master_route();
        Mackie::Strip & master_strip();
@@ -257,9 +319,12 @@ class MackieControlProtocol
    static const char * default_port_name;
   
        /// The Midi port(s) connected to the units
-       typedef vector<Mackie::MackiePort*> MackiePorts;
+       typedef std::vector<Mackie::MackiePort*> MackiePorts;
        MackiePorts _ports;
   
+       /// 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;
   
@@ -283,8 +348,25 @@ class MackieControlProtocol
        /// 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
+       Mackie::Timer _frm_left_last;
+       
+       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;
+       
+       // Which timecode are we displaying? BBT or Timecode
+       ARDOUR::AnyTime::Type _timecode_type;
 };
 
 #endif // ardour_mackie_control_protocol_h