#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;
int set_active (bool yn);
XMLNode& get_state ();
- int set_state (const XMLNode&);
+ int set_state (const XMLNode&, int version);
static bool probe();
// 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();
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 & );
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 & );
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();
// 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;
*/
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.
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();
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;
/// 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