From 7182cd75e367ad97f978827c1bf4f875b46c6776 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Fri, 9 Mar 2007 20:46:46 +0000 Subject: 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 --- libs/surfaces/mackie/TODO | 3 +- libs/surfaces/mackie/bcf_surface.cc | 89 +++++++++------- libs/surfaces/mackie/interface.cc | 38 +++++-- libs/surfaces/mackie/mackie_button_handler.cc | 20 +++- libs/surfaces/mackie/mackie_button_handler.h | 5 + libs/surfaces/mackie/mackie_control_protocol.cc | 55 +++++----- libs/surfaces/mackie/mackie_control_protocol.h | 19 +++- .../mackie/mackie_control_protocol_poll.cc | 113 ++++++++++----------- libs/surfaces/mackie/mackie_port.cc | 53 ++++++---- libs/surfaces/mackie/scripts/bcf-controls.csv | 24 +++-- libs/surfaces/mackie/scripts/generate-surface.rb | 9 +- libs/surfaces/mackie/scripts/host.rb | 11 +- libs/surfaces/mackie/surface_port.cc | 39 +++++-- 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 ); @@ -899,6 +899,13 @@ void Mackie::BcfSurface::init_controls() controls.push_back( control ); 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; @@ -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 #include "mackie_control_protocol.h" +#include + #include 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 ); - // 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 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 +#include +#include 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; } -- cgit v1.2.3