diff options
author | John Anderson <ardour@semiosix.com> | 2007-07-31 10:52:23 +0000 |
---|---|---|
committer | John Anderson <ardour@semiosix.com> | 2007-07-31 10:52:23 +0000 |
commit | 2def7ef1abd7a30e05aa25aebd02e7987946bf1a (patch) | |
tree | f011d8764bbcebf38a2091cd4004f4cf5ae626d5 | |
parent | 0259d682595f966528904cd9b1f99c4380aa2751 (diff) |
Add Control::in_use. Add a timeout-generated stop event to Pot.
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2197 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/surfaces/mackie/TODO | 4 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.cc | 20 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.h | 38 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.cc | 5 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol_poll.cc | 3 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_jog_wheel.cc | 16 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_jog_wheel.h | 2 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_port.cc | 48 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_port.h | 4 | ||||
-rw-r--r-- | libs/surfaces/mackie/types.h | 2 |
10 files changed, 110 insertions, 32 deletions
diff --git a/libs/surfaces/mackie/TODO b/libs/surfaces/mackie/TODO index 245929886c..7d6f945132 100644 --- a/libs/surfaces/mackie/TODO +++ b/libs/surfaces/mackie/TODO @@ -1,8 +1,7 @@ * if mackie wheel moves too fast, it's ignored. -* active (pressed?) state for controls, including timeout * update manual with jog wheel states * alsa/sequencer ports unstable. possibly problems with use of ::poll -* use glib::timeout for check_scrubbing +* use glib::Timer instead of mine * crash when mmc port set to mcu? * remappable buttons * how long can UI signal callbacks take to execute? What happens if they block? @@ -19,6 +18,7 @@ Later ----- * remove commented couts * Perhaps MackieControlProtocol shouldn't implement MackieButtonHandler +* Need a HostAdapter class to encapsulate ardour calls * 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/controls.cc b/libs/surfaces/mackie/controls.cc index bac37797ab..5c2d1e6779 100644 --- a/libs/surfaces/mackie/controls.cc +++ b/libs/surfaces/mackie/controls.cc @@ -45,6 +45,15 @@ Strip::Strip( const std::string & name, int index ) { } +Control::Control( int id, int ordinal, std::string name, Group & group ) +: _id( id ) +, _ordinal( ordinal ) +, _name( name ) +, _group( group ) +, _in_use_timeout( 250 ) +{ +} + /** generated with @@ -108,6 +117,17 @@ Button & Strip::fader_touch() return *_fader_touch; } +bool Control::in_use() const +{ + return _in_use; +} + +Control & Control::in_use( bool rhs ) +{ + _in_use = rhs; + return *this; +} + ostream & Mackie::operator << ( ostream & os, const Mackie::Control & control ) { os << typeid( control ).name(); diff --git a/libs/surfaces/mackie/controls.h b/libs/surfaces/mackie/controls.h index a4e259465c..a6c45e7eef 100644 --- a/libs/surfaces/mackie/controls.h +++ b/libs/surfaces/mackie/controls.h @@ -18,6 +18,8 @@ #ifndef mackie_controls_h #define mackie_controls_h +#include <sigc++/sigc++.h> + #include <map> #include <vector> #include <string> @@ -157,11 +159,7 @@ class Control public: enum type_t { type_led, type_led_ring, type_fader = 0xe0, type_button = 0x90, type_pot = 0xb0 }; - Control( int id, int ordinal, std::string name, Group & group ) - : _id( id ), _ordinal( ordinal ), _name( name ), _group( group ) - { - } - + Control( int id, int ordinal, std::string name, Group & group ); virtual ~Control() {} virtual const Led & led() const @@ -215,11 +213,29 @@ public: /// Jog Wheel virtual bool is_jog() const { return false; } + /** + Return true if the controlis in use, or false otherwise. For buttons + this returns true if the button is currently being held down. For + faders, the touch button has not been released. For pots, this returns + true from the first move event until a timeout after the last move event. + */ + virtual bool in_use() const; + virtual Control & in_use( bool ); + + /// The timeout value for this control. Normally defaulted to 250ms, but + /// certain controls (ie jog wheel) may want to override it. + virtual unsigned int in_use_timeout() { return _in_use_timeout; } + + /// Keep track of the timeout so it can be updated with more incoming events + sigc::connection in_use_connection; + private: int _id; int _ordinal; std::string _name; Group & _group; + bool _in_use; + unsigned int _in_use_timeout; }; std::ostream & operator << ( std::ostream & os, const Control & control ); @@ -229,18 +245,10 @@ class Fader : public Control public: Fader( int id, int ordinal, std::string name, Group & group ) : Control( id, ordinal, name, group ) - , _touch( false ) { } - bool touch() const { return _touch; } - - void touch( bool yn ) { _touch = yn; } - virtual type_t type() const { return type_fader; } - -private: - bool _touch; }; class Led : public Control @@ -272,12 +280,8 @@ public: virtual type_t type() const { return type_button; }; - bool pressed() const { return _pressed; } - Button & pressed( bool rhs ) { _pressed = rhs; return *this; } - private: Led _led; - bool _pressed; }; class LedRing : public Led diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index d0b977c57f..de532e28fa 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -478,7 +478,7 @@ bool MackieControlProtocol::handle_strip_button( Control & control, ButtonState if ( control.name() == "fader_touch" ) { state = bs == press; - control.strip().gain().touch( state ); + control.strip().gain().in_use( state ); } return state; @@ -831,6 +831,7 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control & switch ( control.type() ) { case Control::type_fader: + // TODO this seems to be a duplicate of the above if if ( control.group().is_strip() ) { // find the route in the route table for the id @@ -984,7 +985,7 @@ void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal ) try { Fader & fader = route_signal->strip().gain(); - if ( !fader.touch() ) + if ( !fader.in_use() ) { route_signal->port().write( builder.build_fader( fader, gain_to_slider_position( route_signal->route().effective_gain() ) ) ); } diff --git a/libs/surfaces/mackie/mackie_control_protocol_poll.cc b/libs/surfaces/mackie/mackie_control_protocol_poll.cc index a9e946cd7f..0efca85bd8 100644 --- a/libs/surfaces/mackie/mackie_control_protocol_poll.cc +++ b/libs/surfaces/mackie/mackie_control_protocol_poll.cc @@ -64,9 +64,6 @@ void * MackieControlProtocol::monitor_work() } // poll for automation data from the routes poll_automation(); - - // check if we need to stop scrubbing - _jog_wheel.check_scrubbing(); } catch ( exception & e ) { diff --git a/libs/surfaces/mackie/mackie_jog_wheel.cc b/libs/surfaces/mackie/mackie_jog_wheel.cc index 54ded2f84e..dbf18de931 100644 --- a/libs/surfaces/mackie/mackie_jog_wheel.cc +++ b/libs/surfaces/mackie/mackie_jog_wheel.cc @@ -76,10 +76,18 @@ void JogWheel::jog_event( SurfacePort & port, Control & control, const ControlSt case scrub: { - add_scrub_interval( _scrub_timer.restart() ); - // x clicks per second => speed == 1.0 - float speed = _mcp.surface().scrub_scaling_factor() / average_scrub_interval() * state.ticks; - _mcp.get_session().request_transport_speed( speed * state.sign ); + if ( state.delta != 0.0 ) + { + add_scrub_interval( _scrub_timer.restart() ); + // x clicks per second => speed == 1.0 + float speed = _mcp.surface().scrub_scaling_factor() / average_scrub_interval() * state.ticks; + _mcp.get_session().request_transport_speed( speed * state.sign ); + } + else + { + // we have a stop event + check_scrubbing(); + } break; } diff --git a/libs/surfaces/mackie/mackie_jog_wheel.h b/libs/surfaces/mackie/mackie_jog_wheel.h index c22b75bd1b..83a4364393 100644 --- a/libs/surfaces/mackie/mackie_jog_wheel.h +++ b/libs/surfaces/mackie/mackie_jog_wheel.h @@ -79,7 +79,7 @@ protected: private: MackieControlProtocol & _mcp; - // transport speed for ffwd and rew, controller by jog + /// transport speed for ffwd and rew, controller by jog float _transport_speed; int _transport_direction; diff --git a/libs/surfaces/mackie/mackie_port.cc b/libs/surfaces/mackie/mackie_port.cc index d712270402..c78021ed91 100644 --- a/libs/surfaces/mackie/mackie_port.cc +++ b/libs/surfaces/mackie/mackie_port.cc @@ -23,6 +23,8 @@ #include "controls.h" #include "surface.h" +#include <glibmm/main.h> + #include <midi++/types.h> #include <midi++/port.h> #include <sigc++/sigc++.h> @@ -378,6 +380,17 @@ Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count ) return *control; } +bool MackiePort::handle_control_timeout_event ( Control * control ) +{ + // empty control_state + ControlState control_state; + control->in_use( false ); + control_event( *this, *control, control_state ); + + // only call this method once from the timer + return false; +} + // converts midi messages into control_event signals // it might be worth combining this with lookup_control // because they have similar logic flows. @@ -402,6 +415,7 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, } Control & control = lookup_control( raw_bytes, count ); + control.in_use( true ); // This handles incoming bytes. Outgoing bytes // are sent by the signal handlers. @@ -412,6 +426,9 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, { // only the top-order 10 bits out of 14 are used int midi_pos = ( ( raw_bytes[2] << 7 ) + raw_bytes[1] ) >> 4; + + // in_use is set by the MackieControlProtocol::handle_strip_button + // relies on implicit ControlState constructor control_event( *this, control, float(midi_pos) / float(0x3ff) ); } @@ -419,9 +436,13 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, // button case Control::type_button: - // relies on implicit ControlState constructor - control_event( *this, control, raw_bytes[2] == 0x7f ? press : release ); + { + ControlState control_state( raw_bytes[2] == 0x7f ? press : release ); + control.in_use( control_state.button_state == press ); + control_event( *this, control, control_state ); + break; + } // pot (jog wheel, external control) case Control::type_pot: @@ -434,6 +455,29 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, state.ticks = ( raw_bytes[2] & 0x3f); state.delta = float( state.ticks ) / float( 0x3f ); + /* + Pots only emit events when they move, not when they + stop moving. So to get a stop event, we need to use a timeout. + */ + // this is set to false ... + control.in_use( true ); + + // ... by this timeout + + // first disconnect any previous timeouts + control.in_use_connection.disconnect(); + + // now connect a new timeout to call handle_control_timeout_event + sigc::slot<bool> timeout_slot = sigc::bind( + mem_fun( *this, &MackiePort::handle_control_timeout_event ) + , &control + ); + control.in_use_connection = Glib::signal_timeout().connect( + timeout_slot + , control.in_use_timeout() + ); + + // emit the control event control_event( *this, control, state ); break; } diff --git a/libs/surfaces/mackie/mackie_port.h b/libs/surfaces/mackie/mackie_port.h index 2621e6dd95..26ec1ca799 100644 --- a/libs/surfaces/mackie/mackie_port.h +++ b/libs/surfaces/mackie/mackie_port.h @@ -109,6 +109,10 @@ protected: */ void probe_emulation( const MidiByteArray & bytes ); + /// Handle timeout events set for controls that don't emit + /// an off event + bool handle_control_timeout_event ( Control * ); + private: MackieControlProtocol & _mcp; port_type_t _port_type; diff --git a/libs/surfaces/mackie/types.h b/libs/surfaces/mackie/types.h index 21b0d1989a..be5c7e8b79 100644 --- a/libs/surfaces/mackie/types.h +++ b/libs/surfaces/mackie/types.h @@ -64,7 +64,7 @@ enum ButtonState { neither = -1, release = 0, press = 1 }; */ struct ControlState { - ControlState(): pos(0.0), delta(0.0), button_state(neither) {} + ControlState(): pos(0.0), sign(0), delta(0.0), ticks(0), led_state(off), button_state(neither) {} ControlState( LedState ls ): pos(0.0), delta(0.0), led_state(ls), button_state(neither) {} |