summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Anderson <ardour@semiosix.com>2007-03-09 20:46:46 +0000
committerJohn Anderson <ardour@semiosix.com>2007-03-09 20:46:46 +0000
commit7182cd75e367ad97f978827c1bf4f875b46c6776 (patch)
tree9f459271570fc2937af2234b861021b79e2484e0
parent765d0f4785d1bf6a82c7acc19eebdf851fc305a5 (diff)
Stop trying to talk to device on startup. Remap some bcf buttons.
git-svn-id: svn://localhost/ardour2/trunk@1568 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/surfaces/mackie/TODO3
-rw-r--r--libs/surfaces/mackie/bcf_surface.cc89
-rw-r--r--libs/surfaces/mackie/interface.cc38
-rw-r--r--libs/surfaces/mackie/mackie_button_handler.cc20
-rw-r--r--libs/surfaces/mackie/mackie_button_handler.h5
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc55
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h19
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol_poll.cc113
-rw-r--r--libs/surfaces/mackie/mackie_port.cc53
-rw-r--r--libs/surfaces/mackie/scripts/bcf-controls.csv24
-rwxr-xr-xlibs/surfaces/mackie/scripts/generate-surface.rb9
-rwxr-xr-xlibs/surfaces/mackie/scripts/host.rb11
-rw-r--r--libs/surfaces/mackie/surface_port.cc39
13 files changed, 291 insertions, 187 deletions
diff --git a/libs/surfaces/mackie/TODO b/libs/surfaces/mackie/TODO
index 534ee4f64c..903a8bb23d 100644
--- a/libs/surfaces/mackie/TODO
+++ b/libs/surfaces/mackie/TODO
@@ -3,8 +3,7 @@
if the handler is not called in the "correct thread", it will use a pseudo-RT-safe-enough technique to get the correct thread to recall "handler" later on, and return.
* jog with transport rolling doesn't work properly. My use of ScrollTimeline also doesn't work.
-* finish button mapping. Click on/off. start/end locate. punch in/out
-* discuss button mapping for Ardour
+* finish button mapping.
* concurrency for bank switching? And make sure "old" events aren't sent to "new" faders
* TODOs in code
* removal of a route results in a strip that isn't dead, but doesn't have any effect on the session
diff --git a/libs/surfaces/mackie/bcf_surface.cc b/libs/surfaces/mackie/bcf_surface.cc
index 6390582bd7..2aaa70fc3e 100644
--- a/libs/surfaces/mackie/bcf_surface.cc
+++ b/libs/surfaces/mackie/bcf_surface.cc
@@ -405,29 +405,29 @@ void Mackie::BcfSurface::init_controls()
group->add( *control );
group = groups["assignment"];
- control = new Button ( 41, 1, "sends", *group );
- buttons[0x29] = control;
+ control = new Button ( 90, 1, "sends", *group );
+ buttons[0x5a] = control;
controls.push_back( control );
controls_by_name["sends"] = control;
group->add( *control );
group = groups["assignment"];
- control = new Button ( 42, 1, "pan", *group );
- buttons[0x2a] = control;
+ control = new Button ( 89, 1, "pan", *group );
+ buttons[0x59] = control;
controls.push_back( control );
controls_by_name["pan"] = control;
group->add( *control );
group = groups["assignment"];
- control = new Button ( 43, 1, "plugin", *group );
- buttons[0x2b] = control;
+ control = new Button ( 87, 1, "plugin", *group );
+ buttons[0x57] = control;
controls.push_back( control );
controls_by_name["plugin"] = control;
group->add( *control );
group = groups["assignment"];
- control = new Button ( 44, 1, "eq", *group );
- buttons[0x2c] = control;
+ control = new Button ( 88, 1, "eq", *group );
+ buttons[0x58] = control;
controls.push_back( control );
controls_by_name["eq"] = control;
group->add( *control );
@@ -475,8 +475,8 @@ void Mackie::BcfSurface::init_controls()
group->add( *control );
group = groups["none"];
- control = new Button ( 51, 1, "edit", *group );
- buttons[0x33] = control;
+ control = new Button ( 86, 1, "edit", *group );
+ buttons[0x56] = control;
controls.push_back( control );
controls_by_name["edit"] = control;
group->add( *control );
@@ -607,11 +607,11 @@ void Mackie::BcfSurface::init_controls()
controls_by_name["F16"] = control;
group->add( *control );
- group = groups["modifiers"];
- control = new Button ( 70, 1, "shift", *group );
- buttons[0x46] = control;
+ group = groups["none"];
+ control = new Button ( 39, 1, "global_solo", *group );
+ buttons[0x27] = control;
controls.push_back( control );
- controls_by_name["shift"] = control;
+ controls_by_name["global_solo"] = control;
group->add( *control );
group = groups["modifiers"];
@@ -720,36 +720,36 @@ void Mackie::BcfSurface::init_controls()
group->add( *control );
group = groups["transport"];
- control = new Button ( 86, 1, "loop", *group );
- buttons[0x56] = control;
+ control = new Button ( 70, 1, "loop", *group );
+ buttons[0x46] = control;
controls.push_back( control );
controls_by_name["loop"] = control;
group->add( *control );
group = groups["transport"];
- control = new Button ( 87, 1, "punch_in", *group );
- buttons[0x57] = control;
+ control = new Button ( 44, 1, "punch_in", *group );
+ buttons[0x2c] = control;
controls.push_back( control );
controls_by_name["punch_in"] = control;
group->add( *control );
group = groups["transport"];
- control = new Button ( 88, 1, "punch_out", *group );
- buttons[0x58] = control;
+ control = new Button ( 43, 1, "punch_out", *group );
+ buttons[0x2b] = control;
controls.push_back( control );
controls_by_name["punch_out"] = control;
group->add( *control );
group = groups["transport"];
- control = new Button ( 89, 1, "home", *group );
- buttons[0x59] = control;
+ control = new Button ( 42, 1, "home", *group );
+ buttons[0x2a] = control;
controls.push_back( control );
controls_by_name["home"] = control;
group->add( *control );
group = groups["transport"];
- control = new Button ( 90, 1, "end", *group );
- buttons[0x5a] = control;
+ control = new Button ( 41, 1, "end", *group );
+ buttons[0x29] = control;
controls.push_back( control );
controls_by_name["end"] = control;
group->add( *control );
@@ -900,6 +900,13 @@ void Mackie::BcfSurface::init_controls()
group->add( *control );
group = groups["none"];
+ control = new Button ( 51, 1, "clicking", *group );
+ buttons[0x33] = control;
+ controls.push_back( control );
+ controls_by_name["clicking"] = control;
+ group->add( *control );
+
+ group = groups["none"];
control = new Led ( 113, 1, "smpte", *group );
leds[0x71] = control;
controls.push_back( control );
@@ -949,7 +956,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x29: // sends
+ case 0x5a: // sends
switch ( bs ) {
case press: ls = mbh.sends_press( button ); break;
case release: ls = mbh.sends_release( button ); break;
@@ -957,7 +964,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x2a: // pan
+ case 0x59: // pan
switch ( bs ) {
case press: ls = mbh.pan_press( button ); break;
case release: ls = mbh.pan_release( button ); break;
@@ -965,7 +972,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x2b: // plugin
+ case 0x57: // plugin
switch ( bs ) {
case press: ls = mbh.plugin_press( button ); break;
case release: ls = mbh.plugin_release( button ); break;
@@ -973,7 +980,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x2c: // eq
+ case 0x58: // eq
switch ( bs ) {
case press: ls = mbh.eq_press( button ); break;
case release: ls = mbh.eq_release( button ); break;
@@ -1029,7 +1036,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x33: // edit
+ case 0x56: // edit
switch ( bs ) {
case press: ls = mbh.edit_press( button ); break;
case release: ls = mbh.edit_release( button ); break;
@@ -1181,10 +1188,10 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x46: // shift
+ case 0x27: // global_solo
switch ( bs ) {
- case press: ls = mbh.shift_press( button ); break;
- case release: ls = mbh.shift_release( button ); break;
+ case press: ls = mbh.global_solo_press( button ); break;
+ case release: ls = mbh.global_solo_release( button ); break;
case neither: break;
}
break;
@@ -1309,7 +1316,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x56: // loop
+ case 0x46: // loop
switch ( bs ) {
case press: ls = mbh.loop_press( button ); break;
case release: ls = mbh.loop_release( button ); break;
@@ -1317,7 +1324,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x57: // punch_in
+ case 0x2c: // punch_in
switch ( bs ) {
case press: ls = mbh.punch_in_press( button ); break;
case release: ls = mbh.punch_in_release( button ); break;
@@ -1325,7 +1332,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x58: // punch_out
+ case 0x2b: // punch_out
switch ( bs ) {
case press: ls = mbh.punch_out_press( button ); break;
case release: ls = mbh.punch_out_release( button ); break;
@@ -1333,7 +1340,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x59: // home
+ case 0x2a: // home
switch ( bs ) {
case press: ls = mbh.home_press( button ); break;
case release: ls = mbh.home_release( button ); break;
@@ -1341,7 +1348,7 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
- case 0x5a: // end
+ case 0x29: // end
switch ( bs ) {
case press: ls = mbh.end_press( button ); break;
case release: ls = mbh.end_release( button ); break;
@@ -1453,6 +1460,14 @@ void Mackie::BcfSurface::handle_button( MackieButtonHandler & mbh, ButtonState b
}
break;
+ case 0x33: // clicking
+ switch ( bs ) {
+ case press: ls = mbh.clicking_press( button ); break;
+ case release: ls = mbh.clicking_release( button ); break;
+ case neither: break;
+ }
+ break;
+
}
mbh.update_led( button, ls );
}
diff --git a/libs/surfaces/mackie/interface.cc b/libs/surfaces/mackie/interface.cc
index 500854fe71..eda485b5d6 100644
--- a/libs/surfaces/mackie/interface.cc
+++ b/libs/surfaces/mackie/interface.cc
@@ -18,27 +18,47 @@
#include <control_protocol/control_protocol.h>
#include "mackie_control_protocol.h"
+#include <pbd/error.h>
+
#include <stdexcept>
using namespace ARDOUR;
+using namespace PBD;
using namespace std;
ControlProtocol*
new_mackie_protocol (ControlProtocolDescriptor* descriptor, Session* s)
{
- MackieControlProtocol * mcp = 0;
- try
+ if ( Config->get_mmc_port_name().substr(0,3) == "mcu" )
+ {
+ error << "mcu already used as mmc port" << endmsg;
+ }
+ else if ( Config->get_mtc_port_name().substr(0,3) == "mcu" )
+ {
+ error << "mcu already used as mtc port" << endmsg;
+ }
+ else if ( Config->get_midi_port_name().substr(0,3) == "mcu" )
{
- mcp = new MackieControlProtocol (*s);
- mcp->set_active( true );
+ error << "mcu already used as midi port" << endmsg;
}
- catch( exception & e )
+ else
{
- cout << "Error instantiating MackieControlProtocol: " << e.what() << endl;
- delete mcp;
- mcp = 0;
+ // no one else is using the port, so try instantiate the object
+ MackieControlProtocol * mcp = 0;
+ try
+ {
+ mcp = new MackieControlProtocol (*s);
+ mcp->set_active( true );
+ }
+ catch( exception & e )
+ {
+ error << "Error instantiating MackieControlProtocol: " << e.what() << endmsg;
+ delete mcp;
+ mcp = 0;
+ }
+ return mcp;
}
- return mcp;
+ return 0;
}
void
diff --git a/libs/surfaces/mackie/mackie_button_handler.cc b/libs/surfaces/mackie/mackie_button_handler.cc
index e1cd9f9153..f7ac2ab6d5 100644
--- a/libs/surfaces/mackie/mackie_button_handler.cc
+++ b/libs/surfaces/mackie/mackie_button_handler.cc
@@ -20,7 +20,6 @@ LedState MackieButtonHandler::default_button_release( Button & button )
return off;
}
-
LedState MackieButtonHandler::io_press( Button & button )
{
return default_button_press( button );
@@ -671,3 +670,22 @@ LedState MackieButtonHandler::fader_touch_release( Button & button )
return default_button_release( button );
}
+LedState MackieButtonHandler::clicking_press( Button & button )
+{
+ return default_button_press( button );
+}
+
+LedState MackieButtonHandler::clicking_release( Button & button )
+{
+ return default_button_press( button );
+}
+
+LedState MackieButtonHandler::global_solo_press( Button & button )
+{
+ return default_button_press( button );
+}
+
+LedState MackieButtonHandler::global_solo_release( Button & button )
+{
+ return default_button_press( button );
+}
diff --git a/libs/surfaces/mackie/mackie_button_handler.h b/libs/surfaces/mackie/mackie_button_handler.h
index a07e98b2fd..ee4187c7ce 100644
--- a/libs/surfaces/mackie/mackie_button_handler.h
+++ b/libs/surfaces/mackie/mackie_button_handler.h
@@ -215,6 +215,11 @@ public:
virtual LedState fader_touch_press( Button & );
virtual LedState fader_touch_release( Button & );
+ virtual LedState clicking_press( Button & );
+ virtual LedState clicking_release( Button & );
+
+ virtual LedState global_solo_press( Button & );
+ virtual LedState global_solo_release( Button & );
};
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 26fd15e777..0eff534f63 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -117,6 +117,7 @@ MackieControlProtocol::~MackieControlProtocol()
{
cout << "~MackieControlProtocol caught unknown" << endl;
}
+ cout << "finished ~MackieControlProtocol::MackieControlProtocol" << endl;
}
Mackie::Surface & MackieControlProtocol::surface()
@@ -370,6 +371,9 @@ int MackieControlProtocol::set_active (bool yn)
create_ports();
}
+ // make sure the ports are being listened to
+ update_ports();
+
// wait until poll thread is running, with ports to poll
// the mutex is only there because conditions require a mutex
{
@@ -402,6 +406,7 @@ int MackieControlProtocol::set_active (bool yn)
// send current control positions to surface
// must come after _active = true otherwise it won't run
+ cout << "update_surface in set_active" << endl;
update_surface();
}
else
@@ -555,17 +560,15 @@ void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
connections_back = sport->active_event.connect(
sigc::bind (
- mem_fun (*this, &MackieControlProtocol::handle_port_changed)
+ mem_fun (*this, &MackieControlProtocol::handle_port_active)
, sport
- , true
)
);
connections_back = sport->inactive_event.connect(
sigc::bind (
- mem_fun (*this, &MackieControlProtocol::handle_port_changed)
+ mem_fun (*this, &MackieControlProtocol::handle_port_inactive)
, sport
- , false
)
);
@@ -895,29 +898,11 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
}
}
-/////////////////////////////////////////////////////////
-// Notifications from UI
-/////////////////////////////////////////////////////////
-struct RouteSignalByRoute
-{
- RouteSignalByRoute( Route & route ): _route( route ) {}
-
- bool operator () ( const RouteSignal & rs ) const
- {
- return rs.route().id() == _route.id();
- }
-
- bool operator () ( const RouteSignal * rs ) const
- {
- return rs->route().id() == _route.id();
- }
-
- Route & _route;
-};
-
/////////////////////////////////////////////////
// handlers for Route signals
// TODO should these be part of RouteSignal?
+// They started off as sigc handlers for signals
+// from Route, but they're also used in polling for automation
/////////////////////////////////////////////////
void MackieControlProtocol::notify_solo_changed( RouteSignal * route_signal )
@@ -1038,7 +1023,7 @@ void MackieControlProtocol::poll_automation()
}
// and the master strip
- update_automation( *master_route_signal );
+ if ( master_route_signal != 0 ) update_automation( *master_route_signal );
}
}
@@ -1135,6 +1120,14 @@ void MackieControlProtocol::notify_parameter_changed( const char * name_str )
{
update_global_button( "punch_out", Config->get_punch_out() );
}
+ else if ( name == "clicking" )
+ {
+ update_global_button( "clicking", Config->get_clicking() );
+ }
+ else
+ {
+ cout << "parameter changed: " << name << endl;
+ }
}
// RouteList is the set of routes that have just been added
@@ -1260,6 +1253,18 @@ LedState MackieControlProtocol::end_release( Button & button )
return off;
}
+LedState MackieControlProtocol::clicking_press( Button & button )
+{
+ bool state = !Config->get_clicking();
+ Config->set_clicking( state );
+ return state;
+}
+
+LedState MackieControlProtocol::clicking_release( Button & button )
+{
+ return Config->get_clicking();
+}
+
/////////////////////////////////////
// Bank Switching
/////////////////////////////////////
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 64a75f2ee6..ffaf368c9c 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -167,6 +167,9 @@ 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 & );
+
protected:
// create instances of MackiePort, depending on what's found in ardour.rc
void create_ports();
@@ -222,13 +225,18 @@ 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();
@@ -240,15 +248,18 @@ class MackieControlProtocol
// 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 );
-
/**
notification that the port is about to start it's init sequence.
We must make sure that before this exits, the port is being polled
for new data.
*/
void handle_port_init( Mackie::SurfacePort * );
+
+ /// 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();
diff --git a/libs/surfaces/mackie/mackie_control_protocol_poll.cc b/libs/surfaces/mackie/mackie_control_protocol_poll.cc
index ebbb292f63..875b19705e 100644
--- a/libs/surfaces/mackie/mackie_control_protocol_poll.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol_poll.cc
@@ -34,49 +34,39 @@ bool MackieControlProtocol::probe()
void * MackieControlProtocol::monitor_work()
{
- cout << "MackieControlProtocol::monitor_work" << endl;
// What does ThreadCreatedWithRequestSize do?
PBD::ThreadCreated (pthread_self(), X_("Mackie"));
-#if 0
- // it seems to do the "block" on poll less often
- // with this code disabled
- struct sched_param rtparam;
- memset (&rtparam, 0, sizeof (rtparam));
- rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
-
- int err;
- if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
- // do we care? not particularly.
- PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror( errno )) << endmsg;
- }
-#endif
-
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
// read from midi ports
- cout << "start poll cycle" << endl;
while ( true )
{
- update_ports();
- if ( poll_ports() )
+ try
{
- try { read_ports(); }
- catch ( exception & e ) {
- cout << "MackieControlProtocol::poll_ports caught exception: " << e.what() << endl;
- _ports_changed = true;
- update_ports();
+ 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 automation data from the routes
+ poll_automation();
}
+ catch ( exception & e )
+ {
+ cout << "caught exception in MackieControlProtocol::monitor_work " << e.what() << endl;
+ }
+
// provide a cancellation point
pthread_testcancel();
-
- // poll for automation data from the routes
- poll_automation();
}
- // these never get called
+ // these never get called because of cancellation point above
cout << "MackieControlProtocol::poll_ports exiting" << endl;
delete[] pfd;
@@ -86,16 +76,14 @@ void * MackieControlProtocol::monitor_work()
void MackieControlProtocol::update_ports()
{
- // create pollfd structures if necessary
if ( _ports_changed )
{
- cout << "MackieControlProtocol::update_ports changed 1" << endl;
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
if ( _ports_changed )
{
- cout << "MackieControlProtocol::update_ports updating" << endl;
+ // create new pollfd structures
if ( pfd != 0 ) delete[] pfd;
// TODO This might be a memory leak. How does thread cancellation cleanup work?
pfd = new pollfd[_ports.size()];
@@ -110,9 +98,7 @@ void MackieControlProtocol::update_ports()
}
_ports_changed = false;
}
- cout << "MackieControlProtocol::update_ports signalling" << endl;
update_cond.signal();
- cout << "MackieControlProtocol::update_ports finished" << endl;
}
}
@@ -125,9 +111,11 @@ void MackieControlProtocol::read_ports()
// this will cause handle_midi_any in the MackiePort to be triggered
if ( pfd[p].revents & POLLIN > 0 )
{
- lock.release();
+ // avoid deadlocking?
+ // doesn't seem to make a difference
+ //lock.release();
_ports[p]->read();
- lock.acquire();
+ //lock.acquire();
}
}
}
@@ -161,36 +149,42 @@ bool MackieControlProtocol::poll_ports()
return retval > 0;
}
-void MackieControlProtocol::handle_port_changed( SurfacePort * port, bool active )
+void MackieControlProtocol::handle_port_inactive( SurfacePort * port )
{
- cout << "MackieControlProtocol::handle_port_changed port: " << *port << " active: " << active << endl;
- if ( active == false )
+ // port gone away. So stop polling it ASAP
{
- // port gone away. So stop polling it ASAP
+ // delete the port instance
+ Glib::Mutex::Lock lock( update_mutex );
+ MackiePorts::iterator it = find( _ports.begin(), _ports.end(), port );
+ if ( it != _ports.end() )
{
- // delete the port instance
- Glib::Mutex::Lock lock( update_mutex );
- MackiePorts::iterator it = find( _ports.begin(), _ports.end(), port );
- if ( it != _ports.end() )
- {
- delete *it;
- _ports.erase( it );
- }
+ delete *it;
+ _ports.erase( it );
}
- _ports_changed = true;
- update_ports();
- }
- else
- {
- _ports_changed = true;
- // port added
- update_ports();
- update_surface();
-
- // TODO update bank size
-
- // rebuild surface
}
+ _ports_changed = true;
+ update_ports();
+
+ // TODO all the rebuilding of surfaces and so on
+}
+
+void MackieControlProtocol::handle_port_active( SurfacePort * port )
+{
+ // no need to re-add port because it was already added
+ // during the init phase. So just update the local surface
+ // representation and send the representation to
+ // all existing ports
+
+ // TODO update bank size
+
+ // TODO rebuild surface, to have new units
+
+ // finally update session state to the surface
+ // TODO but this is also done in set_active, and
+ // in fact update_surface won't execute unless
+ // _active == true
+ cout << "update_surface in handle_port_active" << endl;
+ update_surface();
}
void MackieControlProtocol::handle_port_init( Mackie::SurfacePort * sport )
@@ -198,5 +192,4 @@ void MackieControlProtocol::handle_port_init( Mackie::SurfacePort * sport )
cout << "MackieControlProtocol::handle_port_init" << endl;
_ports_changed = true;
update_ports();
- cout << "MackieControlProtocol::handle_port_init finished" << endl;
}
diff --git a/libs/surfaces/mackie/mackie_port.cc b/libs/surfaces/mackie/mackie_port.cc
index 18232f40bb..23371c4d1f 100644
--- a/libs/surfaces/mackie/mackie_port.cc
+++ b/libs/surfaces/mackie/mackie_port.cc
@@ -233,26 +233,7 @@ void MackiePort::probe_emulation( const MidiByteArray & bytes )
return;
}
- // probing doesn't work very well, so just use a config variable
- // to set the emulation mode
- bool emulation_ok = false;
- if ( ARDOUR::Config->get_mackie_emulation() == "bcf" )
- {
- _emulation = bcf2000;
- emulation_ok = true;
- }
- else if ( ARDOUR::Config->get_mackie_emulation() == "mcu" )
- {
- _emulation = mackie;
- emulation_ok = true;
- }
- else
- {
- cout << "unknown mackie emulation: " << ARDOUR::Config->get_mackie_emulation() << endl;
- emulation_ok = false;
- }
-
- finalise_init( emulation_ok );
+ finalise_init( true );
}
void MackiePort::init()
@@ -266,12 +247,42 @@ void MackiePort::init()
init_event();
// kick off initialisation. See docs in header file for init()
- write_sysex ( MidiByteArray (2, 0x13, 0x00 ));
+
+ // bypass the init sequence because sometimes the first
+ // message doesn't get to the unit, and there's no way
+ // to do a timed lock in Glib.
+ //write_sysex ( MidiByteArray ( 2, 0x13, 0x00 ) );
+
+ finalise_init( true );
}
void MackiePort::finalise_init( bool yn )
{
cout << "MackiePort::finalise_init" << endl;
+ bool emulation_ok = false;
+
+ // probing doesn't work very well, so just use a config variable
+ // to set the emulation mode
+ if ( _emulation == none )
+ {
+ if ( ARDOUR::Config->get_mackie_emulation() == "bcf" )
+ {
+ _emulation = bcf2000;
+ emulation_ok = true;
+ }
+ else if ( ARDOUR::Config->get_mackie_emulation() == "mcu" )
+ {
+ _emulation = mackie;
+ emulation_ok = true;
+ }
+ else
+ {
+ cout << "unknown mackie emulation: " << ARDOUR::Config->get_mackie_emulation() << endl;
+ emulation_ok = false;
+ }
+ }
+
+ yn = yn && emulation_ok;
SurfacePort::active( yn );
diff --git a/libs/surfaces/mackie/scripts/bcf-controls.csv b/libs/surfaces/mackie/scripts/bcf-controls.csv
index 165e836b30..6a6d66f6ac 100644
--- a/libs/surfaces/mackie/scripts/bcf-controls.csv
+++ b/libs/surfaces/mackie/scripts/bcf-controls.csv
@@ -17,17 +17,17 @@ button,7,strip,vselect,1,0,0x08
# overlay buttons
button,1,assignment,io,1,1,0x28
-button,1,assignment,sends,1,1,0x29
-button,1,assignment,pan,1,1,0x2a
-button,1,assignment,plugin,1,1,0x2b
-button,1,assignment,eq,1,1,0x2c
+button,1,assignment,sends,1,1,0x5a
+button,1,assignment,pan,1,1,0x59
+button,1,assignment,plugin,1,1,0x57
+button,1,assignment,eq,1,1,0x58
button,1,assignment,dyn,1,1,0x2d
button,1,bank,left,1,0,0x2e
button,1,bank,right,1,0,0x2f
button,1,bank,channel_left,1,0,0x30
button,1,bank,channel_right,1,0,0x31
button,1,,flip,1,1,0x32
-button,1,,edit,1,1,0x33
+button,1,,edit,1,1,0x56
button,1,display,name_value,1,0,0x34
button,1,display,smpte_beats,1,0,0x35
@@ -47,7 +47,8 @@ button,1,,F13,1,0,0x42
button,1,,F14,1,0,0x43
button,1,,F15,1,0,0x44
button,1,,F16,1,0,0x45
-button,1,modifiers,shift,1,0,0x46
+# turn on/off all solos
+button,1,,global_solo,1,0,0x27
button,1,modifiers,option,1,0,0x47
button,1,modifiers,control,1,0,0x48
button,1,modifiers,cmd_alt,1,0,0x49
@@ -63,11 +64,11 @@ button,1,functions,cancel,1,0,0x52
button,1,functions,mixer,1,0,0x53
button,1,transport,frm_left,1,1,0x54
button,1,transport,frm_right,1,1,0x55
-button,1,transport,loop,1,1,0x56
-button,1,transport,punch_in,1,1,0x57
-button,1,transport,punch_out,1,1,0x58
-button,1,transport,home,1,1,0x59
-button,1,transport,end,1,1,0x5a
+button,1,transport,loop,1,1,0x46
+button,1,transport,punch_in,1,1,0x2c
+button,1,transport,punch_out,1,1,0x2b
+button,1,transport,home,1,1,0x2a
+button,1,transport,end,1,1,0x29
# transport buttons
button,1,transport,"rewind",1,1,0x5b
@@ -87,6 +88,7 @@ button,1,user,"user_b",1,0,0x67
button,7,strip,"fader_touch",1,0,0x68
button,1,master,"fader_touch",1,0,0x6f
button,1,master,mute,1,0,0x17
+button,1,,clicking,1,1,0x33
button,1,,"smpte",0,1,0x71
button,1,,"beats",0,1,0x72
diff --git a/libs/surfaces/mackie/scripts/generate-surface.rb b/libs/surfaces/mackie/scripts/generate-surface.rb
index 106fa5682f..c6a028804a 100755
--- a/libs/surfaces/mackie/scripts/generate-surface.rb
+++ b/libs/surfaces/mackie/scripts/generate-surface.rb
@@ -1,17 +1,18 @@
#! /usr/bin/ruby
require 'erb'
-require 'controls.rb'
+
+require File.dirname(__FILE__) + '/controls.rb'
cc_template = ''
-File.open("surface-cc-template.erb", "r") { |f| cc_template = f.read }
+File.open( File.dirname(__FILE__) + "/surface-cc-template.erb", "r" ) { |f| cc_template = f.read }
h_template = ''
-File.open("surface-h-template.erb", "r") { |f| h_template = f.read }
+File.open( File.dirname(__FILE__) + "/surface-h-template.erb", "r" ) { |f| h_template = f.read }
sf = Surface.new( ARGV[0] )
control_data = ''
-File.open("#{sf.name.downcase}-controls.csv", "r") { |f| control_data = f.read }
+File.open( File.dirname(__FILE__) + "/#{sf.name.downcase}-controls.csv", "r") { |f| control_data = f.read }
sf.parse control_data
@result = ""
diff --git a/libs/surfaces/mackie/scripts/host.rb b/libs/surfaces/mackie/scripts/host.rb
index 94815d3e8c..8972cba137 100755
--- a/libs/surfaces/mackie/scripts/host.rb
+++ b/libs/surfaces/mackie/scripts/host.rb
@@ -22,6 +22,11 @@ while !File.exist? ARGV[0]
sleep 0.010
end
+#mapping_csv = ARGV[1] || "mackie-controls.csv"
+mapping_csv = ARGV[1]
+puts "mapping_csv: #{mapping_csv}"
+puts ""
+
file = File.open ARGV[0], 'r+'
mck = Mackie.new( file )
@@ -94,7 +99,7 @@ puts "version: #{version.map{|x| x.chr}}"
sf = Surface.new
control_data = ""
-File.open( "mackie-controls.csv" ) { |f| control_data = f.read }
+File.open( mapping_csv ) { |f| control_data = f.read }
sf.parse( control_data )
# send all faders to 0, but bounce them first
@@ -122,7 +127,7 @@ while bytes = mck.file.read( 3 )
print " Control Type: %-7s, " % sf.types[midi_type]
print "id: %4i" % control_id
- print ", control: %15s" % control.name
- print ", %15s" % control.group.name
+ print ", control: %15s" % ( control ? control.name : "nil control" )
+ print ", %15s" % ( control ? control.group.name : "nil group" )
print "\n"
end
diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc
index 24aa2296d8..8767e692b1 100644
--- a/libs/surfaces/mackie/surface_port.cc
+++ b/libs/surfaces/mackie/surface_port.cc
@@ -28,6 +28,8 @@
#include "i18n.h"
#include <sstream>
+#include <cstring>
+#include <cerrno>
using namespace std;
using namespace Mackie;
@@ -45,7 +47,11 @@ MidiByteArray SurfacePort::read()
// return nothing read if the lock isn't acquired
Glib::RecMutex::Lock lock( _rwlock, Glib::TRY_LOCK );
- if ( !lock.locked() ) return retval;
+ if ( !lock.locked() )
+ {
+ cout << "SurfacePort::read not locked" << endl;
+ return retval;
+ }
// read port and copy to return value
int nread = port().read( buf, sizeof (buf) );
@@ -59,11 +65,17 @@ MidiByteArray SurfacePort::read()
}
else
{
- ostringstream os;
- os << "error reading from port: " << port().name() << " nread: " << nread;
- cout << os.str() << endl;
- //inactive_event();
- //throw MackieControlException( os.str() );
+ if ( errno != EAGAIN )
+ {
+ char buf[512];
+ char * msg = strerror_r( errno, buf, 512 );
+
+ ostringstream os;
+ os << "Surface: error reading from port: " << port().name() << ": " << errno << " " << msg;
+ cout << os.str() << endl;
+ inactive_event();
+ throw MackieControlException( os.str() );
+ }
}
return retval;
}
@@ -76,10 +88,17 @@ void SurfacePort::write( const MidiByteArray & mba )
int count = port().write( mba.bytes().get(), mba.size() );
if ( count != (int)mba.size() )
{
- inactive_event();
- ostringstream os;
- os << _("Surface: couldn't write to port ") << port().name();
- throw MackieControlException( os.str() );
+ if ( errno != EAGAIN )
+ {
+ char buf[512];
+ char * msg = strerror_r( errno, buf, 512 );
+
+ ostringstream os;
+ os << "Surface: couldn't write to port " << port().name() << ": " << errno << " " << msg;
+ cout << os.str();
+ inactive_event();
+ throw MackieControlException( os.str() );
+ }
}
//if ( mba[0] == 0xf0 ) cout << "SurfacePort::write " << count << endl;
}