mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-24 07:27:44 +01:00
Jog Wheel Fun:
- When ffwd/rew is pressed, wheel controls speed - Zoom button allows jog wheel to zoom - Scrub button cycles jog from scrub to shuttle to whatever it was before git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2155 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
47add43cd0
commit
4c12c98e33
19 changed files with 1687 additions and 1262 deletions
|
|
@ -35,6 +35,7 @@ surface.cc
|
|||
mackie_control_protocol.cc
|
||||
bcf_surface.cc
|
||||
mackie_surface.cc
|
||||
mackie_jog_wheel.cc
|
||||
""")
|
||||
|
||||
mackie.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
* update manual with jog wheel states
|
||||
* alsa/sequencer ports unstable
|
||||
* crash when mmc port set to mcu
|
||||
* remappable buttons
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -267,9 +267,13 @@ 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
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
|
|||
, _polling( true )
|
||||
, pfd( 0 )
|
||||
, nfds( 0 )
|
||||
, _jog_wheel( *this )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
cout << "MackieControlProtocol::MackieControlProtocol" << endl;
|
||||
|
|
@ -907,27 +908,17 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
|
|||
{
|
||||
if ( control.name() == "jog" )
|
||||
{
|
||||
// TODO use current snap-to setting?
|
||||
long delta = state.ticks * 1000;
|
||||
nframes_t next = session->transport_frame() + delta;
|
||||
if ( delta < 0 && session->transport_frame() < (nframes_t) abs( delta ) )
|
||||
{
|
||||
next = session->current_start_frame();
|
||||
}
|
||||
else if ( next > session->current_end_frame() )
|
||||
{
|
||||
next = session->current_end_frame();
|
||||
}
|
||||
|
||||
// doesn't work very well
|
||||
session->request_locate( next, session->transport_rolling() );
|
||||
_jog_wheel.jog_event( port, control, state );
|
||||
|
||||
// turn off the led ring, for bcf emulation mode
|
||||
port.write( builder.build_led_ring( dynamic_cast<Pot &>( control ), off ) );
|
||||
if ( mcu_port().emulation() == MackiePort::bcf2000 )
|
||||
{
|
||||
port.write( builder.build_led_ring( dynamic_cast<Pot &>( control ), off ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "external controller" << state.ticks << endl;
|
||||
cout << "external controller" << state.ticks * state.sign << endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1186,12 +1177,16 @@ LedState MackieControlProtocol::record_release( Button & button )
|
|||
|
||||
LedState MackieControlProtocol::rewind_press( Button & button )
|
||||
{
|
||||
session->request_transport_speed( -4.0 );
|
||||
_jog_wheel.push( JogWheel::speed );
|
||||
_jog_wheel.transport_direction( -1 );
|
||||
session->request_transport_speed( -_jog_wheel.transport_speed() );
|
||||
return on;
|
||||
}
|
||||
|
||||
LedState MackieControlProtocol::rewind_release( Button & button )
|
||||
{
|
||||
_jog_wheel.pop();
|
||||
_jog_wheel.transport_direction( 0 );
|
||||
if ( _transport_previously_rolling )
|
||||
session->request_transport_speed( 1.0 );
|
||||
else
|
||||
|
|
@ -1201,12 +1196,16 @@ LedState MackieControlProtocol::rewind_release( Button & button )
|
|||
|
||||
LedState MackieControlProtocol::ffwd_press( Button & button )
|
||||
{
|
||||
session->request_transport_speed( 4.0 );
|
||||
_jog_wheel.push( JogWheel::speed );
|
||||
_jog_wheel.transport_direction( 1 );
|
||||
session->request_transport_speed( _jog_wheel.transport_speed() );
|
||||
return on;
|
||||
}
|
||||
|
||||
LedState MackieControlProtocol::ffwd_release( Button & button )
|
||||
{
|
||||
_jog_wheel.pop();
|
||||
_jog_wheel.transport_direction( 0 );
|
||||
if ( _transport_previously_rolling )
|
||||
session->request_transport_speed( 1.0 );
|
||||
else
|
||||
|
|
@ -1506,3 +1505,50 @@ LedState MackieControlProtocol::marker_release( Button & button )
|
|||
{
|
||||
return off;
|
||||
}
|
||||
|
||||
void jog_wheel_state_display( JogWheel::State state, MackiePort & port )
|
||||
{
|
||||
switch( state )
|
||||
{
|
||||
case JogWheel::zoom: port.write( builder.two_char_display( "Zm" ) ); break;
|
||||
case JogWheel::scroll: port.write( builder.two_char_display( "Sc" ) ); break;
|
||||
case JogWheel::scrub: port.write( builder.two_char_display( "Sb" ) ); break;
|
||||
case JogWheel::shuttle: port.write( builder.two_char_display( "Sh" ) ); break;
|
||||
case JogWheel::speed: port.write( builder.two_char_display( "Sp" ) ); break;
|
||||
case JogWheel::select: port.write( builder.two_char_display( "Se" ) ); break;
|
||||
}
|
||||
}
|
||||
|
||||
Mackie::LedState MackieControlProtocol::zoom_press( Mackie::Button & )
|
||||
{
|
||||
_jog_wheel.zoom_state_toggle();
|
||||
update_global_button( "scrub", _jog_wheel.jog_wheel_state() == JogWheel::scrub );
|
||||
jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
|
||||
return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
|
||||
}
|
||||
|
||||
Mackie::LedState MackieControlProtocol::zoom_release( Mackie::Button & )
|
||||
{
|
||||
return _jog_wheel.jog_wheel_state() == JogWheel::zoom;
|
||||
}
|
||||
|
||||
Mackie::LedState MackieControlProtocol::scrub_press( Mackie::Button & )
|
||||
{
|
||||
_jog_wheel.scrub_state_cycle();
|
||||
update_global_button( "zoom", _jog_wheel.jog_wheel_state() == JogWheel::zoom );
|
||||
jog_wheel_state_display( _jog_wheel.jog_wheel_state(), mcu_port() );
|
||||
return
|
||||
_jog_wheel.jog_wheel_state() == JogWheel::scrub
|
||||
||
|
||||
_jog_wheel.jog_wheel_state() == JogWheel::shuttle
|
||||
;
|
||||
}
|
||||
|
||||
Mackie::LedState MackieControlProtocol::scrub_release( Mackie::Button & )
|
||||
{
|
||||
return
|
||||
_jog_wheel.jog_wheel_state() == JogWheel::scrub
|
||||
||
|
||||
_jog_wheel.jog_wheel_state() == JogWheel::shuttle
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "route_signal.h"
|
||||
#include "mackie_button_handler.h"
|
||||
#include "mackie_port.h"
|
||||
#include "mackie_jog_wheel.h"
|
||||
#include "timer.h"
|
||||
|
||||
namespace MIDI {
|
||||
|
|
@ -184,6 +185,19 @@ class MackieControlProtocol
|
|||
virtual Mackie::LedState marker_press( Mackie::Button & );
|
||||
virtual Mackie::LedState marker_release( Mackie::Button & );
|
||||
|
||||
// jog wheel states
|
||||
virtual Mackie::LedState zoom_press( Mackie::Button & );
|
||||
virtual Mackie::LedState zoom_release( Mackie::Button & );
|
||||
|
||||
virtual Mackie::LedState scrub_press( Mackie::Button & );
|
||||
virtual Mackie::LedState scrub_release( Mackie::Button & );
|
||||
|
||||
/// This is the main MCU port, ie not an extender port
|
||||
/// Only for use by JogWheel
|
||||
const Mackie::MackiePort & mcu_port() const;
|
||||
Mackie::MackiePort & mcu_port();
|
||||
ARDOUR::Session & get_session() { return *session; }
|
||||
|
||||
protected:
|
||||
// create instances of MackiePort, depending on what's found in ardour.rc
|
||||
void create_ports();
|
||||
|
|
@ -222,10 +236,6 @@ class MackieControlProtocol
|
|||
// delete all RouteSignal objects connecting Routes to Strips
|
||||
void clear_route_signals();
|
||||
|
||||
/// This is the main MCU port, ie not an extender port
|
||||
const Mackie::MackiePort & mcu_port() const;
|
||||
Mackie::MackiePort & mcu_port();
|
||||
|
||||
typedef std::vector<Mackie::RouteSignal*> RouteSignals;
|
||||
RouteSignals route_signals;
|
||||
|
||||
|
|
@ -318,6 +328,8 @@ class MackieControlProtocol
|
|||
|
||||
// timer for two quick marker left presses
|
||||
Mackie::Timer _frm_left_last;
|
||||
|
||||
Mackie::JogWheel _jog_wheel;
|
||||
};
|
||||
|
||||
#endif // ardour_mackie_control_protocol_h
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ void * MackieControlProtocol::monitor_work()
|
|||
{
|
||||
if ( poll_ports() )
|
||||
{
|
||||
cout << "--------------------------------------" << endl;
|
||||
cout << "MackieControlProtocol::read_ports _ports: " << _ports.size() << ", nfds: " << nfds << endl;
|
||||
try { read_ports(); }
|
||||
catch ( exception & e ) {
|
||||
cout << "MackieControlProtocol::poll_ports caught exception: " << e.what() << endl;
|
||||
|
|
@ -66,6 +64,9 @@ 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 )
|
||||
{
|
||||
|
|
|
|||
218
libs/surfaces/mackie/mackie_jog_wheel.cc
Normal file
218
libs/surfaces/mackie/mackie_jog_wheel.cc
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
#include "mackie_jog_wheel.h"
|
||||
|
||||
#include "mackie_control_protocol.h"
|
||||
#include "surface_port.h"
|
||||
#include "controls.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Mackie;
|
||||
|
||||
JogWheel::JogWheel( MackieControlProtocol & mcp )
|
||||
: _mcp( mcp )
|
||||
, _transport_speed( 4.0 )
|
||||
, _transport_direction( 0 )
|
||||
, _shuttle_speed( 0.0 )
|
||||
{
|
||||
}
|
||||
|
||||
JogWheel::State JogWheel::jog_wheel_state() const
|
||||
{
|
||||
if ( !_jog_wheel_states.empty() )
|
||||
return _jog_wheel_states.top();
|
||||
else
|
||||
return scroll;
|
||||
}
|
||||
|
||||
void JogWheel::zoom_event( SurfacePort & port, Control & control, const ControlState & state )
|
||||
{
|
||||
}
|
||||
|
||||
void JogWheel::scrub_event( SurfacePort & port, Control & control, const ControlState & state )
|
||||
{
|
||||
}
|
||||
|
||||
void JogWheel::speed_event( SurfacePort & port, Control & control, const ControlState & state )
|
||||
{
|
||||
}
|
||||
|
||||
void JogWheel::scroll_event( SurfacePort & port, Control & control, const ControlState & state )
|
||||
{
|
||||
}
|
||||
|
||||
float scaled_delta( const ControlState & state, float current_speed )
|
||||
{
|
||||
return state.sign * ( pow( state.ticks + 1, 2 ) + current_speed ) / 100.0;
|
||||
}
|
||||
|
||||
void JogWheel::jog_event( SurfacePort & port, Control & control, const ControlState & state )
|
||||
{
|
||||
// TODO use current snap-to setting?
|
||||
#if 0
|
||||
long delta = state.ticks * sign * 1000;
|
||||
nframes_t next = session->transport_frame() + delta;
|
||||
if ( delta < 0 && session->transport_frame() < (nframes_t) abs( delta ) )
|
||||
{
|
||||
next = session->current_start_frame();
|
||||
}
|
||||
else if ( next > session->current_end_frame() )
|
||||
{
|
||||
next = session->current_end_frame();
|
||||
}
|
||||
|
||||
// doesn't work very well
|
||||
session->request_locate( next, session->transport_rolling() );
|
||||
#endif
|
||||
|
||||
switch ( jog_wheel_state() )
|
||||
{
|
||||
case scroll:
|
||||
//ScrollTimeline causes crashes
|
||||
if ( _mcp.mcu_port().emulation() == MackiePort::bcf2000 )
|
||||
_mcp.ScrollTimeline( state.ticks * state.sign / 100.0 );
|
||||
else
|
||||
_mcp.ScrollTimeline( state.ticks * state.sign / 100.0 );
|
||||
break;
|
||||
|
||||
case zoom:
|
||||
// TODO do a for loop for each, to number of ticks
|
||||
if ( state.sign > 0 )
|
||||
for ( unsigned int i = 0; i < state.ticks; ++i ) _mcp.ZoomIn();
|
||||
else
|
||||
for ( unsigned int i = 0; i < state.ticks; ++i ) _mcp.ZoomOut();
|
||||
break;
|
||||
|
||||
case speed:
|
||||
{
|
||||
// block because we initialize a variable
|
||||
// locally, _transport_speed is an absolute value...
|
||||
// fairly arbitrary scaling function
|
||||
_transport_speed += scaled_delta( state, _mcp.get_session().transport_speed() );
|
||||
|
||||
// make sure not weirdness get so the session
|
||||
if ( _transport_speed < 0 || isnan( _transport_speed ) )
|
||||
{
|
||||
_transport_speed = 0.0;
|
||||
}
|
||||
|
||||
// translated current speed to a signed transport velocity
|
||||
_mcp.get_session().request_transport_speed( transport_speed() * transport_direction() );
|
||||
break;
|
||||
}
|
||||
|
||||
case scrub:
|
||||
{
|
||||
add_scrub_interval( _scrub_timer.restart() );
|
||||
// copied from tranzport driver
|
||||
float speed = 0.0;
|
||||
|
||||
// This should really be part of the surface object
|
||||
if ( _mcp.mcu_port().emulation() == MackiePort::bcf2000 )
|
||||
// 5 clicks per second => speed == 1.0
|
||||
speed = 50.0 / average_scrub_interval() * state.ticks;
|
||||
else
|
||||
// 10 clicks per second => speed == 1.0
|
||||
speed = 100.0 / average_scrub_interval() * state.ticks;
|
||||
|
||||
_mcp.get_session().request_transport_speed( speed * state.sign );
|
||||
break;
|
||||
}
|
||||
|
||||
case shuttle:
|
||||
_shuttle_speed = _mcp.get_session().transport_speed();
|
||||
_shuttle_speed += scaled_delta( state, _mcp.get_session().transport_speed() );
|
||||
_mcp.get_session().request_transport_speed( _shuttle_speed );
|
||||
break;
|
||||
|
||||
case select:
|
||||
cout << "JogWheel select not implemented" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JogWheel::check_scrubbing()
|
||||
{
|
||||
// if the last elapsed is greater than the average + std deviation, then stop
|
||||
if ( !_scrub_intervals.empty() && _scrub_timer.elapsed() > average_scrub_interval() + std_dev_scrub_interval() )
|
||||
{
|
||||
_mcp.get_session().request_transport_speed( 0.0 );
|
||||
_scrub_intervals.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void JogWheel::push( State state )
|
||||
{
|
||||
_jog_wheel_states.push( state );
|
||||
}
|
||||
|
||||
void JogWheel::pop()
|
||||
{
|
||||
if ( _jog_wheel_states.size() > 0 )
|
||||
{
|
||||
_jog_wheel_states.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void JogWheel::zoom_state_toggle()
|
||||
{
|
||||
if ( jog_wheel_state() == zoom )
|
||||
pop();
|
||||
else
|
||||
push( zoom );
|
||||
}
|
||||
|
||||
JogWheel::State JogWheel::scrub_state_cycle()
|
||||
{
|
||||
State top = jog_wheel_state();
|
||||
if ( top == scrub )
|
||||
{
|
||||
// stop scrubbing and go to shuttle
|
||||
pop();
|
||||
push( shuttle );
|
||||
_shuttle_speed = 0.0;
|
||||
}
|
||||
else if ( top == shuttle )
|
||||
{
|
||||
// default to scroll, or the last selected
|
||||
pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// start with scrub
|
||||
push( scrub );
|
||||
}
|
||||
|
||||
return jog_wheel_state();
|
||||
}
|
||||
|
||||
void JogWheel::add_scrub_interval( unsigned long elapsed )
|
||||
{
|
||||
if ( _scrub_intervals.size() > 5 )
|
||||
{
|
||||
_scrub_intervals.pop_front();
|
||||
}
|
||||
_scrub_intervals.push_back( elapsed );
|
||||
}
|
||||
|
||||
float JogWheel::average_scrub_interval()
|
||||
{
|
||||
float sum = 0.0;
|
||||
for ( std::deque<unsigned long>::iterator it = _scrub_intervals.begin(); it != _scrub_intervals.end(); ++it )
|
||||
{
|
||||
sum += *it;
|
||||
}
|
||||
return sum / _scrub_intervals.size();
|
||||
}
|
||||
|
||||
float JogWheel::std_dev_scrub_interval()
|
||||
{
|
||||
float average = average_scrub_interval();
|
||||
|
||||
// calculate standard deviation
|
||||
float sum = 0.0;
|
||||
for ( std::deque<unsigned long>::iterator it = _scrub_intervals.begin(); it != _scrub_intervals.end(); ++it )
|
||||
{
|
||||
sum += pow( *it - average, 2 );
|
||||
}
|
||||
return sqrt( sum / _scrub_intervals.size() -1 );
|
||||
}
|
||||
102
libs/surfaces/mackie/mackie_jog_wheel.h
Normal file
102
libs/surfaces/mackie/mackie_jog_wheel.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#ifndef mackie_jog_wheel
|
||||
#define mackie_jog_wheel
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
#include <stack>
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
|
||||
class MackieControlProtocol;
|
||||
|
||||
namespace Mackie
|
||||
{
|
||||
|
||||
class SurfacePort;
|
||||
class Control;
|
||||
class ControlState;
|
||||
|
||||
/**
|
||||
A jog wheel can be used to control many things. This
|
||||
handles all of the states and state transitions.
|
||||
|
||||
Mainly it exists to avoid putting a bunch of messy
|
||||
stuff in MackieControlProtocol.
|
||||
|
||||
But it doesn't really know who it is, with stacks, queues and various
|
||||
boolean state variables.
|
||||
*/
|
||||
class JogWheel
|
||||
{
|
||||
public:
|
||||
enum State { scroll, zoom, speed, scrub, shuttle, select };
|
||||
|
||||
JogWheel( MackieControlProtocol & mcp );
|
||||
|
||||
/// As the wheel turns...
|
||||
void jog_event( SurfacePort & port, Control & control, const ControlState & state );
|
||||
|
||||
// These are for incoming button presses that change the internal state
|
||||
// but they're not actually used at the moment.
|
||||
void zoom_event( SurfacePort & port, Control & control, const ControlState & state );
|
||||
void scrub_event( SurfacePort & port, Control & control, const ControlState & state );
|
||||
void speed_event( SurfacePort & port, Control & control, const ControlState & state );
|
||||
void scroll_event( SurfacePort & port, Control & control, const ControlState & state );
|
||||
|
||||
/// Return the current jog wheel mode, which defaults to Scroll
|
||||
State jog_wheel_state() const;
|
||||
|
||||
/// The current transport speed for ffwd and rew. Can be
|
||||
/// set by wheel when they're pressed.
|
||||
float transport_speed() const { return _transport_speed; }
|
||||
|
||||
/// one of -1,0,1
|
||||
int transport_direction() const { return _transport_direction; }
|
||||
void transport_direction( int rhs ) { _transport_direction = rhs; }
|
||||
|
||||
void push( State state );
|
||||
void pop();
|
||||
|
||||
/// Turn zoom mode on and off
|
||||
void zoom_state_toggle();
|
||||
|
||||
/**
|
||||
Cycle scrub -> shuttle -> previous
|
||||
*/
|
||||
State scrub_state_cycle();
|
||||
|
||||
/// Check to see when the last scrub event was
|
||||
/// And stop scrubbing if it was too long ago.
|
||||
/// Intended to be called from a periodic timer of
|
||||
/// some kind.
|
||||
void check_scrubbing();
|
||||
|
||||
protected:
|
||||
void add_scrub_interval( unsigned long elapsed );
|
||||
float average_scrub_interval();
|
||||
float std_dev_scrub_interval();
|
||||
|
||||
private:
|
||||
MackieControlProtocol & _mcp;
|
||||
|
||||
// transport speed for ffwd and rew, controller by jog
|
||||
float _transport_speed;
|
||||
int _transport_direction;
|
||||
|
||||
/// Speed for shuttle
|
||||
float _shuttle_speed;
|
||||
|
||||
/// a stack for keeping track of states
|
||||
std::stack<State> _jog_wheel_states;
|
||||
|
||||
/// So we know how fast to set the transport speed while scrubbing
|
||||
Timer _scrub_timer;
|
||||
|
||||
/// to keep track of what the current scrub rate is
|
||||
/// so we can calculate a moving average
|
||||
std::deque<unsigned long> _scrub_intervals;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -408,9 +408,9 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes,
|
|||
ControlState state;
|
||||
|
||||
// bytes[2] & 0b01000000 (0x40) give sign
|
||||
int sign = ( bytes[2] & 0x40 ) == 0 ? 1 : -1;
|
||||
state.sign = ( bytes[2] & 0x40 ) == 0 ? 1 : -1;
|
||||
// bytes[2] & 0b00111111 (0x3f) gives delta
|
||||
state.ticks = ( bytes[2] & 0x3f) * sign;
|
||||
state.ticks = ( bytes[2] & 0x3f);
|
||||
state.delta = float( state.ticks ) / float( 0x3f );
|
||||
|
||||
control_event( *this, control, state );
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -21,12 +21,12 @@ 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,assignment,zoom,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,,scrub,1,1,0x32
|
||||
button,1,,edit,1,1,0x56
|
||||
|
||||
button,1,display,name_value,1,0,0x34
|
||||
|
|
@ -78,8 +78,8 @@ button,1,cursor,"cursor_up",1,0,0x60
|
|||
button,1,cursor,"cursor_down",1,0,0x61
|
||||
button,1,cursor,"cursor_left",1,0,0x62
|
||||
button,1,cursor,"cursor_right",1,0,0x63
|
||||
button,1,,"zoom",1,1,0x64
|
||||
button,1,,"scrub",1,1,0x65
|
||||
button,1,,"dyn",1,1,0x64
|
||||
button,1,,"flip",1,1,0x65
|
||||
button,1,user,"user_a",1,0,0x66
|
||||
button,1,user,"user_b",1,0,0x67
|
||||
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -99,7 +99,7 @@ while bytes = mck.file.read( 3 )
|
|||
control = sf.midis[midi_type][control_id]
|
||||
|
||||
print " Control Type: %-7s, " % sf.types[midi_type]
|
||||
print "id: %4i" % control_id
|
||||
print "id: %4x" % control_id
|
||||
print ", control: %15s" % ( control ? control.name : "nil control" )
|
||||
print ", %15s" % ( control ? control.group.name : "nil group" )
|
||||
print "\n"
|
||||
|
|
|
|||
|
|
@ -52,17 +52,20 @@ void Mackie::<%= sf.name %>Surface::init_controls()
|
|||
% end
|
||||
|
||||
// initialise controls
|
||||
Control * control = 0;
|
||||
Fader * fader = 0;
|
||||
Pot * pot = 0;
|
||||
Button * button = 0;
|
||||
Led * led = 0;
|
||||
|
||||
% sf.controls.each do |control|
|
||||
group = groups["<%=control.group.name%>"];
|
||||
control = new <%= control.class.name %> ( <%= control.id %>, <%= control.ordinal %>, "<%=control.name%>", *group );
|
||||
<%=control.class.name.downcase%>s[0x<%=control.id.to_hex %>] = control;
|
||||
controls.push_back( control );
|
||||
<%= 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 %> );
|
||||
<%- if control.group.class != Strip -%>
|
||||
controls_by_name["<%= control.name %>"] = control;
|
||||
controls_by_name["<%= control.name %>"] = <%= control.class.name.downcase %>;
|
||||
<%- end -%>
|
||||
group->add( *control );
|
||||
group->add( *<%= control.class.name.downcase %> );
|
||||
|
||||
% end
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ public:
|
|||
|
||||
Indexed by raw_id not by id. @see Control for the distinction.
|
||||
*/
|
||||
std::map<int,Control*> faders;
|
||||
std::map<int,Control*> pots;
|
||||
std::map<int,Control*> buttons;
|
||||
std::map<int,Control*> leds;
|
||||
std::map<int,Fader*> faders;
|
||||
std::map<int,Pot*> pots;
|
||||
std::map<int,Button*> buttons;
|
||||
std::map<int,Led*> leds;
|
||||
|
||||
/// no strip controls in here because they usually
|
||||
/// have the same names.
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ MidiByteArray SurfacePort::read()
|
|||
retval.copy( nread, buf );
|
||||
if ((size_t) nread == sizeof (buf))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef PORT_DEBUG
|
||||
cout << "SurfacePort::read recursive" << endl;
|
||||
#endif
|
||||
retval << read();
|
||||
|
|
@ -106,7 +106,7 @@ MidiByteArray SurfacePort::read()
|
|||
throw MackieControlException( os.str() );
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
#ifdef PORT_DEBUG
|
||||
cout << "SurfacePort::read: " << retval << endl;
|
||||
#endif
|
||||
return retval;
|
||||
|
|
@ -114,7 +114,7 @@ MidiByteArray SurfacePort::read()
|
|||
|
||||
void SurfacePort::write( const MidiByteArray & mba )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef PORT_DEBUG
|
||||
//if ( mba[0] == 0xf0 ) cout << "SurfacePort::write: " << mba << endl;
|
||||
cout << "SurfacePort::write: " << mba << endl;
|
||||
#endif
|
||||
|
|
@ -140,7 +140,7 @@ void SurfacePort::write( const MidiByteArray & mba )
|
|||
throw MackieControlException( os.str() );
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
#ifdef PORT_DEBUG
|
||||
cout << "SurfacePort::wrote " << count << endl;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
if ( shouldStart )
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start the timer running. Return the current timestamp, in milliseconds
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,8 +2,28 @@
|
|||
|
||||
namespace Mackie
|
||||
{
|
||||
LedState on( LedState::on );
|
||||
LedState off( LedState::off );
|
||||
LedState flashing( LedState::flashing );
|
||||
LedState none( LedState::none );
|
||||
LedState on( LedState::on );
|
||||
LedState off( LedState::off );
|
||||
LedState flashing( LedState::flashing );
|
||||
LedState none( LedState::none );
|
||||
|
||||
std::ostream & operator << ( std::ostream & os, const ControlState & cs )
|
||||
{
|
||||
os << "ControlState { ";
|
||||
os << "pos: " << cs.pos;
|
||||
os << ", ";
|
||||
os << "sign: " << cs.sign;
|
||||
os << ", ";
|
||||
os << "delta: " << cs.delta;
|
||||
os << ", ";
|
||||
os << "ticks: " << cs.ticks;
|
||||
os << ", ";
|
||||
os << "led_state: " << cs.led_state.state();
|
||||
os << ", ";
|
||||
os << "button_state: " << cs.button_state;
|
||||
os << " }";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef mackie_types_h
|
||||
#define mackie_types_h
|
||||
|
||||
#define DEBUG 1
|
||||
#include <iostream>
|
||||
|
||||
namespace Mackie
|
||||
{
|
||||
|
|
@ -71,16 +71,27 @@ struct ControlState
|
|||
// Note that this sets both pos and delta to the flt value
|
||||
ControlState( LedState ls, float flt ): pos(flt), delta(flt), ticks(0), led_state(ls), button_state(neither) {}
|
||||
ControlState( float flt ): pos(flt), delta(flt), ticks(0), led_state(none), button_state(neither) {}
|
||||
ControlState( float flt, int tcks ): pos(flt), delta(flt), ticks(tcks), led_state(none), button_state(neither) {}
|
||||
ControlState( float flt, unsigned int tcks ): pos(flt), delta(flt), ticks(tcks), led_state(none), button_state(neither) {}
|
||||
ControlState( ButtonState bs ): pos(0.0), delta(0.0), ticks(0), led_state(none), button_state(bs) {}
|
||||
|
||||
/// For faders. Between 0 and 1.
|
||||
float pos;
|
||||
|
||||
/// For pots. Sign. Either -1 or 1;
|
||||
int sign;
|
||||
|
||||
/// For pots. Signed value of total movement. Between 0 and 1
|
||||
float delta;
|
||||
int ticks;
|
||||
|
||||
/// For pots. Unsigned number of ticks. Usually between 1 and 16.
|
||||
unsigned int ticks;
|
||||
|
||||
LedState led_state;
|
||||
ButtonState button_state;
|
||||
};
|
||||
|
||||
std::ostream & operator << ( std::ostream &, const ControlState & );
|
||||
|
||||
class Control;
|
||||
class Fader;
|
||||
class Button;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue