mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
substantial overhaul of MCU code - no more separate thread, just connect to signals on ports already listened to by the MidiUI thread in libardour (feedback is missing - needs a timeout connection); also reformat some big chunks of code to fit ardour coding style
git-svn-id: svn://localhost/ardour2/branches/3.0@6377 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
aae367b63c
commit
96cd6c993b
5 changed files with 728 additions and 942 deletions
|
|
@ -228,7 +228,7 @@ public:
|
||||||
virtual unsigned int in_use_timeout() { return _in_use_timeout; }
|
virtual unsigned int in_use_timeout() { return _in_use_timeout; }
|
||||||
|
|
||||||
/// Keep track of the timeout so it can be updated with more incoming events
|
/// 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:
|
private:
|
||||||
int _id;
|
int _id;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,20 +1,21 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2006,2007 John Anderson
|
Copyright (C) 2006,2007 John Anderson
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
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.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ardour_mackie_control_protocol_h
|
#ifndef ardour_mackie_control_protocol_h
|
||||||
#define ardour_mackie_control_protocol_h
|
#define ardour_mackie_control_protocol_h
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@
|
||||||
#include <glibmm/thread.h>
|
#include <glibmm/thread.h>
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
#include "ardour/midi_ui.h"
|
||||||
#include "midi++/types.h"
|
#include "midi++/types.h"
|
||||||
|
|
||||||
#include "control_protocol/control_protocol.h"
|
#include "control_protocol/control_protocol.h"
|
||||||
|
|
@ -40,7 +42,6 @@
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
class Port;
|
class Port;
|
||||||
class Parser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Mackie {
|
namespace Mackie {
|
||||||
|
|
@ -66,12 +67,13 @@ namespace Mackie {
|
||||||
up the relevant Strip in Surface. Then the state is retrieved from
|
up the relevant Strip in Surface. Then the state is retrieved from
|
||||||
the Route and encoded as the correct midi message.
|
the Route and encoded as the correct midi message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class MackieControlProtocol
|
class MackieControlProtocol
|
||||||
: public ARDOUR::ControlProtocol
|
: public ARDOUR::ControlProtocol
|
||||||
, public Mackie::MackieButtonHandler
|
, public Mackie::MackieButtonHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MackieControlProtocol( ARDOUR::Session & );
|
MackieControlProtocol(ARDOUR::Session &);
|
||||||
virtual ~MackieControlProtocol();
|
virtual ~MackieControlProtocol();
|
||||||
|
|
||||||
int set_active (bool yn);
|
int set_active (bool yn);
|
||||||
|
|
@ -83,130 +85,131 @@ class MackieControlProtocol
|
||||||
|
|
||||||
Mackie::Surface & surface();
|
Mackie::Surface & surface();
|
||||||
|
|
||||||
// control events
|
// control events
|
||||||
void handle_control_event( Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state );
|
void handle_control_event(Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state);
|
||||||
|
|
||||||
// strip/route related stuff
|
// strip/route related stuff
|
||||||
public:
|
public:
|
||||||
/// Signal handler for Route::solo
|
/// Signal handler for Route::solo
|
||||||
void notify_solo_changed( Mackie::RouteSignal * );
|
void notify_solo_changed(Mackie::RouteSignal *);
|
||||||
/// Signal handler for Route::mute
|
/// Signal handler for Route::mute
|
||||||
void notify_mute_changed( Mackie::RouteSignal * );
|
void notify_mute_changed(Mackie::RouteSignal *);
|
||||||
/// Signal handler for Route::record_enable_changed
|
/// Signal handler for Route::record_enable_changed
|
||||||
void notify_record_enable_changed( Mackie::RouteSignal * );
|
void notify_record_enable_changed(Mackie::RouteSignal *);
|
||||||
/// Signal handler for Route::gain_changed ( from IO )
|
/// Signal handler for Route::gain_changed (from IO)
|
||||||
void notify_gain_changed( Mackie::RouteSignal *, bool force_update = true );
|
void notify_gain_changed(Mackie::RouteSignal *, bool force_update = true);
|
||||||
/// Signal handler for Route::name_change
|
/// Signal handler for Route::name_change
|
||||||
void notify_name_changed( Mackie::RouteSignal * );
|
void notify_name_changed(Mackie::RouteSignal *);
|
||||||
/// Signal handler from Panner::Change
|
/// 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
|
/// Signal handler for new routes added
|
||||||
void notify_route_added( ARDOUR::RouteList & );
|
void notify_route_added(ARDOUR::RouteList &);
|
||||||
/// Signal handler for Route::active_changed
|
/// Signal handler for Route::active_changed
|
||||||
void notify_active_changed( Mackie::RouteSignal * );
|
void notify_active_changed(Mackie::RouteSignal *);
|
||||||
|
|
||||||
void notify_remote_id_changed();
|
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.
|
/// remote id changed.
|
||||||
void refresh_current_bank();
|
void refresh_current_bank();
|
||||||
|
|
||||||
// global buttons (ie button not part of strips)
|
// global buttons (ie button not part of strips)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// button-related signals
|
// button-related signals
|
||||||
void notify_record_state_changed();
|
void notify_record_state_changed();
|
||||||
void notify_transport_state_changed();
|
void notify_transport_state_changed();
|
||||||
// mainly to pick up punch-in and punch-out
|
// mainly to pick up punch-in and punch-out
|
||||||
void notify_parameter_changed( std::string const & );
|
void notify_parameter_changed(std::string const &);
|
||||||
void notify_solo_active_changed( bool );
|
void notify_solo_active_changed(bool);
|
||||||
|
|
||||||
/// Turn timecode on and beats off, or vice versa, depending
|
/// Turn timecode on and beats off, or vice versa, depending
|
||||||
/// on state of _timecode_type
|
/// on state of _timecode_type
|
||||||
void update_timecode_beats_led();
|
void update_timecode_beats_led();
|
||||||
|
|
||||||
/// this is called to generate the midi to send in response to a button press.
|
/// 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_button(const std::string & name, Mackie::LedState);
|
||||||
void update_global_led( 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_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState frm_left_release( Mackie::Button & );
|
virtual Mackie::LedState frm_left_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState frm_right_press( Mackie::Button & );
|
virtual Mackie::LedState frm_right_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState frm_right_release( Mackie::Button & );
|
virtual Mackie::LedState frm_right_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState stop_press( Mackie::Button & );
|
virtual Mackie::LedState stop_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState stop_release( Mackie::Button & );
|
virtual Mackie::LedState stop_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState play_press( Mackie::Button & );
|
virtual Mackie::LedState play_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState play_release( Mackie::Button & );
|
virtual Mackie::LedState play_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState record_press( Mackie::Button & );
|
virtual Mackie::LedState record_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState record_release( Mackie::Button & );
|
virtual Mackie::LedState record_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState loop_press( Mackie::Button & );
|
virtual Mackie::LedState loop_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState loop_release( Mackie::Button & );
|
virtual Mackie::LedState loop_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState punch_in_press( Mackie::Button & );
|
virtual Mackie::LedState punch_in_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState punch_in_release( Mackie::Button & );
|
virtual Mackie::LedState punch_in_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState punch_out_press( Mackie::Button & );
|
virtual Mackie::LedState punch_out_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState punch_out_release( Mackie::Button & );
|
virtual Mackie::LedState punch_out_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState home_press( Mackie::Button & );
|
virtual Mackie::LedState home_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState home_release( Mackie::Button & );
|
virtual Mackie::LedState home_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState end_press( Mackie::Button & );
|
virtual Mackie::LedState end_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState end_release( Mackie::Button & );
|
virtual Mackie::LedState end_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState rewind_press( Mackie::Button & button );
|
virtual Mackie::LedState rewind_press(Mackie::Button & button);
|
||||||
virtual Mackie::LedState rewind_release( Mackie::Button & button );
|
virtual Mackie::LedState rewind_release(Mackie::Button & button);
|
||||||
|
|
||||||
virtual Mackie::LedState ffwd_press( Mackie::Button & button );
|
virtual Mackie::LedState ffwd_press(Mackie::Button & button);
|
||||||
virtual Mackie::LedState ffwd_release( Mackie::Button & button );
|
virtual Mackie::LedState ffwd_release(Mackie::Button & button);
|
||||||
|
|
||||||
// bank switching button handler methods from MackieButtonHandler
|
// bank switching button handler methods from MackieButtonHandler
|
||||||
virtual Mackie::LedState left_press( Mackie::Button & );
|
virtual Mackie::LedState left_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState left_release( Mackie::Button & );
|
virtual Mackie::LedState left_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState right_press( Mackie::Button & );
|
virtual Mackie::LedState right_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState right_release( Mackie::Button & );
|
virtual Mackie::LedState right_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState channel_left_press( Mackie::Button & );
|
virtual Mackie::LedState channel_left_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState channel_left_release( Mackie::Button & );
|
virtual Mackie::LedState channel_left_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState channel_right_press( Mackie::Button & );
|
virtual Mackie::LedState channel_right_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState channel_right_release( Mackie::Button & );
|
virtual Mackie::LedState channel_right_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState clicking_press( Mackie::Button & );
|
virtual Mackie::LedState clicking_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState clicking_release( Mackie::Button & );
|
virtual Mackie::LedState clicking_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState global_solo_press( Mackie::Button & );
|
virtual Mackie::LedState global_solo_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState global_solo_release( Mackie::Button & );
|
virtual Mackie::LedState global_solo_release(Mackie::Button &);
|
||||||
|
|
||||||
// function buttons
|
// function buttons
|
||||||
virtual Mackie::LedState marker_press( Mackie::Button & );
|
virtual Mackie::LedState marker_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState marker_release( Mackie::Button & );
|
virtual Mackie::LedState marker_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState drop_press( Mackie::Button & );
|
virtual Mackie::LedState drop_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState drop_release( Mackie::Button & );
|
virtual Mackie::LedState drop_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState save_press( Mackie::Button & );
|
virtual Mackie::LedState save_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState save_release( Mackie::Button & );
|
virtual Mackie::LedState save_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState timecode_beats_press( Mackie::Button & );
|
virtual Mackie::LedState timecode_beats_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState timecode_beats_release( Mackie::Button & );
|
virtual Mackie::LedState timecode_beats_release(Mackie::Button &);
|
||||||
|
|
||||||
// jog wheel states
|
// jog wheel states
|
||||||
virtual Mackie::LedState zoom_press( Mackie::Button & );
|
virtual Mackie::LedState zoom_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState zoom_release( Mackie::Button & );
|
virtual Mackie::LedState zoom_release(Mackie::Button &);
|
||||||
|
|
||||||
virtual Mackie::LedState scrub_press( Mackie::Button & );
|
virtual Mackie::LedState scrub_press(Mackie::Button &);
|
||||||
virtual Mackie::LedState scrub_release( 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
|
/// Only for use by JogWheel
|
||||||
const Mackie::SurfacePort & mcu_port() const;
|
const Mackie::SurfacePort & mcu_port() const;
|
||||||
Mackie::SurfacePort & mcu_port();
|
Mackie::SurfacePort & mcu_port();
|
||||||
|
|
@ -225,89 +228,74 @@ class MackieControlProtocol
|
||||||
void initialize_surface();
|
void initialize_surface();
|
||||||
|
|
||||||
// This sets up the notifications and sets the
|
// This sets up the notifications and sets the
|
||||||
// controls to the correct values
|
// controls to the correct values
|
||||||
void update_surface();
|
void update_surface();
|
||||||
|
|
||||||
// connects global (not strip) signals from the Session to here
|
// connects global (not strip) signals from the Session to here
|
||||||
// so the surface can be notified of changes from the other UIs.
|
// so the surface can be notified of changes from the other UIs.
|
||||||
void connect_session_signals();
|
void connect_session_signals();
|
||||||
|
|
||||||
// set all controls to their zero position
|
// set all controls to their zero position
|
||||||
void zero_all();
|
void zero_all();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetch the set of routes to be considered for control by the
|
Fetch the set of routes to be considered for control by the
|
||||||
surface. Excluding master, hidden and control routes, and inactive routes
|
surface. Excluding master, hidden and control routes, and inactive routes
|
||||||
*/
|
*/
|
||||||
typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
|
typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
|
||||||
Sorted get_sorted_routes();
|
Sorted get_sorted_routes();
|
||||||
|
|
||||||
// bank switching
|
// bank switching
|
||||||
void switch_banks( int initial );
|
void switch_banks(int initial);
|
||||||
void prev_track();
|
void prev_track();
|
||||||
void next_track();
|
void next_track();
|
||||||
|
|
||||||
// delete all RouteSignal objects connecting Routes to Strips
|
// delete all RouteSignal objects connecting Routes to Strips
|
||||||
void clear_route_signals();
|
void clear_route_signals();
|
||||||
|
|
||||||
typedef std::vector<Mackie::RouteSignal*> RouteSignals;
|
typedef std::vector<Mackie::RouteSignal*> RouteSignals;
|
||||||
RouteSignals route_signals;
|
RouteSignals route_signals;
|
||||||
|
|
||||||
// return which of the ports a particular route_table
|
// return which of the ports a particular route_table
|
||||||
// index belongs to
|
// index belongs to
|
||||||
Mackie::MackiePort & port_for_id( uint32_t index );
|
Mackie::MackiePort & port_for_id(uint32_t index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Handle a button press for the control and return whether
|
Handle a button press for the control and return whether
|
||||||
the corresponding light should be on or off.
|
the corresponding light should be on or off.
|
||||||
*/
|
*/
|
||||||
bool handle_strip_button( Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route> );
|
bool handle_strip_button(Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
|
||||||
|
|
||||||
/// thread started. Calls monitor_work.
|
void add_port(MIDI::Port &, int number);
|
||||||
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 );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Read session data and send to surface. Includes
|
Read session data and send to surface. Includes
|
||||||
automation from the currently active routes and
|
automation from the currently active routes and
|
||||||
timecode displays.
|
timecode displays.
|
||||||
*/
|
*/
|
||||||
void poll_session_data();
|
void poll_session_data();
|
||||||
|
|
||||||
// called from poll_automation to figure out which automations need to be sent
|
// 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
|
// also called from poll_automation to update timecode display
|
||||||
void update_timecode_display();
|
void update_timecode_display();
|
||||||
|
|
||||||
std::string format_bbt_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 );
|
std::string format_timecode_timecode (ARDOUR::nframes_t now_frame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
notification that the port is about to start it's init sequence.
|
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
|
We must make sure that before this exits, the port is being polled
|
||||||
for new data.
|
for new data.
|
||||||
*/
|
*/
|
||||||
void handle_port_init( Mackie::SurfacePort * );
|
void handle_port_init(Mackie::SurfacePort *);
|
||||||
|
|
||||||
/// notification from a MackiePort that it's now active
|
/// 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
|
/// 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();
|
boost::shared_ptr<ARDOUR::Route> master_route();
|
||||||
Mackie::Strip & master_strip();
|
Mackie::Strip & master_strip();
|
||||||
|
|
@ -315,7 +303,7 @@ class MackieControlProtocol
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<Mackie::RouteSignal> master_route_signal;
|
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
|
/// The Midi port(s) connected to the units
|
||||||
typedef std::vector<Mackie::MackiePort*> MackiePorts;
|
typedef std::vector<Mackie::MackiePort*> MackiePorts;
|
||||||
|
|
@ -324,18 +312,12 @@ class MackieControlProtocol
|
||||||
/// Sometimes the real port goes away, and we want to contain the breakage
|
/// Sometimes the real port goes away, and we want to contain the breakage
|
||||||
Mackie::DummyPort _dummy_port;
|
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.
|
/// 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;
|
Glib::Mutex update_mutex;
|
||||||
|
|
||||||
/// Protects set_active, and allows waiting on the poll thread
|
|
||||||
Glib::Cond update_cond;
|
|
||||||
|
|
||||||
PBD::ScopedConnectionList session_connections;
|
PBD::ScopedConnectionList session_connections;
|
||||||
PBD::ScopedConnectionList port_connections;
|
PBD::ScopedConnectionList port_connections;
|
||||||
PBD::ScopedConnectionList route_connections;
|
PBD::ScopedConnectionList route_connections;
|
||||||
|
|
@ -343,14 +325,6 @@ class MackieControlProtocol
|
||||||
/// The representation of the physical controls on the surface.
|
/// The representation of the physical controls on the surface.
|
||||||
Mackie::Surface * _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;
|
bool _transport_previously_rolling;
|
||||||
|
|
||||||
// timer for two quick marker left presses
|
// timer for two quick marker left presses
|
||||||
|
|
@ -358,9 +332,6 @@ class MackieControlProtocol
|
||||||
|
|
||||||
Mackie::JogWheel _jog_wheel;
|
Mackie::JogWheel _jog_wheel;
|
||||||
|
|
||||||
// Timer for controlling midi bandwidth used by automation polls
|
|
||||||
Mackie::Timer _automation_last;
|
|
||||||
|
|
||||||
// last written timecode string
|
// last written timecode string
|
||||||
std::string _timecode_last;
|
std::string _timecode_last;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,151 +29,14 @@ const char * MackieControlProtocol::default_port_name = "mcu";
|
||||||
|
|
||||||
bool MackieControlProtocol::probe()
|
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;
|
info << "Mackie: No MIDI port called " << default_port_name << endmsg;
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
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 )
|
void MackieControlProtocol::handle_port_inactive( SurfacePort * port )
|
||||||
{
|
{
|
||||||
// port gone away. So stop polling it ASAP
|
// port gone away. So stop polling it ASAP
|
||||||
|
|
@ -187,8 +50,6 @@ void MackieControlProtocol::handle_port_inactive( SurfacePort * port )
|
||||||
_ports.erase( it );
|
_ports.erase( it );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ports_changed = true;
|
|
||||||
update_ports();
|
|
||||||
|
|
||||||
// TODO all the rebuilding of surfaces and so on
|
// TODO all the rebuilding of surfaces and so on
|
||||||
}
|
}
|
||||||
|
|
@ -219,8 +80,6 @@ void MackieControlProtocol::handle_port_init (Mackie::SurfacePort *)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "MackieControlProtocol::handle_port_init" << endl;
|
cout << "MackieControlProtocol::handle_port_init" << endl;
|
||||||
#endif
|
#endif
|
||||||
_ports_changed = true;
|
|
||||||
update_ports();
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "MackieControlProtocol::handle_port_init finish" << endl;
|
cout << "MackieControlProtocol::handle_port_init finish" << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include "midi++/types.h"
|
#include "midi++/types.h"
|
||||||
#include "midi++/port.h"
|
#include "midi++/port.h"
|
||||||
|
|
||||||
|
#include "ardour/debug.h"
|
||||||
#include "ardour/rc_configuration.h"
|
#include "ardour/rc_configuration.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
@ -37,6 +39,7 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Mackie;
|
using namespace Mackie;
|
||||||
|
using namespace ARDOUR;
|
||||||
|
|
||||||
// The MCU sysex header
|
// The MCU sysex header
|
||||||
MidiByteArray mackie_sysex_hdr ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10 );
|
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 );
|
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 )
|
MackiePort::MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int number, port_type_t port_type )
|
||||||
: SurfacePort( port, number )
|
: SurfacePort( port, number )
|
||||||
, _mcp( mcp )
|
, _mcp( mcp )
|
||||||
, _port_type( port_type )
|
, _port_type( port_type )
|
||||||
, _emulation( none )
|
, _emulation( none )
|
||||||
, _initialising( true )
|
, _initialising( true )
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::MackiePort\n");
|
||||||
cout << "MackiePort::MackiePort" <<endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MackiePort::~MackiePort()
|
MackiePort::~MackiePort()
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::~MackiePort\n");
|
||||||
cout << "~MackiePort" << endl;
|
|
||||||
#endif
|
|
||||||
close();
|
close();
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "~MackiePort finished\n");
|
||||||
cout << "~MackiePort finished" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MackiePort::strips() const
|
int MackiePort::strips() const
|
||||||
|
|
@ -91,9 +88,8 @@ int MackiePort::strips() const
|
||||||
// should really be in MackiePort
|
// should really be in MackiePort
|
||||||
void MackiePort::open()
|
void MackiePort::open()
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::open %1\n", *this));
|
||||||
cout << "MackiePort::open " << *this << endl;
|
|
||||||
#endif
|
|
||||||
port().input()->sysex.connect (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
|
port().input()->sysex.connect (sysex_connection, boost::bind (&MackiePort::handle_midi_sysex, this, _1, _2, _3));
|
||||||
|
|
||||||
// make sure the device is connected
|
// make sure the device is connected
|
||||||
|
|
@ -102,18 +98,13 @@ void MackiePort::open()
|
||||||
|
|
||||||
void MackiePort::close()
|
void MackiePort::close()
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::close\n");
|
||||||
cout << "MackiePort::close" << endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// disconnect signals
|
// disconnect signals
|
||||||
any_connection.disconnect();
|
any_connection.disconnect();
|
||||||
sysex_connection.disconnect();
|
sysex_connection.disconnect();
|
||||||
|
|
||||||
// TODO emit a "closing" signal?
|
// TODO emit a "closing" signal?
|
||||||
#ifdef PORT_DEBUG
|
|
||||||
cout << "MackiePort::close finished" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MidiByteArray & MackiePort::sysex_hdr() const
|
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 )
|
MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
|
||||||
{
|
{
|
||||||
// handle host connection query
|
// handle host connection query
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host connection query: %1\n", bytes));
|
||||||
cout << "host connection query: " << bytes << endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( bytes.size() != 18 )
|
if ( bytes.size() != 18 )
|
||||||
{
|
{
|
||||||
|
|
@ -172,9 +161,7 @@ MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
|
||||||
// not used right now
|
// not used right now
|
||||||
MidiByteArray MackiePort::host_connection_confirmation( const MidiByteArray & bytes )
|
MidiByteArray MackiePort::host_connection_confirmation( const MidiByteArray & bytes )
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host_connection_confirmation: %1\n", bytes));
|
||||||
cout << "host_connection_confirmation: " << bytes << endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// decode host connection confirmation
|
// decode host connection confirmation
|
||||||
if ( bytes.size() != 14 )
|
if ( bytes.size() != 14 )
|
||||||
|
|
@ -213,15 +200,13 @@ void MackiePort::probe_emulation (const MidiByteArray &)
|
||||||
|
|
||||||
void MackiePort::init()
|
void MackiePort::init()
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::init\n");
|
||||||
cout << "MackiePort::init" << endl;
|
|
||||||
#endif
|
|
||||||
init_mutex.lock();
|
init_mutex.lock();
|
||||||
_initialising = true;
|
_initialising = true;
|
||||||
|
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::init lock acquired\n");
|
||||||
cout << "MackiePort::init lock acquired" << endl;
|
|
||||||
#endif
|
|
||||||
// emit pre-init signal
|
// emit pre-init signal
|
||||||
init_event();
|
init_event();
|
||||||
|
|
||||||
|
|
@ -237,9 +222,8 @@ void MackiePort::init()
|
||||||
|
|
||||||
void MackiePort::finalise_init( bool yn )
|
void MackiePort::finalise_init( bool yn )
|
||||||
{
|
{
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::finalise_init\n");
|
||||||
cout << "MackiePort::finalise_init" << endl;
|
|
||||||
#endif
|
|
||||||
bool emulation_ok = false;
|
bool emulation_ok = false;
|
||||||
|
|
||||||
// probing doesn't work very well, so just use a config variable
|
// 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 );
|
SurfacePort::active( yn );
|
||||||
|
|
||||||
if ( yn )
|
if (yn) {
|
||||||
{
|
|
||||||
active_event();
|
active_event();
|
||||||
|
|
||||||
// start handling messages from controls
|
// start handling messages from controls
|
||||||
connect_any();
|
connect_any();
|
||||||
}
|
}
|
||||||
|
|
||||||
_initialising = false;
|
_initialising = false;
|
||||||
init_cond.signal();
|
init_cond.signal();
|
||||||
init_mutex.unlock();
|
init_mutex.unlock();
|
||||||
#ifdef PORT_DEBUG
|
|
||||||
cout << "MackiePort::finalise_init lock released" << endl;
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::finalise_init lock released\n");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MackiePort::connect_any()
|
void MackiePort::connect_any()
|
||||||
|
|
@ -296,44 +279,36 @@ void MackiePort::connect_any()
|
||||||
bool MackiePort::wait_for_init()
|
bool MackiePort::wait_for_init()
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock( init_mutex );
|
Glib::Mutex::Lock lock( init_mutex );
|
||||||
while ( _initialising )
|
while (_initialising) {
|
||||||
{
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active waiting\n");
|
||||||
#ifdef PORT_DEBUG
|
|
||||||
cout << "MackiePort::wait_for_active waiting" << endl;
|
|
||||||
#endif
|
|
||||||
init_cond.wait( init_mutex );
|
init_cond.wait( init_mutex );
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active released\n");
|
||||||
cout << "MackiePort::wait_for_active released" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active returning\n");
|
||||||
cout << "MackiePort::wait_for_active returning" << endl;
|
|
||||||
#endif
|
|
||||||
return SurfacePort::active();
|
return SurfacePort::active();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
|
void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
|
||||||
{
|
{
|
||||||
MidiByteArray bytes( count, raw_bytes );
|
MidiByteArray bytes( count, raw_bytes );
|
||||||
#ifdef PORT_DEBUG
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handle_midi_sysex: %1\n", bytes));
|
||||||
cout << "handle_midi_sysex: " << bytes << endl;
|
|
||||||
#endif
|
|
||||||
switch( bytes[5] )
|
switch( bytes[5] )
|
||||||
{
|
{
|
||||||
case 0x01:
|
case 0x01:
|
||||||
// not used right now
|
// not used right now
|
||||||
write_sysex( host_connection_query( bytes ) );
|
write_sysex (host_connection_query (bytes));
|
||||||
break;
|
break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
// not used right now
|
// not used right now
|
||||||
write_sysex( host_connection_confirmation( bytes ) );
|
write_sysex (host_connection_confirmation (bytes));
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
inactive_event();
|
inactive_event ();
|
||||||
cout << "host connection error" << bytes << endl;
|
cout << "host connection error" << bytes << endl;
|
||||||
break;
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
probe_emulation( bytes );
|
probe_emulation (bytes);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cout << "unknown sysex: " << bytes << endl;
|
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.
|
// Don't instantiate a MidiByteArray here unless it's needed for exceptions.
|
||||||
// Reason being that this method is called for every single incoming
|
// Reason being that this method is called for every single incoming
|
||||||
// midi event, and it needs to be as efficient as possible.
|
// midi event, and it needs to be as efficient as possible.
|
||||||
|
|
||||||
Control * control = 0;
|
Control * control = 0;
|
||||||
MIDI::byte midi_type = bytes[0] & 0xf0; //0b11110000
|
MIDI::byte midi_type = bytes[0] & 0xf0; //0b11110000
|
||||||
switch( midi_type )
|
|
||||||
{
|
switch (midi_type) {
|
||||||
// fader
|
// fader
|
||||||
case MackieMidiBuilder::midi_fader_id:
|
case MackieMidiBuilder::midi_fader_id:
|
||||||
{
|
{
|
||||||
|
|
@ -413,18 +389,16 @@ bool MackiePort::handle_control_timeout_event ( Control * control )
|
||||||
// because they have similar logic flows.
|
// because they have similar logic flows.
|
||||||
void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
|
void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
|
||||||
MidiByteArray bytes( count, raw_bytes );
|
MidiByteArray bytes( count, raw_bytes );
|
||||||
cout << "MackiePort::handle_midi_any " << bytes << endl;
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::handle_midi_any %1\n", bytes));
|
||||||
#endif
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// ignore sysex messages
|
// ignore sysex messages
|
||||||
if ( raw_bytes[0] == MIDI::sysex ) return;
|
if ( raw_bytes[0] == MIDI::sysex ) return;
|
||||||
|
|
||||||
// sanity checking
|
// sanity checking
|
||||||
if ( count != 3 )
|
if (count != 3) {
|
||||||
{
|
|
||||||
ostringstream os;
|
ostringstream os;
|
||||||
MidiByteArray mba( count, raw_bytes );
|
MidiByteArray mba( count, raw_bytes );
|
||||||
os << "MackiePort::handle_midi_any needs 3 bytes, but received " << mba;
|
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
|
// This handles incoming bytes. Outgoing bytes
|
||||||
// are sent by the signal handlers.
|
// are sent by the signal handlers.
|
||||||
switch ( control.type() )
|
switch (control.type()) {
|
||||||
{
|
|
||||||
// fader
|
// fader
|
||||||
case 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
|
// first disconnect any previous timeouts
|
||||||
control.in_use_connection.disconnect();
|
control.in_use_connection.disconnect();
|
||||||
|
|
||||||
#if 0 // BOOSTSIGNALS
|
|
||||||
// now connect a new timeout to call handle_control_timeout_event
|
// now connect a new timeout to call handle_control_timeout_event
|
||||||
sigc::slot<bool> timeout_slot = sigc::bind (
|
// XXX should this use the GUI event loop (default) or the
|
||||||
mem_fun( *this, &MackiePort::handle_control_timeout_event )
|
// MIDI UI event loop ?
|
||||||
, &control
|
|
||||||
);
|
sigc::slot<bool> timeout_slot = sigc::bind
|
||||||
control.in_use_connection = Glib::signal_timeout().connect(
|
(sigc::mem_fun( *this, &MackiePort::handle_control_timeout_event), &control);
|
||||||
timeout_slot
|
|
||||||
, control.in_use_timeout()
|
control.in_use_connection = Glib::signal_timeout().connect (timeout_slot , control.in_use_timeout());
|
||||||
);
|
|
||||||
#endif
|
|
||||||
// emit the control event
|
// emit the control event
|
||||||
control_event( *this, control, state );
|
control_event( *this, control, state );
|
||||||
break;
|
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;
|
cerr << "Do not understand control type " << control;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( MackieControlException & e )
|
|
||||||
{
|
catch( MackieControlException & e ) {
|
||||||
MidiByteArray bytes( count, raw_bytes );
|
MidiByteArray bytes( count, raw_bytes );
|
||||||
cout << bytes << ' ' << e.what() << endl;
|
cout << bytes << ' ' << e.what() << endl;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "finished MackiePort::handle_midi_any " << bytes << endl;
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("finished MackiePort::handle_midi_any %1\n", bytes));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue