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
|
|
@ -15,6 +15,7 @@
|
||||||
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,6 +67,7 @@ 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
|
||||||
|
|
@ -112,6 +114,7 @@ class MackieControlProtocol
|
||||||
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();
|
||||||
|
|
@ -263,21 +266,6 @@ class MackieControlProtocol
|
||||||
*/
|
*/
|
||||||
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.
|
|
||||||
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);
|
void add_port(MIDI::Port &, int number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -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 );
|
||||||
|
|
@ -51,20 +54,14 @@ MackiePort::MackiePort( MackieControlProtocol & mcp, MIDI::Port & port, int numb
|
||||||
, _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,28 +279,20 @@ 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:
|
||||||
|
|
@ -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