summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Anderson <ardour@semiosix.com>2007-07-21 08:53:44 +0000
committerJohn Anderson <ardour@semiosix.com>2007-07-21 08:53:44 +0000
commit46424db99ab51ef7cd0ea4569cece45a140ec3e6 (patch)
tree1e71da56ec1a2d528cb1533c1b9abfd5b6ee884a
parent7a14cc049b409dfd9fb504d72451e0f5cbd5d764 (diff)
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
-rw-r--r--libs/surfaces/mackie/TODO3
-rw-r--r--libs/surfaces/mackie/bcf_surface.cc2
-rw-r--r--libs/surfaces/mackie/controls.h17
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc16
-rw-r--r--libs/surfaces/mackie/mackie_midi_builder.cc1
-rw-r--r--libs/surfaces/mackie/mackie_port.cc47
-rw-r--r--libs/surfaces/mackie/mackie_port.h6
-rw-r--r--libs/surfaces/mackie/mackie_surface.cc2
-rw-r--r--libs/surfaces/mackie/scripts/mackie-dump.midibin0 -> 495 bytes
-rw-r--r--libs/surfaces/mackie/scripts/simple_host.rb15
-rw-r--r--libs/surfaces/mackie/scripts/surface-cc-template.erb19
-rw-r--r--libs/surfaces/mackie/surface_port.cc16
12 files changed, 81 insertions, 63 deletions
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<Pot &>( 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> 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<Pot &>( 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<std::string> &
{
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
--- /dev/null
+++ b/libs/surfaces/mackie/scripts/mackie-dump.midi
Binary files 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 << "{ ";