From 46424db99ab51ef7cd0ea4569cece45a140ec3e6 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Sat, 21 Jul 2007 08:53:44 +0000 Subject: optimisations on control paths that are used for every midi event git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2167 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/surfaces/mackie/TODO | 3 ++ libs/surfaces/mackie/bcf_surface.cc | 2 +- libs/surfaces/mackie/controls.h | 17 +++++++- libs/surfaces/mackie/mackie_control_protocol.cc | 16 ++++--- libs/surfaces/mackie/mackie_midi_builder.cc | 1 + libs/surfaces/mackie/mackie_port.cc | 47 +++++++++++++-------- libs/surfaces/mackie/mackie_port.h | 6 +-- libs/surfaces/mackie/mackie_surface.cc | 2 +- libs/surfaces/mackie/scripts/mackie-dump.midi | Bin 0 -> 495 bytes libs/surfaces/mackie/scripts/simple_host.rb | 15 ++----- .../mackie/scripts/surface-cc-template.erb | 19 ++++++--- libs/surfaces/mackie/surface_port.cc | 16 ------- 12 files changed, 81 insertions(+), 63 deletions(-) create mode 100644 libs/surfaces/mackie/scripts/mackie-dump.midi diff --git a/libs/surfaces/mackie/TODO b/libs/surfaces/mackie/TODO index 04d7692417..aa9a98f247 100644 --- a/libs/surfaces/mackie/TODO +++ b/libs/surfaces/mackie/TODO @@ -1,3 +1,5 @@ +* if mackie wheel moves too fast, it's ignored. +* need to put scaling functions and multipliers in subclasses. * update manual with jog wheel states * alsa/sequencer ports unstable. possibly problems with use of ::poll * use glib::timeout for check_scrubbing @@ -16,6 +18,7 @@ Later ----- * remove commented couts +* Perhaps MackieControlProtocol shouldn't implement MackieButtonHandler * talk to route plugins * check for excessiveness (ie too many events making other subsystems work too hard) * Queueing of writes? diff --git a/libs/surfaces/mackie/bcf_surface.cc b/libs/surfaces/mackie/bcf_surface.cc index 0740c8293c..9ac144b8b5 100644 --- a/libs/surfaces/mackie/bcf_surface.cc +++ b/libs/surfaces/mackie/bcf_surface.cc @@ -177,7 +177,7 @@ void Mackie::BcfSurface::init_controls() group->add( *pot ); group = groups["none"]; - pot = new Pot ( 23, 1, "jog", *group ); + pot = new Jog ( 23, 1, "jog", *group ); pots[0x17] = pot; controls.push_back( pot ); controls_by_name["jog"] = pot; diff --git a/libs/surfaces/mackie/controls.h b/libs/surfaces/mackie/controls.h index 453ef4a091..a4e259465c 100644 --- a/libs/surfaces/mackie/controls.h +++ b/libs/surfaces/mackie/controls.h @@ -170,7 +170,7 @@ public: } /// type() << 8 + midi id of the control. This - /// provides a unique id of any control on the surface. + /// provides a unique id for any control on the surface. int id() const { return ( type() << 8 ) + _id; @@ -211,6 +211,10 @@ public: virtual type_t type() const = 0; + /// Return true if this control is the one and only + /// Jog Wheel + virtual bool is_jog() const { return false; } + private: int _id; int _ordinal; @@ -307,6 +311,17 @@ private: LedRing _led_ring; }; +class Jog : public Pot +{ +public: + Jog( int id, int ordinal, std::string name, Group & group ) + : Pot( id, ordinal, name, group ) + { + } + + virtual bool is_jog() const { return true; } +}; + } #endif diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index f648ed059e..54805141d2 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -535,6 +535,13 @@ void MackieControlProtocol::update_surface() // update strip from route master_route_signal->notify_all(); + // turn off the led ring, for bcf emulation mode + if ( mcu_port().emulation() == MackiePort::bcf2000 ) + { + Control & control = *surface().controls_by_name["jog"]; + mcu_port().write( builder.build_led_ring( dynamic_cast( control ), off ) ); + } + // update global buttons and displays notify_record_state_changed(); notify_transport_state_changed(); @@ -800,6 +807,7 @@ int MackieControlProtocol::set_state( const XMLNode & node ) void MackieControlProtocol::handle_control_event( SurfacePort & port, Control & control, const ControlState & state ) { + // fetch a RouteSignal so we know what route to update uint32_t index = control.ordinal() - 1 + ( port.number() * port.strips() ); boost::shared_ptr route; if ( control.group().is_strip() ) @@ -906,15 +914,9 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control & } else { - if ( control.name() == "jog" ) + if ( control.is_jog() ) { _jog_wheel.jog_event( port, control, state ); - - // turn off the led ring, for bcf emulation mode - if ( mcu_port().emulation() == MackiePort::bcf2000 ) - { - port.write( builder.build_led_ring( dynamic_cast( control ), off ) ); - } } else { diff --git a/libs/surfaces/mackie/mackie_midi_builder.cc b/libs/surfaces/mackie/mackie_midi_builder.cc index 801e0cfc7c..8ddbff1043 100644 --- a/libs/surfaces/mackie/mackie_midi_builder.cc +++ b/libs/surfaces/mackie/mackie_midi_builder.cc @@ -208,6 +208,7 @@ MidiByteArray MackieMidiBuilder::all_strips_display( std::vector & { MidiByteArray retval; retval << 0x12 << 0; + // NOTE remember max 112 bytes per message, including sysex headers retval << "Not working yet"; return retval; } diff --git a/libs/surfaces/mackie/mackie_port.cc b/libs/surfaces/mackie/mackie_port.cc index 2a859702dc..0d81bd7c6f 100644 --- a/libs/surfaces/mackie/mackie_port.cc +++ b/libs/surfaces/mackie/mackie_port.cc @@ -113,50 +113,53 @@ const MidiByteArray & MackiePort::sysex_hdr() const return mackie_sysex_hdr; } -Control & MackiePort::lookup_control( const MidiByteArray & bytes ) +Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count ) { Control * control = 0; - int midi_id = -1; MIDI::byte midi_type = bytes[0] & 0xf0; //0b11110000 switch( midi_type ) { // fader case MackieMidiBuilder::midi_fader_id: - midi_id = bytes[0] & 0x0f; + { + int midi_id = bytes[0] & 0x0f; control = _mcp.surface().faders[midi_id]; if ( control == 0 ) { + MidiByteArray mba( count, bytes ); ostringstream os; - os << "control for fader" << midi_id << " is null"; + os << "control for fader" << bytes << " id " << midi_id << " is null"; throw MackieControlException( os.str() ); } break; + } // button case MackieMidiBuilder::midi_button_id: - midi_id = bytes[1]; - control = _mcp.surface().buttons[midi_id]; + control = _mcp.surface().buttons[bytes[1]]; if ( control == 0 ) { + MidiByteArray mba( count, bytes ); ostringstream os; - os << "control for button" << midi_id << " is null"; + os << "control for button " << bytes << " is null"; throw MackieControlException( os.str() ); } break; // pot (jog wheel, external control) case MackieMidiBuilder::midi_pot_id: - midi_id = bytes[1] & 0x1f; - control = _mcp.surface().pots[midi_id]; + control = _mcp.surface().pots[bytes[1]]; if ( control == 0 ) { + MidiByteArray mba( count, bytes ); ostringstream os; - os << "control for button" << midi_id << " is null"; + os << "control for rotary " << mba << " is null"; throw MackieControlException( os.str() ); } break; default: + MidiByteArray mba( count, bytes ); ostringstream os; os << "Cannot find control for " << bytes; throw MackieControlException( os.str() ); @@ -370,16 +373,25 @@ void MackiePort::handle_midi_sysex (MIDI::Parser & parser, MIDI::byte * raw_byte // converts midi messages into control_event signals void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, size_t count ) { - MidiByteArray bytes( count, raw_bytes ); #ifdef DEBUG + MidiByteArray bytes( count, raw_bytes ); cout << "MackiePort::handle_midi_any " << bytes << endl; #endif try { // ignore sysex messages - if ( bytes[0] == MIDI::sysex ) return; + if ( raw_bytes[0] == MIDI::sysex ) return; - Control & control = lookup_control( bytes ); + // sanity checking + if ( count != 3 ) + { + ostringstream os; + MidiByteArray mba( count, raw_bytes ); + os << "MackiePort::handle_midi_any needs 3 bytes, but received " << mba; + throw MackieControlException( os.str() ); + } + + Control & control = lookup_control( raw_bytes, count ); // This handles incoming bytes. Outgoing bytes // are sent by the signal handlers. @@ -392,14 +404,14 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, // According to the Logic docs, these should both be 0x7f. // Although it does mention something about only the top-order // 10 bits out of 14 being used - int midi_pos = ( bytes[2] << 7 ) + bytes[1]; + int midi_pos = ( raw_bytes[2] << 7 ) + raw_bytes[1]; control_event( *this, control, float(midi_pos) / float(0x3fff) ); } break; // button case Control::type_button: - control_event( *this, control, bytes[2] == 0x7f ? press : release ); + control_event( *this, control, raw_bytes[2] == 0x7f ? press : release ); break; // pot (jog wheel, external control) @@ -408,9 +420,9 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, ControlState state; // bytes[2] & 0b01000000 (0x40) give sign - state.sign = ( bytes[2] & 0x40 ) == 0 ? 1 : -1; + state.sign = ( raw_bytes[2] & 0x40 ) == 0 ? 1 : -1; // bytes[2] & 0b00111111 (0x3f) gives delta - state.ticks = ( bytes[2] & 0x3f); + state.ticks = ( raw_bytes[2] & 0x3f); state.delta = float( state.ticks ) / float( 0x3f ); control_event( *this, control, state ); @@ -422,6 +434,7 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, } catch( MackieControlException & e ) { + MidiByteArray bytes( count, raw_bytes ); cout << bytes << ' ' << e.what() << endl; } #ifdef DEBUG diff --git a/libs/surfaces/mackie/mackie_port.h b/libs/surfaces/mackie/mackie_port.h index 0a705e65f3..2621e6dd95 100644 --- a/libs/surfaces/mackie/mackie_port.h +++ b/libs/surfaces/mackie/mackie_port.h @@ -55,12 +55,12 @@ public: virtual const MidiByteArray & sysex_hdr() const; /// Handle device initialisation - void handle_midi_sysex( MIDI::Parser &, MIDI::byte *, size_t ); + void handle_midi_sysex( MIDI::Parser &, MIDI::byte *, size_t count ); /// Handle all control messags - void handle_midi_any( MIDI::Parser &, MIDI::byte *, size_t ); + void handle_midi_any( MIDI::Parser &, MIDI::byte *, size_t count ); - Control & lookup_control( const MidiByteArray & bytes ); + Control & lookup_control( MIDI::byte *, size_t count ); /// return the number of strips associated with this port virtual int strips() const; diff --git a/libs/surfaces/mackie/mackie_surface.cc b/libs/surfaces/mackie/mackie_surface.cc index 7b0344b683..f284a05142 100644 --- a/libs/surfaces/mackie/mackie_surface.cc +++ b/libs/surfaces/mackie/mackie_surface.cc @@ -193,7 +193,7 @@ void Mackie::MackieSurface::init_controls() group->add( *pot ); group = groups["none"]; - pot = new Pot ( 60, 1, "jog", *group ); + pot = new Jog ( 60, 1, "jog", *group ); pots[0x3c] = pot; controls.push_back( pot ); controls_by_name["jog"] = pot; diff --git a/libs/surfaces/mackie/scripts/mackie-dump.midi b/libs/surfaces/mackie/scripts/mackie-dump.midi new file mode 100644 index 0000000000..57b36002a5 Binary files /dev/null and b/libs/surfaces/mackie/scripts/mackie-dump.midi differ diff --git a/libs/surfaces/mackie/scripts/simple_host.rb b/libs/surfaces/mackie/scripts/simple_host.rb index a5c07f2abb..a369ac8904 100644 --- a/libs/surfaces/mackie/scripts/simple_host.rb +++ b/libs/surfaces/mackie/scripts/simple_host.rb @@ -25,17 +25,8 @@ while !File.exist? ARGV[0] end file = File.open( ARGV[0], 'r+' ) -mck = Mackie.new( file ) - -# faders to minimum. bcf2000 doesn't respond -mck.write_sysex "\x61" - -# all leds off. bcf2000 doesn't respond -mck.write_sysex "\x62" - -# get version. comes back as ASCII bytes -version = mck.sysex "\x13\x00" -puts "version: #{version.map{|x| x.chr}}" +#mck = Mackie.new( file ) +device = false # respond to control movements while bytes = file.read( 3 ) @@ -121,7 +112,7 @@ while bytes = file.read( 3 ) end # output bytes - if output + if device && output #sleep 0.1 puts "sending: %02.x %02.x %02.x" % [ output[0], output[1], output[2] ] begin diff --git a/libs/surfaces/mackie/scripts/surface-cc-template.erb b/libs/surfaces/mackie/scripts/surface-cc-template.erb index 79cd2e4ae0..a82a144b67 100644 --- a/libs/surfaces/mackie/scripts/surface-cc-template.erb +++ b/libs/surfaces/mackie/scripts/surface-cc-template.erb @@ -58,14 +58,23 @@ void Mackie::<%= sf.name %>Surface::init_controls() Led * led = 0; % sf.controls.each do |control| + <%- + variable_name = control.class.name.downcase + class_name = + if control.name == 'jog' + 'Jog' + else + control.class.name + end + -%> group = groups["<%=control.group.name%>"]; - <%= control.class.name.downcase %> = new <%= control.class.name %> ( <%= control.id %>, <%= control.ordinal %>, "<%=control.name%>", *group ); - <%=control.class.name.downcase%>s[0x<%=control.id.to_hex %>] = <%= control.class.name.downcase %>; - controls.push_back( <%= control.class.name.downcase %> ); + <%= variable_name %> = new <%= class_name %> ( <%= control.id %>, <%= control.ordinal %>, "<%=control.name%>", *group ); + <%= variable_name %>s[0x<%=control.id.to_hex %>] = <%= variable_name %>; + controls.push_back( <%= variable_name %> ); <%- if control.group.class != Strip -%> - controls_by_name["<%= control.name %>"] = <%= control.class.name.downcase %>; + controls_by_name["<%= control.name %>"] = <%= variable_name %>; <%- end -%> - group->add( *<%= control.class.name.downcase %> ); + group->add( *<%= variable_name %> ); % end } diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc index a1de02a356..5354e71df6 100644 --- a/libs/surfaces/mackie/surface_port.cc +++ b/libs/surfaces/mackie/surface_port.cc @@ -159,22 +159,6 @@ void SurfacePort::write_sysex( MIDI::byte msg ) write( buf ); } -// This should be moved to midi++ at some point -ostream & operator << ( ostream & os, const MIDI::Port & port ) -{ - os << "device: " << port.device(); - os << "; "; - os << "name: " << port.name(); - os << "; "; - os << "type: " << port.type(); - os << "; "; - os << "mode: " << port.mode(); - os << "; "; - os << "ok: " << port.ok(); - os << "; "; - return os; -} - ostream & Mackie::operator << ( ostream & os, const SurfacePort & port ) { os << "{ "; -- cgit v1.2.3