MCP: drastically alter setup of Mackie surface to not use the CSV files in anyway, reformat chunks to match coding style standards, don't throw() if part of a sysex message is message

git-svn-id: svn://localhost/ardour2/branches/3.0@11820 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2012-04-07 18:43:06 +00:00
parent 9cdeaa30b9
commit a202b08f65
11 changed files with 1690 additions and 2444 deletions

View File

@@ -6,37 +6,41 @@
using namespace Mackie;
void BcfSurface::display_bank_start( SurfacePort & port, MackieMidiBuilder & builder, uint32_t current_bank )
void BcfSurface::display_bank_start (SurfacePort & port, MackieMidiBuilder & builder, uint32_t current_bank)
{
if ( current_bank == 0 )
{
if (current_bank == 0) {
// send Ar. to 2-char display on the master
port.write( builder.two_char_display( "Ar", ".." ) );
}
else
{
port.write (builder.two_char_display ("Ar", ".."));
} else {
// write the current first remote_id to the 2-char display
port.write( builder.two_char_display( current_bank ) );
port.write (builder.two_char_display (current_bank));
}
}
void BcfSurface::zero_all( SurfacePort & port, MackieMidiBuilder & builder )
void
BcfSurface::zero_all (SurfacePort & port, MackieMidiBuilder & builder)
{
// clear 2-char display
port.write( builder.two_char_display( "LC" ) );
port.write (builder.two_char_display ("LC"));
// and the led ring for the master strip
blank_jog_ring( port, builder );
blank_jog_ring (port, builder);
}
void BcfSurface::blank_jog_ring( SurfacePort & port, MackieMidiBuilder & builder )
void
BcfSurface::blank_jog_ring (SurfacePort & port, MackieMidiBuilder & builder)
{
Control & control = *controls_by_name["jog"];
port.write( builder.build_led_ring( dynamic_cast<Pot &>( control ), off ) );
port.write (builder.build_led_ring (dynamic_cast<Pot &> (control), off));
}
float BcfSurface::scaled_delta( const ControlState & state, float current_speed )
float
BcfSurface::scaled_delta (const ControlState & state, float current_speed)
{
return state.sign * ( std::pow( float(state.ticks + 1), 2 ) + current_speed ) / 100.0;
return state.sign * (std::pow (float(state.ticks + 1), 2) + current_speed) / 100.0;
}
void
BcfSurface::init_strips ()
{
}

View File

@@ -18,7 +18,8 @@ public:
virtual void handle_button( MackieButtonHandler & mbh, ButtonState bs, Button & button );
virtual void init_controls();
virtual void init_strips ();
virtual void display_bank_start( SurfacePort & port, MackieMidiBuilder & builder, uint32_t current_bank );
virtual void zero_all( SurfacePort & port, MackieMidiBuilder & builder );
virtual void blank_jog_ring( SurfacePort & port, MackieMidiBuilder & builder );

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,12 @@
using namespace Mackie;
using namespace std;
uint32_t Control::button_cnt = 0;
uint32_t Control::pot_cnt = 0;
uint32_t Control::fader_cnt = 0;
uint32_t Control::led_cnt = 0;
uint32_t Control::jog_cnt = 0;
void Group::add( Control & control )
{
_controls.push_back( &control );

View File

@@ -38,8 +38,8 @@ class Control;
class Group
{
public:
Group( const std::string & name )
: _name( name )
Group (const std::string & name)
: _name (name)
{
}
@@ -55,7 +55,7 @@ public:
return false;
}
virtual void add( Control & control );
virtual void add (Control & control);
const std::string & name() const
{
@@ -63,7 +63,7 @@ public:
}
// This is for Surface only
void name( const std::string & rhs ) { _name = rhs; }
void name (const std::string & rhs) { _name = rhs; }
typedef std::vector<Control*> Controls;
const Controls & controls() const { return _controls; }
@@ -88,21 +88,22 @@ public:
/**
\param is the index of the strip. 0-based.
*/
Strip( const std::string & name, int index );
Strip (const std::string & name, int index);
Strip (const Strip& other);
virtual bool is_strip() const
{
return true;
}
virtual void add( Control & control );
virtual void add (Control & control);
/// This is the index of the strip. zero-based.
int index() const { return _index; }
/// This is for Surface only
/// index is zero-based
void index( int rhs ) { _index = rhs; }
void index (int rhs) { _index = rhs; }
Button & solo();
Button & recenable();
@@ -134,20 +135,15 @@ private:
int _index;
};
std::ostream & operator << ( std::ostream &, const Strip & );
std::ostream & operator << (std::ostream &, const Strip &);
class MasterStrip : public Strip
{
public:
MasterStrip( const std::string & name, int index )
: Strip( name, index )
{
}
MasterStrip (const std::string & name, int index)
: Strip (name, index) {}
virtual bool is_master() const
{
return true;
}
virtual bool is_master() const { return true; }
};
class Led;
@@ -159,22 +155,22 @@ class Led;
class Control
{
public:
enum type_t { type_led, type_led_ring, type_fader = 0xe0, type_button = 0x90, type_pot = 0xb0 };
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 );
Control (int id, int ordinal, std::string name, Group & group);
virtual ~Control() {}
virtual const Led & led() const
{
throw MackieControlException( "no led available" );
}
virtual const Led & led() const { throw MackieControlException ("no led available"); }
/// type() << 8 + midi id of the control. This
/// provides a unique id for any control on the surface.
int id() const
{
return ( type() << 8 ) + _id;
}
int id() const { return (type() << 8) + _id; }
/// the value of the second bytes of the message. It's
/// the id of the control, but only guaranteed to be
@@ -184,30 +180,11 @@ public:
/// The 1-based number of the control
int ordinal() const { return _ordinal; }
const std::string & name() const
{
return _name;
}
const Group & group() const
{
return _group;
}
const Strip & strip() const
{
return dynamic_cast<const Strip&>( _group );
}
Strip & strip()
{
return dynamic_cast<Strip&>( _group );
}
virtual bool accepts_feedback() const
{
return true;
}
const std::string & name() const { return _name; }
const Group & group() const { return _group; }
const Strip & strip() const { return dynamic_cast<const Strip&> (_group); }
Strip & strip() { return dynamic_cast<Strip&> (_group); }
virtual bool accepts_feedback() const { return true; }
virtual type_t type() const = 0;
@@ -224,7 +201,13 @@ public:
* is its touch button control; otherwise 0.
*/
Control* in_use_touch_control;
static uint32_t button_cnt;
static uint32_t pot_cnt;
static uint32_t fader_cnt;
static uint32_t led_cnt;
static uint32_t jog_cnt;
private:
int _id;
int _ordinal;
@@ -233,13 +216,13 @@ private:
bool _in_use;
};
std::ostream & operator << ( std::ostream & os, const Control & control );
std::ostream & operator << (std::ostream & os, const Control & control);
class Fader : public Control
{
public:
Fader( int id, int ordinal, std::string name, Group & group )
: Control( id, ordinal, name, group )
Fader (int ordinal, std::string name, Group & group)
: Control (Control::fader_cnt++, ordinal, name, group)
{
}
@@ -249,8 +232,8 @@ public:
class Led : public Control
{
public:
Led( int id, int ordinal, std::string name, Group & group )
: Control( id, ordinal, name, group )
Led (int ordinal, std::string name, Group & group)
: Control (Control::led_cnt++, ordinal, name, group)
{
}
@@ -262,16 +245,11 @@ public:
class Button : public Control
{
public:
Button( int id, int ordinal, std::string name, Group & group )
: Control( id, ordinal, name, group )
, _led( id, ordinal, name + "_led", group )
{
}
Button (int ordinal, std::string name, Group & group)
: Control (Control::button_cnt++, ordinal, name, group)
, _led (ordinal, name + "_led", group) {}
virtual const Led & led() const
{
return _led;
}
virtual const Led & led() const { return _led; }
virtual type_t type() const { return type_button; };
@@ -282,8 +260,8 @@ private:
class LedRing : public Led
{
public:
LedRing( int id, int ordinal, std::string name, Group & group )
: Led( id, ordinal, name, group )
LedRing (int ordinal, std::string name, Group & group)
: Led (ordinal, name, group)
{
}
@@ -293,18 +271,17 @@ public:
class Pot : public Control
{
public:
Pot( int id, int ordinal, std::string name, Group & group )
: Control( id, ordinal, name, group )
, _led_ring( id, ordinal, name + "_ring", group )
{
}
Pot (int ordinal, std::string name, Group & group)
: Control (Control::pot_cnt++, ordinal, name, group)
, _led_ring (ordinal, name + "_ring", group) {}
Pot (int id, int ordinal, std::string name, Group & group)
: Control (id, ordinal, name, group)
, _led_ring (ordinal, name + "_ring", group) {}
virtual type_t type() const { return type_pot; }
virtual const LedRing & led_ring() const
{
return _led_ring;
}
virtual const LedRing & led_ring() const {return _led_ring; }
private:
LedRing _led_ring;
@@ -313,8 +290,8 @@ private:
class Jog : public Pot
{
public:
Jog( int id, int ordinal, std::string name, Group & group )
: Pot( id, ordinal, name, group )
Jog (int ordinal, std::string name, Group & group)
: Pot (Control::jog_cnt++, ordinal, name, group)
{
}

View File

@@ -43,17 +43,17 @@ using namespace ARDOUR;
using namespace PBD;
// The MCU sysex header
MidiByteArray mackie_sysex_hdr ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10 );
MidiByteArray mackie_sysex_hdr (5, MIDI::sysex, 0x0, 0x0, 0x66, 0x10);
// The MCU extender sysex header
MidiByteArray mackie_sysex_hdr_xt ( 5, MIDI::sysex, 0x0, 0x0, 0x66, 0x11 );
MidiByteArray mackie_sysex_hdr_xt (5, MIDI::sysex, 0x0, 0x0, 0x66, 0x11);
MackiePort::MackiePort (MackieControlProtocol & mcp, MIDI::Port & input_port, MIDI::Port & output_port, int number, port_type_t port_type)
: SurfacePort (input_port, output_port, number)
, _mcp( mcp )
, _port_type( port_type )
, _emulation( none )
, _initialising( true )
, _mcp (mcp)
, _port_type (port_type)
, _emulation (none)
, _initialising (true)
{
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::MackiePort\n");
}
@@ -67,16 +67,16 @@ MackiePort::~MackiePort()
int MackiePort::strips() const
{
if ( _port_type == mcu )
if (_port_type == mcu)
{
switch ( _emulation )
switch (_emulation)
{
// BCF2000 only has 8 faders, so reserve one for master
case bcf2000: return 7;
case mackie: return 8;
case none:
default:
throw MackieControlException( "MackiePort::strips: don't know what emulation we're using" );
throw MackieControlException ("MackiePort::strips: don't know what emulation we're using");
}
}
else
@@ -110,7 +110,7 @@ void MackiePort::close()
const MidiByteArray & MackiePort::sysex_hdr() const
{
switch ( _port_type )
switch (_port_type)
{
case mcu: return mackie_sysex_hdr;
case ext: return mackie_sysex_hdr_xt;
@@ -119,62 +119,59 @@ const MidiByteArray & MackiePort::sysex_hdr() const
return mackie_sysex_hdr;
}
MidiByteArray calculate_challenge_response( MidiByteArray::iterator begin, MidiByteArray::iterator end )
MidiByteArray calculate_challenge_response (MidiByteArray::iterator begin, MidiByteArray::iterator end)
{
MidiByteArray l;
back_insert_iterator<MidiByteArray> back ( l );
copy( begin, end, back );
back_insert_iterator<MidiByteArray> back (l);
copy (begin, end, back);
MidiByteArray retval;
// this is how to calculate the response to the challenge.
// from the Logic docs.
retval << ( 0x7f & ( l[0] + ( l[1] ^ 0xa ) - l[3] ) );
retval << ( 0x7f & ( ( l[2] >> l[3] ) ^ ( l[0] + l[3] ) ) );
retval << ( 0x7f & ( (l[3] - ( l[2] << 2 )) ^ ( l[0] | l[1] ) ) );
retval << ( 0x7f & ( l[1] - l[2] + ( 0xf0 ^ ( l[3] << 4 ) ) ) );
retval << (0x7f & (l[0] + (l[1] ^ 0xa) - l[3]));
retval << (0x7f & ( (l[2] >> l[3]) ^ (l[0] + l[3])));
retval << (0x7f & ((l[3] - (l[2] << 2)) ^ (l[0] | l[1])));
retval << (0x7f & (l[1] - l[2] + (0xf0 ^ (l[3] << 4))));
return retval;
}
// not used right now
MidiByteArray MackiePort::host_connection_query( MidiByteArray & bytes )
MidiByteArray MackiePort::host_connection_query (MidiByteArray & bytes)
{
// handle host connection query
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host connection query: %1\n", bytes));
if ( bytes.size() != 18 )
{
finalise_init( false );
ostringstream os;
os << "expecting 18 bytes, read " << bytes << " from " << input_port().name();
throw MackieControlException( os.str() );
if (bytes.size() != 18) {
finalise_init (false);
cerr << "expecting 18 bytes, read " << bytes << " from " << input_port().name() << endl;
return;
}
// build and send host connection reply
MidiByteArray response;
response << 0x02;
copy( bytes.begin() + 6, bytes.begin() + 6 + 7, back_inserter( response ) );
response << calculate_challenge_response( bytes.begin() + 6 + 7, bytes.begin() + 6 + 7 + 4 );
copy (bytes.begin() + 6, bytes.begin() + 6 + 7, back_inserter (response));
response << calculate_challenge_response (bytes.begin() + 6 + 7, bytes.begin() + 6 + 7 + 4);
return response;
}
// not used right now
MidiByteArray MackiePort::host_connection_confirmation( const MidiByteArray & bytes )
MidiByteArray MackiePort::host_connection_confirmation (const MidiByteArray & bytes)
{
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("host_connection_confirmation: %1\n", bytes));
// decode host connection confirmation
if ( bytes.size() != 14 )
{
finalise_init( false );
if (bytes.size() != 14) {
finalise_init (false);
ostringstream os;
os << "expecting 14 bytes, read " << bytes << " from " << input_port().name();
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
// send version request
return MidiByteArray( 2, 0x13, 0x00 );
return MidiByteArray (2, 0x13, 0x00);
}
void MackiePort::probe_emulation (const MidiByteArray &)
@@ -183,7 +180,7 @@ void MackiePort::probe_emulation (const MidiByteArray &)
cout << "MackiePort::probe_emulation: " << bytes.size() << ", " << bytes << endl;
MidiByteArray version_string;
for ( int i = 6; i < 11; ++i ) version_string << bytes[i];
for (int i = 6; i < 11; ++i) version_string << bytes[i];
cout << "version_string: " << version_string << endl;
#endif
@@ -196,7 +193,7 @@ void MackiePort::probe_emulation (const MidiByteArray &)
return;
}
finalise_init( true );
finalise_init (true);
}
void MackiePort::init()
@@ -216,12 +213,12 @@ void MackiePort::init()
// 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 ) );
//write_sysex (MidiByteArray (2, 0x13, 0x00));
finalise_init( true );
finalise_init (true);
}
void MackiePort::finalise_init( bool yn )
void MackiePort::finalise_init (bool yn)
{
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::finalise_init\n");
@@ -232,15 +229,15 @@ void MackiePort::finalise_init( bool yn )
// TODO This might have to be specified on a per-port basis
// in the config file
// if an mcu and a bcf are needed to work as one surface
if ( _emulation == none )
if (_emulation == none)
{
// TODO same as code in mackie_control_protocol.cc
if ( ARDOUR::Config->get_mackie_emulation() == "bcf" )
if (ARDOUR::Config->get_mackie_emulation() == "bcf")
{
_emulation = bcf2000;
emulation_ok = true;
}
else if ( ARDOUR::Config->get_mackie_emulation() == "mcu" )
else if (ARDOUR::Config->get_mackie_emulation() == "mcu")
{
_emulation = mackie;
emulation_ok = true;
@@ -254,7 +251,7 @@ void MackiePort::finalise_init( bool yn )
yn = yn && emulation_ok;
SurfacePort::active( yn );
SurfacePort::active (yn);
if (yn) {
active_event();
@@ -279,25 +276,25 @@ void MackiePort::connect_any()
bool MackiePort::wait_for_init()
{
Glib::Mutex::Lock lock( init_mutex );
Glib::Mutex::Lock lock (init_mutex);
while (_initialising) {
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active waiting\n");
init_cond.wait( init_mutex );
init_cond.wait (init_mutex);
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active released\n");
}
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::wait_for_active returning\n");
return SurfacePort::active();
}
void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count)
{
MidiByteArray bytes( count, raw_bytes );
MidiByteArray bytes (count, raw_bytes);
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handle_midi_sysex: %1\n", bytes));
switch( bytes[5] )
switch (bytes[5])
{
case 0x01:
// not used right now
write_sysex (host_connection_query (bytes));
break;
case 0x03:
@@ -316,7 +313,7 @@ void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size
}
}
Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
Control & MackiePort::lookup_control (MIDI::byte * bytes, size_t count)
{
// Don't instantiate a MidiByteArray here unless it's needed for exceptions.
// Reason being that this method is called for every single incoming
@@ -331,12 +328,12 @@ Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
{
int midi_id = bytes[0] & 0x0f;
control = _mcp.surface().faders[midi_id];
if ( control == 0 )
if (control == 0)
{
MidiByteArray mba( count, bytes );
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Control for fader" << bytes << " id " << midi_id << " is null";
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
break;
}
@@ -344,32 +341,32 @@ Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
// button
case MackieMidiBuilder::midi_button_id:
control = _mcp.surface().buttons[bytes[1]];
if ( control == 0 )
if (control == 0)
{
MidiByteArray mba( count, bytes );
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Control for button " << mba << " is null";
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
break;
// pot (jog wheel, external control)
case MackieMidiBuilder::midi_pot_id:
control = _mcp.surface().pots[bytes[1]];
if ( control == 0 )
if (control == 0)
{
MidiByteArray mba( count, bytes );
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Control for rotary " << mba << " is null";
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
break;
default:
MidiByteArray mba( count, bytes );
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Cannot find control for " << mba;
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
return *control;
}
@@ -377,25 +374,25 @@ Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
// converts midi messages into control_event signals
// it might be worth combining this with lookup_control
// because they have similar logic flows.
void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count )
void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count)
{
MidiByteArray bytes( count, raw_bytes );
MidiByteArray bytes (count, raw_bytes);
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::handle_midi_any %1\n", bytes));
try
{
// ignore sysex messages
if ( raw_bytes[0] == MIDI::sysex ) return;
if (raw_bytes[0] == MIDI::sysex) return;
// sanity checking
if (count != 3) {
ostringstream os;
MidiByteArray mba( count, raw_bytes );
MidiByteArray mba (count, raw_bytes);
os << "MackiePort::handle_midi_any needs 3 bytes, but received " << mba;
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
Control & control = lookup_control( raw_bytes, count );
Control & control = lookup_control (raw_bytes, count);
control.set_in_use (true);
// This handles incoming bytes. Outgoing bytes
@@ -405,21 +402,21 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
case Control::type_fader:
{
// only the top-order 10 bits out of 14 are used
int midi_pos = ( ( raw_bytes[2] << 7 ) + raw_bytes[1] ) >> 4;
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) );
control_event (*this, control, float(midi_pos) / float(0x3ff));
}
break;
// button
case Control::type_button:
{
ControlState control_state( raw_bytes[2] == 0x7f ? press : release );
ControlState control_state (raw_bytes[2] == 0x7f ? press : release);
control.set_in_use (control_state.button_state == press);
control_event( *this, control, control_state );
control_event (*this, control, control_state);
break;
}
@@ -430,16 +427,16 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
ControlState state;
// bytes[2] & 0b01000000 (0x40) give sign
state.sign = ( raw_bytes[2] & 0x40 ) == 0 ? 1 : -1;
state.sign = (raw_bytes[2] & 0x40) == 0 ? 1 : -1;
// bytes[2] & 0b00111111 (0x3f) gives delta
state.ticks = ( raw_bytes[2] & 0x3f);
state.ticks = (raw_bytes[2] & 0x3f);
if (state.ticks == 0) {
/* euphonix and perhaps other devices send zero
when they mean 1, we think.
*/
state.ticks = 1;
}
state.delta = float( state.ticks ) / float( 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.
@@ -449,7 +446,7 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
add_in_use_timeout (control, &control);
// emit the control event
control_event( *this, control, state );
control_event (*this, control, state);
break;
}
default:
@@ -457,8 +454,8 @@ void MackiePort::handle_midi_any (MIDI::Parser &, MIDI::byte * raw_bytes, size_t
}
}
catch( MackieControlException & e ) {
MidiByteArray bytes( count, raw_bytes );
catch (MackieControlException & e) {
MidiByteArray bytes (count, raw_bytes);
cout << bytes << ' ' << e.what() << endl;
}

View File

@@ -1,18 +1,629 @@
#include <cmath>
#include <sstream>
#include <string>
#include "mackie_surface.h"
#include "surface_port.h"
#include "mackie_midi_builder.h"
#include <cmath>
#include <string>
using namespace Mackie;
void MackieSurface::display_timecode( SurfacePort & port, MackieMidiBuilder & builder, const std::string & timecode, const std::string & timecode_last )
void
MackieSurface::display_timecode( SurfacePort & port, MackieMidiBuilder & builder, const std::string & timecode, const std::string & timecode_last )
{
port.write( builder.timecode_display( port, timecode, timecode_last ) );
}
float MackieSurface::scaled_delta( const ControlState & state, float current_speed )
float
MackieSurface::scaled_delta( const ControlState & state, float current_speed )
{
return state.sign * ( std::pow( float(state.ticks + 1), 2 ) + current_speed ) / 100.0;
}
void
Mackie::MackieSurface::init_controls()
{
Pot* pot = 0;
Button* button = 0;
Led* led = 0;
// intialise groups and strips
Group * group = 0;
// make sure there are enough strips
strips.resize (8);
group = new Group ("user");
groups["user"] = group;
group = new Group ("assignment");
groups["assignment"] = group;
group = new Group ("none");
groups["none"] = group;
group = new MasterStrip ("master", 0);
groups["master"] = group;
strips[0] = dynamic_cast<Strip*> (group);
group = new Group ("cursor");
groups["cursor"] = group;
group = new Group ("functions");
groups["functions"] = group;
group = new Group ("automation");
groups["automation"] = group;
group = new Group ("display");
groups["display"] = group;
group = new Group ("transport");
groups["transport"] = group;
group = new Group ("modifiers");
groups["modifiers"] = group;
group = new Group ("bank");
groups["bank"] = group;
group = groups["none"];
pot = new Jog (1, "jog", *group);
pots[0x3c] = pot;
controls.push_back (pot);
controls_by_name["jog"] = pot;
group->add (*pot);
group = groups["none"];
pot = new Pot (1, "external", *group);
pots[0x2e] = pot;
controls.push_back (pot);
controls_by_name["external"] = pot;
group->add (*pot);
group = groups["assignment"];
button = new Button (1, "io", *group);
buttons[0x28] = button;
controls.push_back (button);
controls_by_name["io"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "sends", *group);
buttons[0x29] = button;
controls.push_back (button);
controls_by_name["sends"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "pan", *group);
buttons[0x2a] = button;
controls.push_back (button);
controls_by_name["pan"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "plugin", *group);
buttons[0x2b] = button;
controls.push_back (button);
controls_by_name["plugin"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "eq", *group);
buttons[0x2c] = button;
controls.push_back (button);
controls_by_name["eq"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "dyn", *group);
buttons[0x2d] = button;
controls.push_back (button);
controls_by_name["dyn"] = button;
group->add (*button);
group = groups["bank"];
button = new Button (1, "left", *group);
buttons[0x2e] = button;
controls.push_back (button);
controls_by_name["left"] = button;
group->add (*button);
group = groups["bank"];
button = new Button (1, "right", *group);
buttons[0x2f] = button;
controls.push_back (button);
controls_by_name["right"] = button;
group->add (*button);
group = groups["bank"];
button = new Button (1, "channel_left", *group);
buttons[0x30] = button;
controls.push_back (button);
controls_by_name["channel_left"] = button;
group->add (*button);
group = groups["bank"];
button = new Button (1, "channel_right", *group);
buttons[0x31] = button;
controls.push_back (button);
controls_by_name["channel_right"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "flip", *group);
buttons[0x32] = button;
controls.push_back (button);
controls_by_name["flip"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "edit", *group);
buttons[0x33] = button;
controls.push_back (button);
controls_by_name["edit"] = button;
group->add (*button);
group = groups["display"];
button = new Button (1, "name_value", *group);
buttons[0x34] = button;
controls.push_back (button);
controls_by_name["name_value"] = button;
group->add (*button);
group = groups["display"];
button = new Button (1, "timecode_beats", *group);
buttons[0x35] = button;
controls.push_back (button);
controls_by_name["timecode_beats"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F1", *group);
buttons[0x36] = button;
controls.push_back (button);
controls_by_name["F1"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F2", *group);
buttons[0x37] = button;
controls.push_back (button);
controls_by_name["F2"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F3", *group);
buttons[0x38] = button;
controls.push_back (button);
controls_by_name["F3"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F4", *group);
buttons[0x39] = button;
controls.push_back (button);
controls_by_name["F4"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F5", *group);
buttons[0x3a] = button;
controls.push_back (button);
controls_by_name["F5"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F6", *group);
buttons[0x3b] = button;
controls.push_back (button);
controls_by_name["F6"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F7", *group);
buttons[0x3c] = button;
controls.push_back (button);
controls_by_name["F7"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F8", *group);
buttons[0x3d] = button;
controls.push_back (button);
controls_by_name["F8"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F9", *group);
buttons[0x3e] = button;
controls.push_back (button);
controls_by_name["F9"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F10", *group);
buttons[0x3f] = button;
controls.push_back (button);
controls_by_name["F10"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F11", *group);
buttons[0x40] = button;
controls.push_back (button);
controls_by_name["F11"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F12", *group);
buttons[0x41] = button;
controls.push_back (button);
controls_by_name["F12"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F13", *group);
buttons[0x42] = button;
controls.push_back (button);
controls_by_name["F13"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F14", *group);
buttons[0x43] = button;
controls.push_back (button);
controls_by_name["F14"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F15", *group);
buttons[0x44] = button;
controls.push_back (button);
controls_by_name["F15"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "F16", *group);
buttons[0x45] = button;
controls.push_back (button);
controls_by_name["F16"] = button;
group->add (*button);
group = groups["modifiers"];
button = new Button (1, "shift", *group);
buttons[0x46] = button;
controls.push_back (button);
controls_by_name["shift"] = button;
group->add (*button);
group = groups["modifiers"];
button = new Button (1, "option", *group);
buttons[0x47] = button;
controls.push_back (button);
controls_by_name["option"] = button;
group->add (*button);
group = groups["modifiers"];
button = new Button (1, "control", *group);
buttons[0x48] = button;
controls.push_back (button);
controls_by_name["control"] = button;
group->add (*button);
group = groups["modifiers"];
button = new Button (1, "cmd_alt", *group);
buttons[0x49] = button;
controls.push_back (button);
controls_by_name["cmd_alt"] = button;
group->add (*button);
group = groups["automation"];
button = new Button (1, "on", *group);
buttons[0x4a] = button;
controls.push_back (button);
controls_by_name["on"] = button;
group->add (*button);
group = groups["automation"];
button = new Button (1, "rec_ready", *group);
buttons[0x4b] = button;
controls.push_back (button);
controls_by_name["rec_ready"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "undo", *group);
buttons[0x4c] = button;
controls.push_back (button);
controls_by_name["undo"] = button;
group->add (*button);
group = groups["automation"];
button = new Button (1, "snapshot", *group);
buttons[0x4d] = button;
controls.push_back (button);
controls_by_name["snapshot"] = button;
group->add (*button);
group = groups["automation"];
button = new Button (1, "touch", *group);
buttons[0x4e] = button;
controls.push_back (button);
controls_by_name["touch"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "redo", *group);
buttons[0x4f] = button;
controls.push_back (button);
controls_by_name["redo"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "marker", *group);
buttons[0x50] = button;
controls.push_back (button);
controls_by_name["marker"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "enter", *group);
buttons[0x51] = button;
controls.push_back (button);
controls_by_name["enter"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "cancel", *group);
buttons[0x52] = button;
controls.push_back (button);
controls_by_name["cancel"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "mixer", *group);
buttons[0x53] = button;
controls.push_back (button);
controls_by_name["mixer"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "frm_left", *group);
buttons[0x54] = button;
controls.push_back (button);
controls_by_name["frm_left"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "frm_right", *group);
buttons[0x55] = button;
controls.push_back (button);
controls_by_name["frm_right"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "loop", *group);
buttons[0x56] = button;
controls.push_back (button);
controls_by_name["loop"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "punch_in", *group);
buttons[0x57] = button;
controls.push_back (button);
controls_by_name["punch_in"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "punch_out", *group);
buttons[0x58] = button;
controls.push_back (button);
controls_by_name["punch_out"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "home", *group);
buttons[0x59] = button;
controls.push_back (button);
controls_by_name["home"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "end", *group);
buttons[0x5a] = button;
controls.push_back (button);
controls_by_name["end"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "rewind", *group);
buttons[0x5b] = button;
controls.push_back (button);
controls_by_name["rewind"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "ffwd", *group);
buttons[0x5c] = button;
controls.push_back (button);
controls_by_name["ffwd"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "stop", *group);
buttons[0x5d] = button;
controls.push_back (button);
controls_by_name["stop"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "play", *group);
buttons[0x5e] = button;
controls.push_back (button);
controls_by_name["play"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "record", *group);
buttons[0x5f] = button;
controls.push_back (button);
controls_by_name["record"] = button;
group->add (*button);
group = groups["cursor"];
button = new Button (1, "cursor_up", *group);
buttons[0x60] = button;
controls.push_back (button);
controls_by_name["cursor_up"] = button;
group->add (*button);
group = groups["cursor"];
button = new Button (1, "cursor_down", *group);
buttons[0x61] = button;
controls.push_back (button);
controls_by_name["cursor_down"] = button;
group->add (*button);
group = groups["cursor"];
button = new Button (1, "cursor_left", *group);
buttons[0x62] = button;
controls.push_back (button);
controls_by_name["cursor_left"] = button;
group->add (*button);
group = groups["cursor"];
button = new Button (1, "cursor_right", *group);
buttons[0x63] = button;
controls.push_back (button);
controls_by_name["cursor_right"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "zoom", *group);
buttons[0x64] = button;
controls.push_back (button);
controls_by_name["zoom"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "scrub", *group);
buttons[0x65] = button;
controls.push_back (button);
controls_by_name["scrub"] = button;
group->add (*button);
group = groups["user"];
button = new Button (1, "user_a", *group);
buttons[0x66] = button;
controls.push_back (button);
controls_by_name["user_a"] = button;
group->add (*button);
group = groups["user"];
button = new Button (1, "user_b", *group);
buttons[0x67] = button;
controls.push_back (button);
controls_by_name["user_b"] = button;
group->add (*button);
group = groups["master"];
button = new Button (1, "fader_touch", *group);
buttons[0x70] = button;
controls.push_back (button);
group->add (*button);
group = groups["none"];
led = new Led (1, "timecode", *group);
leds[0x71] = led;
controls.push_back (led);
controls_by_name["timecode"] = led;
group->add (*led);
group = groups["none"];
led = new Led (1, "beats", *group);
leds[0x72] = led;
controls.push_back (led);
controls_by_name["beats"] = led;
group->add (*led);
group = groups["none"];
led = new Led (1, "solo", *group);
leds[0x73] = led;
controls.push_back (led);
controls_by_name["solo"] = led;
group->add (*led);
group = groups["none"];
led = new Led (1, "relay_click", *group);
leds[0x76] = led;
controls.push_back (led);
controls_by_name["relay_click"] = led;
group->add (*led);
}
void MackieSurface::init_strips ()
{
Fader* fader = 0;
Pot* pot = 0;
Button* button = 0;
for (uint32_t i = 0; i < _max_strips; ++i) {
std::ostringstream os;
uint32_t unit_index = i % _unit_strips;
uint32_t unit_ordinal = unit_index + 1;
os << "strip_" << unit_ordinal;
std::string name = os.str();
Strip* strip = new Strip (name, i);
groups[name] = strip;
strips[i] = strip;
fader = new Fader (unit_ordinal, "gain", *strip);
faders[0x00+unit_index] = fader;
controls.push_back (fader);
strip->add (*fader);
pot = new Pot (unit_ordinal, "vpot", *strip);
pots[0x10+unit_index] = pot;
controls.push_back (pot);
strip->add (*pot);
button = new Button (unit_ordinal, "recenable", *strip);
buttons[0x00+unit_index] = button;
controls.push_back (button);
strip->add (*button);
button = new Button (unit_ordinal, "solo", *strip);
buttons[0x08+unit_index] = button;
controls.push_back (button);
strip->add (*button);
button = new Button (unit_ordinal, "mute", *strip);
buttons[0x10+unit_index] = button;
controls.push_back (button);
strip->add (*button);
button = new Button (unit_ordinal, "select", *strip);
buttons[0x18+unit_index] = button;
controls.push_back (button);
strip->add (*button);
button = new Button (unit_ordinal, "vselect", *strip);
buttons[0x20+unit_index] = button;
controls.push_back (button);
strip->add (*button);
button = new Button (unit_ordinal, "fader_touch", *strip);
buttons[0x68+unit_index] = button;
controls.push_back (button);
strip->add (*button);
}
}

View File

@@ -12,19 +12,18 @@ namespace Mackie
class MackieButtonHandler;
class MackieSurface : public Surface
{
public:
MackieSurface( uint32_t max_strips ) : Surface( max_strips )
{
}
public:
MackieSurface (uint32_t max_strips) : Surface (max_strips, 8) {}
virtual void handle_button( MackieButtonHandler & mbh, ButtonState bs, Button & button );
virtual void handle_button (MackieButtonHandler & mbh, ButtonState bs, Button & button);
virtual void init_controls();
virtual void init_strips();
virtual bool has_timecode_display() const { return true; }
virtual void display_timecode( SurfacePort &, MackieMidiBuilder &, const std::string & timecode, const std::string & timecode_last );
virtual void display_timecode (SurfacePort &, MackieMidiBuilder &, const std::string & timecode, const std::string & timecode_last);
virtual float scrub_scaling_factor() { return 100.0; }
virtual float scaled_delta( const ControlState & state, float current_speed );
virtual float scaled_delta (const ControlState & state, float current_speed);
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,15 +10,16 @@ using namespace PBD;
using namespace Mackie;
Surface::Surface( uint32_t max_strips, uint32_t unit_strips )
: _max_strips( max_strips ), _unit_strips( unit_strips )
: _max_strips (max_strips)
, _unit_strips( unit_strips )
{
}
void Surface::init()
{
DEBUG_TRACE (DEBUG::MackieControl, "Surface::init\n");
init_controls();
init_strips( _max_strips, _unit_strips );
init_controls ();
init_strips ();
DEBUG_TRACE (DEBUG::MackieControl, "Surface::init finish\n");
}
@@ -37,36 +38,3 @@ Surface::~Surface()
}
}
// Mackie-specific, because of multiple devices on separate ports
// add the strips from 9..max_strips
// unit_strips is the number of strips for additional units.
void Surface::init_strips (uint32_t max_strips, uint32_t unit_strips)
{
if ( strips.size() < max_strips ) {
uint32_t const old_size = strips.size();
strips.resize (max_strips);
for (uint32_t i = old_size; i < max_strips; ++i) {
// because I can't find itoa
ostringstream os;
os << "strip_" << i + 1;
string name = os.str();
// shallow copy existing strip
// which works because the controls
// have the same ids across units
// TODO this needs to be a deep copy because
// controls hold state now - in_use
Strip * strip = new Strip( *strips[i % unit_strips] );
// update the relevant values
strip->index (i);
strip->name (name);
// add to data structures
groups[name] = strip;
strips[i] = strip;
}
}
}

View File

@@ -38,7 +38,8 @@ public:
\param max_strips is the number of strips for the entire surface.
\param unit_strips is the number of strips per unit.
*/
Surface( uint32_t max_strips, uint32_t unit_strips = 8 );
Surface (uint32_t max_strips, uint32_t unit_strips);
virtual ~Surface();
/// Calls the virtual initialisation methods. This *must* be called after
@@ -76,10 +77,7 @@ public:
typedef std::map<std::string,Group*> Groups;
Groups groups;
uint32_t max_strips() const
{
return _max_strips;
}
uint32_t max_strips() const { return _max_strips; }
/// map button ids to calls to press_ and release_ in mbh
virtual void handle_button( MackieButtonHandler & mbh, ButtonState bs, Button & button ) = 0;
@@ -117,11 +115,10 @@ public:
protected:
virtual void init_controls() = 0;
virtual void init_strips( uint32_t max_strips, uint32_t unit_strips );
virtual void init_strips () {}
private:
uint32_t _max_strips;
uint32_t _unit_strips;
const uint32_t _max_strips;
const uint32_t _unit_strips;
};
}