13
0

MCP: major redesign of control instantiation; continuing code reformatting

git-svn-id: svn://localhost/ardour2/branches/3.0@11824 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-04-08 14:11:00 +00:00
parent 05b36d0092
commit c72287e67d
9 changed files with 545 additions and 1048 deletions

View File

@ -87,502 +87,502 @@ void Mackie::BcfSurface::init_controls()
Led * led = 0;
group = groups["master"];
fader = new Fader (1, "gain", *group);
fader = new Fader (0x07, 1, "gain", *group);
faders[0x07] = fader;
controls.push_back (fader);
group->add (*fader);
group = groups["none"];
pot = new Jog (1, "jog", *group);
pot = new Jog (0x17, 1, "jog", *group);
pots[0x17] = pot;
controls.push_back (pot);
controls_by_name["jog"] = pot;
group->add (*pot);
group = groups["none"];
pot = new Pot (1, "external", *group);
pot = new Pot (0x2e, 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);
button = new Button (0x28, 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);
button = new Button (0x5a, 1, "sends", *group);
buttons[0x5a] = button;
controls.push_back (button);
controls_by_name["sends"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "pan", *group);
button = new Button (0x59, 1, "pan", *group);
buttons[0x59] = button;
controls.push_back (button);
controls_by_name["pan"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "plugin", *group);
button = new Button (0x57, 1, "plugin", *group);
buttons[0x57] = button;
controls.push_back (button);
controls_by_name["plugin"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "drop", *group);
button = new Button (0x58, 1, "drop", *group);
buttons[0x58] = button;
controls.push_back (button);
controls_by_name["drop"] = button;
group->add (*button);
group = groups["assignment"];
button = new Button (1, "zoom", *group);
button = new Button (0x2d, 1, "zoom", *group);
buttons[0x2d] = button;
controls.push_back (button);
controls_by_name["zoom"] = button;
group->add (*button);
group = groups["bank"];
button = new Button (1, "left", *group);
button = new Button (0x2e, 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);
button = new Button (0x2f, 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);
button = new Button (0x30, 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);
button = new Button (0x31, 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, "scrub", *group);
button = new Button (0x32, 1, "scrub", *group);
buttons[0x32] = button;
controls.push_back (button);
controls_by_name["scrub"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "edit", *group);
button = new Button (0x56, 1, "edit", *group);
buttons[0x56] = button;
controls.push_back (button);
controls_by_name["edit"] = button;
group->add (*button);
group = groups["display"];
button = new Button (1, "name_value", *group);
button = new Button (0x34, 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);
button = new Button (0x35, 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);
button = new Button (0x36, 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);
button = new Button (0x37, 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);
button = new Button (0x38, 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);
button = new Button (0x39, 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);
button = new Button (0x3a, 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);
button = new Button (0x3b, 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);
button = new Button (0x3c, 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);
button = new Button (0x3d, 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);
button = new Button (0x3e, 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);
button = new Button (0x3f, 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);
button = new Button (0x40, 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);
button = new Button (0x41, 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);
button = new Button (0x42, 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);
button = new Button (0x43, 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);
button = new Button (0x44, 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);
button = new Button (0x45, 1, "F16", *group);
buttons[0x45] = button;
controls.push_back (button);
controls_by_name["F16"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "global_solo", *group);
button = new Button (0x27, 1, "global_solo", *group);
buttons[0x27] = button;
controls.push_back (button);
controls_by_name["global_solo"] = button;
group->add (*button);
group = groups["modifiers"];
button = new Button (1, "option", *group);
button = new Button (0x50, 1, "option", *group);
buttons[0x50] = button;
controls.push_back (button);
controls_by_name["option"] = button;
group->add (*button);
group = groups["modifiers"];
button = new Button (1, "cmd_alt", *group);
button = new Button (0x49, 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);
button = new Button (0x4a, 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);
button = new Button (0x4b, 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);
button = new Button (0x4c, 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);
button = new Button (0x5f, 1, "snapshot", *group);
buttons[0x5f] = button;
controls.push_back (button);
controls_by_name["snapshot"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "redo", *group);
button = new Button (0x4f, 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);
button = new Button (0x47, 1, "marker", *group);
buttons[0x47] = button;
controls.push_back (button);
controls_by_name["marker"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "enter", *group);
button = new Button (0x51, 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);
button = new Button (0x52, 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);
button = new Button (0x53, 1, "mixer", *group);
buttons[0x53] = button;
controls.push_back (button);
controls_by_name["mixer"] = button;
group->add (*button);
group = groups["functions"];
button = new Button (1, "save", *group);
button = new Button (0x4d, 1, "save", *group);
buttons[0x4d] = button;
controls.push_back (button);
controls_by_name["save"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "frm_left", *group);
button = new Button (0x5b, 1, "frm_left", *group);
buttons[0x5b] = button;
controls.push_back (button);
controls_by_name["frm_left"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "frm_right", *group);
button = new Button (0x5c, 1, "frm_right", *group);
buttons[0x5c] = button;
controls.push_back (button);
controls_by_name["frm_right"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "loop", *group);
button = new Button (0x46, 1, "loop", *group);
buttons[0x46] = button;
controls.push_back (button);
controls_by_name["loop"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "punch_in", *group);
button = new Button (0x48, 1, "punch_in", *group);
buttons[0x48] = button;
controls.push_back (button);
controls_by_name["punch_in"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "punch_out", *group);
button = new Button (0x4e, 1, "punch_out", *group);
buttons[0x4e] = button;
controls.push_back (button);
controls_by_name["punch_out"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "home", *group);
button = new Button (0x2a, 1, "home", *group);
buttons[0x2a] = button;
controls.push_back (button);
controls_by_name["home"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "end", *group);
button = new Button (0x29, 1, "end", *group);
buttons[0x29] = button;
controls.push_back (button);
controls_by_name["end"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "rewind", *group);
button = new Button (0x2c, 1, "rewind", *group);
buttons[0x2c] = button;
controls.push_back (button);
controls_by_name["rewind"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "ffwd", *group);
button = new Button (0x2b, 1, "ffwd", *group);
buttons[0x2b] = button;
controls.push_back (button);
controls_by_name["ffwd"] = button;
group->add (*button);
group = groups["transport"];
button = new Button (1, "stop", *group);
button = new Button (0x5d, 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);
button = new Button (0x5e, 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);
button = new Button (0x1f, 1, "record", *group);
buttons[0x1f] = button;
controls.push_back (button);
controls_by_name["record"] = button;
group->add (*button);
group = groups["cursor"];
button = new Button (1, "cursor_up", *group);
button = new Button (0x60, 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);
button = new Button (0x61, 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);
button = new Button (0x62, 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);
button = new Button (0x63, 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, "dyn", *group);
button = new Button (0x64, 1, "dyn", *group);
buttons[0x64] = button;
controls.push_back (button);
controls_by_name["dyn"] = button;
group->add (*button);
group = groups["none"];
button = new Button (1, "flip", *group);
button = new Button (0x65, 1, "flip", *group);
buttons[0x65] = button;
controls.push_back (button);
controls_by_name["flip"] = button;
group->add (*button);
group = groups["user"];
button = new Button (1, "user_a", *group);
button = new Button (0x66, 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);
button = new Button (0x67, 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, "mute", *group);
button = new Button (0x17, 1, "mute", *group);
buttons[0x17] = button;
controls.push_back (button);
group->add (*button);
group = groups["none"];
button = new Button (1, "clicking", *group);
button = new Button (0x33, 1, "clicking", *group);
buttons[0x33] = button;
controls.push_back (button);
controls_by_name["clicking"] = button;
group->add (*button);
group = groups["none"];
led = new Led (1, "timecode", *group);
led = new Led (0x71, 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);
led = new Led (0x72, 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);
led = new Led (0x73, 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);
led = new Led (0x76, 1, "relay_click", *group);
leds[0x76] = led;
controls.push_back (led);
controls_by_name["relay_click"] = led;

View File

@ -1,4 +1,4 @@
/*
/*
Copyright (C) 2006,2007 John Anderson
This program is free software; you can redistribute it and/or modify
@ -15,171 +15,170 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "controls.h"
#include "types.h"
#include "mackie_midi_builder.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include "controls.h"
#include "types.h"
#include "mackie_midi_builder.h"
#include "surface.h"
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 )
void Group::add (Control& control)
{
_controls.push_back( &control );
_controls.push_back (&control);
}
Strip::Strip( const std::string & name, int index )
: Group( name )
, _solo( 0 )
, _recenable( 0 )
, _mute( 0 )
, _select( 0 )
, _vselect( 0 )
, _fader_touch( 0 )
, _vpot( 0 )
, _gain( 0 )
, _index( index )
Strip::Strip (const std::string& name, int index)
: Group (name)
, _solo (0)
, _recenable (0)
, _mute (0)
, _select (0)
, _vselect (0)
, _fader_touch (0)
, _vpot (0)
, _gain (0)
, _index (index)
{
/* master strip only */
}
Strip::Strip (Surface& surface, const std::string& name, int index, int unit_index, StripControlDefinition* ctls)
: Group (name)
, _solo (0)
, _recenable (0)
, _mute (0)
, _select (0)
, _vselect (0)
, _fader_touch (0)
, _vpot (0)
, _gain (0)
, _index (index)
{
/* build the controls for this track, which will automatically add them
to the Group
*/
for (uint32_t i = 0; ctls[i].name[0]; ++i) {
ctls[i].factory (surface, ctls[i].base_id + unit_index, unit_index+1, ctls[i].name, *this);
}
}
/**
TODO could optimise this to use enum, but it's only
called during the protocol class instantiation.
generated using
irb -r controls.rb
sf=Surface.new
sf.parse
controls = sf.groups.find{|x| x[0] =~ /strip/}.each{|x| puts x[1]}
controls[1].each {|x| puts "\telse if ( control.name() == \"#{x.name}\" )\n\t{\n\t\t_#{x.name} = reinterpret_cast<#{x.class.name}*>(&control);\n\t}\n"}
*/
void Strip::add( Control & control )
void Strip::add (Control & control)
{
Group::add( control );
if ( control.name() == "gain" )
{
Group::add (control);
if (control.name() == "gain") {
_gain = reinterpret_cast<Fader*>(&control);
}
else if ( control.name() == "vpot" )
{
} else if (control.name() == "vpot") {
_vpot = reinterpret_cast<Pot*>(&control);
}
else if ( control.name() == "recenable" )
{
} else if (control.name() == "recenable") {
_recenable = reinterpret_cast<Button*>(&control);
}
else if ( control.name() == "solo" )
{
} else if (control.name() == "solo") {
_solo = reinterpret_cast<Button*>(&control);
}
else if ( control.name() == "mute" )
{
} else if (control.name() == "mute") {
_mute = reinterpret_cast<Button*>(&control);
}
else if ( control.name() == "select" )
{
} else if (control.name() == "select") {
_select = reinterpret_cast<Button*>(&control);
}
else if ( control.name() == "vselect" )
{
} else if (control.name() == "vselect") {
_vselect = reinterpret_cast<Button*>(&control);
}
else if ( control.name() == "fader_touch" )
{
} else if (control.name() == "fader_touch") {
_fader_touch = reinterpret_cast<Button*>(&control);
}
else if ( control.type() == Control::type_led || control.type() == Control::type_led_ring )
{
// do nothing
cout << "Strip::add not adding " << control << endl;
}
else
{
} else if (control.type() == Control::type_led || control.type() == Control::type_led_ring) {
// relax
} else {
ostringstream os;
os << "Strip::add: unknown control type " << control;
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
}
Control::Control( int id, int ordinal, std::string name, Group & group )
: _id( id )
, _ordinal( ordinal )
, _name( name )
, _group( group )
, _in_use( false )
Control::Control (int id, int ordinal, std::string name, Group & group)
: _id (id)
, _ordinal (ordinal)
, _name (name)
, _group (group)
, _in_use (false)
{
}
/**
generated with
controls[1].each do |x|
puts <<EOF
#{x.class.name} & Strip::#{x.name}()
Fader&
Strip::gain()
{
if ( _#{x.name} == 0 )
throw MackieControlException( "#{x.name} is null" );
return *_#{x.name};
}
EOF
end
*/
Fader & Strip::gain()
{
if ( _gain == 0 )
throw MackieControlException( "gain is null" );
if (_gain == 0) {
throw MackieControlException ("gain is null");
}
return *_gain;
}
Pot & Strip::vpot()
Pot&
Strip::vpot()
{
if ( _vpot == 0 )
throw MackieControlException( "vpot is null" );
if (_vpot == 0) {
throw MackieControlException ("vpot is null");
}
return *_vpot;
}
Button & Strip::recenable()
Button&
Strip::recenable()
{
if ( _recenable == 0 )
throw MackieControlException( "recenable is null" );
if (_recenable == 0) {
throw MackieControlException ("recenable is null");
}
return *_recenable;
}
Button & Strip::solo()
Button&
Strip::solo()
{
if ( _solo == 0 )
throw MackieControlException( "solo is null" );
if (_solo == 0) {
throw MackieControlException ("solo is null");
}
return *_solo;
}
Button & Strip::mute()
Button&
Strip::mute()
{
if ( _mute == 0 )
throw MackieControlException( "mute is null" );
if (_mute == 0) {
throw MackieControlException ("mute is null");
}
return *_mute;
}
Button & Strip::select()
Button&
Strip::select()
{
if ( _select == 0 )
throw MackieControlException( "select is null" );
if (_select == 0) {
throw MackieControlException ("select is null");
}
return *_select;
}
Button & Strip::vselect()
Button&
Strip::vselect()
{
if ( _vselect == 0 )
throw MackieControlException( "vselect is null" );
if (_vselect == 0) {
throw MackieControlException ("vselect is null");
}
return *_vselect;
}
Button & Strip::fader_touch()
Button&
Strip::fader_touch()
{
if ( _fader_touch == 0 )
throw MackieControlException( "fader_touch is null" );
if (_fader_touch == 0) {
throw MackieControlException ("fader_touch is null");
}
return *_fader_touch;
}
@ -201,9 +200,9 @@ Control::set_in_use (bool in_use)
_in_use = in_use;
}
ostream & Mackie::operator << ( ostream & os, const Mackie::Control & control )
ostream & Mackie::operator << (ostream & os, const Mackie::Control & control)
{
os << typeid( control ).name();
os << typeid (control).name();
os << " { ";
os << "name: " << control.name();
os << ", ";
@ -221,9 +220,9 @@ ostream & Mackie::operator << ( ostream & os, const Mackie::Control & control )
return os;
}
std::ostream & Mackie::operator << ( std::ostream & os, const Strip & strip )
std::ostream & Mackie::operator << (std::ostream & os, const Strip & strip)
{
os << typeid( strip ).name();
os << typeid (strip).name();
os << " { ";
os << "has_solo: " << boolalpha << strip.has_solo();
os << ", ";
@ -244,3 +243,52 @@ std::ostream & Mackie::operator << ( std::ostream & os, const Strip & strip )
return os;
}
Control*
Button::factory (Surface& surface, int id, int ordinal, const char* name, Group& group)
{
Button* b = new Button (id, ordinal, name, group);
surface.buttons[id] = b;
surface.controls.push_back (b);
group.add (*b);
return b;
}
Control*
Fader::factory (Surface& surface, int id, int ordinal, const char* name, Group& group)
{
Fader* f = new Fader (id, ordinal, name, group);
surface.faders[id] = f;
surface.controls.push_back (f);
group.add (*f);
return f;
}
Control*
Pot::factory (Surface& surface, int id, int ordinal, const char* name, Group& group)
{
Pot* p = new Pot (id, ordinal, name, group);
surface.pots[id] = p;
surface.controls.push_back (p);
group.add (*p);
return p;
}
Control*
Led::factory (Surface& surface, int id, int ordinal, const char* name, Group& group)
{
Led* l = new Led (id, ordinal, name, group);
surface.leds[id] = l;
surface.controls.push_back (l);
group.add (*l);
return l;
}
Control*
Jog::factory (Surface& surface, int id, int ordinal, const char* name, Group& group)
{
Jog* j = new Jog (id, ordinal, name, group);
surface.controls.push_back (j);
group.add (*j);
return j;
}

View File

@ -21,6 +21,7 @@
#include <map>
#include <vector>
#include <string>
#include <stdint.h>
#include "pbd/signals.h"
@ -30,6 +31,7 @@ namespace Mackie
{
class Control;
class Surface;
/**
This is a loose group of controls, eg cursor buttons,
@ -39,31 +41,17 @@ class Group
{
public:
Group (const std::string & name)
: _name (name)
{
}
: _name (name) {}
virtual ~Group() {}
virtual bool is_strip() const
{
return false;
}
virtual bool is_master() const
{
return false;
}
virtual bool is_strip() const { return false; }
virtual bool is_master() const { return false; }
virtual void add (Control & control);
const std::string & name() const
{
return _name;
}
// This is for Surface only
void name (const std::string & rhs) { _name = rhs; }
const std::string & name() const { return _name; }
void set_name (const std::string & rhs) { _name = rhs; }
typedef std::vector<Control*> Controls;
const Controls & controls() const { return _controls; }
@ -79,31 +67,31 @@ class Button;
class Pot;
class Fader;
struct StripControlDefinition {
const char* name;
uint32_t base_id;
Control* (*factory)(Surface&, int index, int ordinal, const char* name, Group&);
};
struct GlobalControlDefinition {
const char* name;
uint32_t id;
Control* (*factory)(Surface&, int index, int ordinal, const char* name, Group&);
const char* group_name;
};
/**
This is the set of controls that make up a strip.
*/
class Strip : public Group
{
public:
/**
\param is the index of the strip. 0-based.
*/
Strip (const std::string & name, int index);
Strip (const Strip& other);
Strip (const std::string& name, int index); /* master strip only */
Strip (Surface&, const std::string & name, int index, int unit_index, StripControlDefinition* ctls);
virtual bool is_strip() const
{
return true;
}
virtual bool is_strip() const { return true; }
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; }
int index() const { return _index; } // zero based
Button & solo();
Button & recenable();
@ -124,15 +112,15 @@ public:
bool has_gain() const { return _gain != 0; }
private:
Button * _solo;
Button * _recenable;
Button * _mute;
Button * _select;
Button * _vselect;
Button * _fader_touch;
Pot * _vpot;
Fader * _gain;
int _index;
Button* _solo;
Button* _recenable;
Button* _mute;
Button* _select;
Button* _vselect;
Button* _fader_touch;
Pot* _vpot;
Fader* _gain;
int _index;
};
std::ostream & operator << (std::ostream &, const Strip &);
@ -162,6 +150,17 @@ public:
type_button = 0x90,
type_pot = 0xb0
};
enum base_id_t {
fader_base_id = 0x0,
pot_base_id = 0x10,
fader_touch_button_base_id = 0x68,
vselect_button_base_id = 0x20,
select_button_base_id = 0x18,
mute_button_base_id = 0x10,
solo_button_base_id = 0x08,
recenable_button_base_id = 0x0,
};
Control (int id, int ordinal, std::string name, Group& group);
virtual ~Control() {}
@ -202,12 +201,6 @@ public:
*/
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;
@ -221,37 +214,43 @@ std::ostream & operator << (std::ostream & os, const Control & control);
class Fader : public Control
{
public:
Fader (int ordinal, std::string name, Group & group)
: Control (Control::fader_cnt++, ordinal, name, group)
Fader (int id, int ordinal, std::string name, Group & group)
: Control (id, ordinal, name, group)
{
}
virtual type_t type() const { return type_fader; }
static Control* factory (Surface&, int id, int ordinal, const char*, Group&);
};
class Led : public Control
{
public:
Led (int ordinal, std::string name, Group & group)
: Control (Control::led_cnt++, ordinal, name, group)
Led (int id, int ordinal, std::string name, Group & group)
: Control (id, ordinal, name, group)
{
}
virtual const Led & led() const { return *this; }
virtual type_t type() const { return type_led; }
static Control* factory (Surface&, int id, int ordinal, const char*, Group&);
};
class Button : public Control
{
public:
Button (int ordinal, std::string name, Group & group)
: Control (Control::button_cnt++, ordinal, name, group)
, _led (ordinal, name + "_led", group) {}
Button (int id, int ordinal, std::string name, Group & group)
: Control (id, ordinal, name, group)
, _led (id, ordinal, name + "_led", group) {}
virtual const Led & led() const { return _led; }
virtual type_t type() const { return type_button; };
static Control* factory (Surface&, int id, int ordinal, const char*, Group&);
private:
Led _led;
@ -260,8 +259,8 @@ private:
class LedRing : public Led
{
public:
LedRing (int ordinal, std::string name, Group & group)
: Led (ordinal, name, group)
LedRing (int id, int ordinal, std::string name, Group & group)
: Led (id, ordinal, name, group)
{
}
@ -271,18 +270,16 @@ public:
class Pot : public Control
{
public:
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) {}
, _led_ring (id, ordinal, name + "_ring", group) {}
virtual type_t type() const { return type_pot; }
virtual const LedRing & led_ring() const {return _led_ring; }
static Control* factory (Surface&, int id, int ordinal, const char*, Group&);
private:
LedRing _led_ring;
};
@ -290,12 +287,14 @@ private:
class Jog : public Pot
{
public:
Jog (int ordinal, std::string name, Group & group)
: Pot (Control::jog_cnt++, ordinal, name, group)
Jog (int id, int ordinal, std::string name, Group & group)
: Pot (id, ordinal, name, group)
{
}
virtual bool is_jog() const { return true; }
static Control* factory (Surface&, int id, int ordinal, const char*, Group&);
};
}

View File

@ -102,7 +102,7 @@ void MackiePort::close()
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::close\n");
// disconnect signals
any_connection.disconnect();
sysex_connection.disconnect();
// TODO emit a "closing" signal?
@ -230,21 +230,16 @@ 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;
}
else
{
} else {
cout << "unknown mackie emulation: " << ARDOUR::Config->get_mackie_emulation() << endl;
emulation_ok = false;
}
@ -258,7 +253,7 @@ void MackiePort::finalise_init (bool yn)
active_event();
// start handling messages from controls
connect_any();
connect_to_signals ();
}
_initialising = false;
@ -268,11 +263,24 @@ void MackiePort::finalise_init (bool yn)
DEBUG_TRACE (DEBUG::MackieControl, "MackiePort::finalise_init lock released\n");
}
void MackiePort::connect_any()
void MackiePort::connect_to_signals ()
{
if (!any_connection.connected()) {
input_port().parser()->any.connect_same_thread (any_connection, boost::bind (&MackiePort::handle_midi_any, this, _1, _2, _3));
if (ScopedConnectionList::empty()) {
MIDI::Parser* p = input_port().parser();
p->controller.connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_controller_message, this, _1, _2));
p->channel_pitchbend[0].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 0U));
p->channel_pitchbend[1].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 1U));
p->channel_pitchbend[2].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 2U));
p->channel_pitchbend[3].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 3U));
p->channel_pitchbend[4].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 4U));
p->channel_pitchbend[5].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 5U));
p->channel_pitchbend[6].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 6U));
p->channel_pitchbend[7].connect_same_thread (*this, boost::bind (&MackiePort::handle_midi_pitchbend_message, this, _1, _2, 7U));
}
}
bool MackiePort::wait_for_init()
@ -314,156 +322,72 @@ void MackiePort::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size
}
}
Control&
MackiePort::lookup_control (MIDI::byte * bytes, size_t count)
void
MackiePort::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uint32_t fader_id)
{
// Don't instantiate a MidiByteArray here unless it's needed for exceptions.
// Reason being that this method is called for every single incoming
// midi event, and it needs to be as efficient as possible.
Control* control = _mcp.surface().faders[fader_id];
Control * control = 0;
MIDI::byte midi_type = bytes[0] & 0xf0; //0b11110000
switch (midi_type) {
// fader
case MackieMidiBuilder::midi_fader_id:
{
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" << bytes << " id " << midi_id << " is null";
throw MackieControlException (os.str());
}
break;
}
// button
case MackieMidiBuilder::midi_button_id:
control = _mcp.surface().buttons[bytes[1]];
if (control == 0)
{
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Control for button " << mba << " is null";
throw MackieControlException (os.str());
}
break;
// pot (jog wheel, external control)
case MackieMidiBuilder::midi_pot_id:
control = _mcp.surface().pots[bytes[1]];
if (control == 0)
{
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Control for rotary " << mba << " is null";
throw MackieControlException (os.str());
}
break;
if (control) {
// only the top-order 10 bits out of 14 are used
int midi_pos = pb & 0x3ff;
// in_use is set by the MackieControlProtocol::handle_strip_button
default:
MidiByteArray mba (count, bytes);
ostringstream os;
os << "Cannot find control for " << mba;
throw MackieControlException (os.str());
// relies on implicit ControlState constructor
control_event (*this, *control, float (midi_pos) / float(0x3ff));
}
return *control;
}
// 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)
MackiePort::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
{
MidiByteArray bytes (count, raw_bytes);
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::handle_midi_any %1\n", bytes));
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::handle_midi_controller %1 = %2\n", ev->controller_number, ev->value));
try
{
// ignore sysex messages
if (raw_bytes[0] == MIDI::sysex) {
return;
}
Control* control;
// 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());
switch (ev->controller_number & 0xf0) {
case Control::type_button:
control = _mcp.surface().buttons[ev->controller_number];
if (control) {
control->set_in_use (true);
ControlState control_state (ev->value == 0x7f ? press : release);
control->set_in_use (control_state.button_state == press);
control_event (*this, *control, control_state);
}
Control & control = lookup_control (raw_bytes, count);
control.set_in_use (true);
// This handles incoming bytes. Outgoing bytes
// are sent by the signal handlers.
switch (control.type()) {
// fader
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;
// in_use is set by the MackieControlProtocol::handle_strip_button
// relies on implicit ControlState constructor
control_event (*this, control, float(midi_pos) / float(0x3ff));
}
break;
// button
case Control::type_button:
{
ControlState control_state (raw_bytes[2] == 0x7f ? press : release);
control.set_in_use (control_state.button_state == press);
control_event (*this, control, control_state);
break;
}
// pot (jog wheel, external control)
case Control::type_pot:
{
ControlState state;
// bytes[2] & 0b01000000 (0x40) give sign
state.sign = (raw_bytes[2] & 0x40) == 0 ? 1 : -1;
// bytes[2] & 0b00111111 (0x3f) gives delta
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);
/* Pots only emit events when they move, not when they
stop moving. So to get a stop event, we need to use a timeout.
break;
case Control::type_pot:
control = _mcp.surface().pots[ev->controller_number];
if (control) {
ControlState state;
// bytes[2] & 0b01000000 (0x40) give sign
state.sign = (ev->value & 0x40) == 0 ? 1 : -1;
// bytes[2] & 0b00111111 (0x3f) gives delta
state.ticks = (ev->value & 0x3f);
if (state.ticks == 0) {
/* euphonix and perhaps other devices send zero
when they mean 1, we think.
*/
control.set_in_use (true);
add_in_use_timeout (control, &control);
// emit the control event
control_event (*this, control, state);
break;
state.ticks = 1;
}
default:
cerr << "Do not understand control type " << control;
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.
*/
control->set_in_use (true);
add_in_use_timeout (*control, control);
// emit the control event
control_event (*this, *control, state);
}
break;
default:
break;
}
catch (MackieControlException & e) {
MidiByteArray bytes (count, raw_bytes);
cout << bytes << ' ' << e.what() << endl;
}
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("finished MackiePort::handle_midi_any %1\n", bytes));
}

View File

@ -54,11 +54,8 @@ public:
/// Handle device initialisation
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 count );
Control & lookup_control( MIDI::byte *, size_t count );
void handle_midi_pitchbend_message (MIDI::Parser &, MIDI::pitchbend_t, uint32_t channel_id);
void handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes*);
/// return the number of strips associated with this port
virtual int strips() const;
@ -71,7 +68,7 @@ public:
/// Connect the any signal from the parser to handle_midi_any
/// unless it's already connected
void connect_any();
void connect_to_signals ();
protected:
/**

View File

@ -1,6 +1,7 @@
#include <cmath>
#include <sstream>
#include <string>
#include <cstdio>
#include "mackie_surface.h"
#include "surface_port.h"
@ -9,618 +10,147 @@
using namespace Mackie;
void
MackieSurface::display_timecode( SurfacePort & port, MackieMidiBuilder & builder, const std::string & timecode, const std::string & timecode_last )
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 ) );
port.write (builder.timecode_display (port, timecode, timecode_last));
}
float
MackieSurface::scaled_delta( const ControlState & state, float current_speed )
MackieSurface::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;
}
static GlobalControlDefinition mackie_global_controls[] = {
{ "jog", 0x3c, Jog::factory, "none" },
{ "external", 0x2e, Pot::factory, "none" },
{ "io", 0x28, Button::factory, "assignment" },
{ "sends", 0x29, Button::factory, "assignment" },
{ "pan", 0x2a, Button::factory, "assignment" },
{ "plugin", 0x2b, Button::factory, "assignment" },
{ "eq", 0x2c, Button::factory, "assignment" },
{ "dyn", 0x2d, Button::factory, "assignment" },
{ "left", 0x2e, Button::factory, "bank" },
{ "right", 0x2f, Button::factory, "bank" },
{ "channel_left", 0x30, Button::factory, "bank" },
{ "channel_right", 0x31, Button::factory, "bank" },
{ "flip", 0x32, Button::factory, "none" },
{ "edit", 0x33, Button::factory, "none" },
{ "name_value", 0x34, Button::factory, "display" },
{ "timecode_beats", 0x35, Button::factory, "display" },
{ "F1", 0x36, Button::factory, "none" },
{ "F2", 0x37, Button::factory, "none" },
{ "F3", 0x38, Button::factory, "none" },
{ "F4", 0x39, Button::factory, "none" },
{ "F5", 0x3a, Button::factory, "none" },
{ "F6", 0x3b, Button::factory, "none" },
{ "F7", 0x3c, Button::factory, "none" },
{ "F8", 0x3d, Button::factory, "none" },
{ "F9", 0x3e, Button::factory, "none" },
{ "F10", 0x3f, Button::factory, "none" },
{ "F11", 0x40, Button::factory, "none" },
{ "F12", 0x41, Button::factory, "none" },
{ "F13", 0x42, Button::factory, "none" },
{ "F14", 0x43, Button::factory, "none" },
{ "F15", 0x44, Button::factory, "none" },
{ "F16", 0x45, Button::factory, "none" },
{ "shift", 0x46, Button::factory, "modifiers" },
{ "option", 0x47, Button::factory, "modifiers" },
{ "control", 0x48, Button::factory, "modifiers" },
{ "cmd_alt", 0x49, Button::factory, "modifiers" },
{ "on", 0x4a, Button::factory, "automation" },
{ "rec_ready", 0x4b, Button::factory, "automation" },
{ "undo", 0x4c, Button::factory, "functions" },
{ "snapshot", 0x4d, Button::factory, "automation" },
{ "touch", 0x4e, Button::factory, "automation" },
{ "redo", 0x4f, Button::factory, "functions" },
{ "marker", 0x50, Button::factory, "functions" },
{ "enter", 0x51, Button::factory, "functions" },
{ "cancel", 0x52, Button::factory, "functions" },
{ "mixer", 0x53, Button::factory, "functions" },
{ "frm_left", 0x54, Button::factory, "transport" },
{ "frm_right", 0x55, Button::factory, "transport" },
{ "loop", 0x56, Button::factory, "transport" },
{ "punch_in", 0x57, Button::factory, "transport" },
{ "punch_out", 0x58, Button::factory, "transport" },
{ "home", 0x59, Button::factory, "transport" },
{ "end", 0x5a, Button::factory, "transport" },
{ "rewind", 0x5b, Button::factory, "transport" },
{ "ffwd", 0x5c, Button::factory, "transport" },
{ "stop", 0x5d, Button::factory, "transport" },
{ "play", 0x5e, Button::factory, "transport" },
{ "record", 0x5f, Button::factory, "transport" },
{ "cursor_up", 0x60, Button::factory, "cursor" },
{ "cursor_down", 0x61, Button::factory, "cursor" },
{ "cursor_left", 0x62, Button::factory, "cursor" },
{ "cursor_right", 0x63, Button::factory, "cursor" },
{ "zoom", 0x64, Button::factory, "none" },
{ "scrub", 0x65, Button::factory, "none" },
{ "user_a", 0x66, Button::factory, "user" },
{ "user_b", 0x67, Button::factory, "user" },
{ "fader_touch", 0x70, Led::factory, "master" },
{ "timecode", 0x71, Led::factory, "none" },
{ "beats", 0x72, Led::factory, "none" },
{ "solo", 0x73, Led::factory, "none" },
{ "relay_click", 0x73, Led::factory, "none" },
{ "", 0, Button::factory, "" }
};
void
Mackie::MackieSurface::init_controls()
{
Pot* pot = 0;
Button* button = 0;
Led* led = 0;
Group* group;
groups["assignment"] = new Group ("assignment");
groups["automation"] = new Group ("automation");
groups["bank"] = new Group ("bank");
groups["cursor"] = new Group ("cursor");
groups["display"] = new Group ("display");
groups["functions"] = new Group ("functions");
groups["modifiers"] = new Group ("modifiers");
groups["none"] = new Group ("none");
groups["transport"] = new Group ("transport");
groups["user"] = new Group ("user");
// intialise groups and strips
Group * group = 0;
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);
for (uint32_t n = 0; mackie_global_controls[n].name[0]; ++n) {
group = groups[mackie_global_controls[n].group_name];
Control* control = mackie_global_controls[n].factory (*this, mackie_global_controls[n].id, 1, mackie_global_controls[n].name, *group);
controls_by_name[mackie_global_controls[n].name] = control;
group->add (*control);
}
}
static StripControlDefinition mackie_strip_controls[] = {
{ "gain", Control::fader_base_id, Fader::factory, },
{ "vpot", Control::pot_base_id, Pot::factory, },
{ "recenable", Control::recenable_button_base_id, Button::factory, },
{ "solo", Control::solo_button_base_id, Button::factory, },
{ "mute", Control::mute_button_base_id, Button::factory, },
{ "select", Control::select_button_base_id, Button::factory, },
{ "vselect", Control::vselect_button_base_id, Button::factory, },
{ "fader_touch", Control::fader_touch_button_base_id, Button::factory, },
{ "", 0, Button::factory, }
};
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();
char name[32];
Strip* strip = new Strip (name, i);
uint32_t unit_index = i % _unit_strips;
snprintf (name, sizeof (name), "strip_%d", unit_index+1);
Strip* strip = new Strip (*this, name, i, unit_index, mackie_strip_controls);
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

@ -9,13 +9,13 @@ using namespace std;
using namespace PBD;
using namespace Mackie;
Surface::Surface( uint32_t max_strips, uint32_t unit_strips )
Surface::Surface (uint32_t max_strips, uint32_t unit_strips)
: _max_strips (max_strips)
, _unit_strips( unit_strips )
{
}
void Surface::init()
void Surface::init ()
{
DEBUG_TRACE (DEBUG::MackieControl, "Surface::init\n");
@ -26,17 +26,15 @@ void Surface::init()
DEBUG_TRACE (DEBUG::MackieControl, "Surface::init finish\n");
}
Surface::~Surface()
Surface::~Surface ()
{
// delete groups
for( Groups::iterator it = groups.begin(); it != groups.end(); ++it )
{
for (Groups::iterator it = groups.begin(); it != groups.end(); ++it) {
delete it->second;
}
// delete controls
for( Controls::iterator it = controls.begin(); it != controls.end(); ++it )
{
for (Controls::iterator it = controls.begin(); it != controls.end(); ++it) {
delete *it;
}
}

View File

@ -56,7 +56,7 @@ SurfacePort::~SurfacePort()
cout << "~SurfacePort::SurfacePort()" << endl;
#endif
// make sure another thread isn't reading or writing as we close the port
Glib::RecMutex::Lock lock( _rwlock );
Glib::RecMutex::Lock lock (_rwlock);
_active = false;
MIDI::Manager* mm = MIDI::Manager::instance ();
@ -77,9 +77,9 @@ SurfacePort::~SurfacePort()
}
// wrapper for one day when strerror_r is working properly
string fetch_errmsg( int error_number )
string fetch_errmsg (int error_number)
{
char * msg = strerror( error_number );
char * msg = strerror (error_number);
return msg;
}
@ -91,46 +91,43 @@ MidiByteArray SurfacePort::read()
// check active. Mainly so that the destructor
// doesn't destroy the mutex while it's still locked
if ( !active() ) return retval;
if (!active()) {
return retval;
}
// return nothing read if the lock isn't acquired
#if 0
Glib::RecMutex::Lock lock( _rwlock, Glib::TRY_LOCK );
Glib::RecMutex::Lock lock (_rwlock, Glib::TRY_LOCK);
if ( !lock.locked() )
{
if (!lock.locked()) {
cout << "SurfacePort::read not locked" << endl;
return retval;
}
// check active again - destructor sequence
if ( !active() ) return retval;
if (!active()) return retval;
#endif
// read port and copy to return value
int nread = input_port().read( buf, sizeof (buf) );
int nread = input_port().read (buf, sizeof (buf));
if (nread >= 0) {
retval.copy( nread, buf );
if ((size_t) nread == sizeof (buf))
{
retval.copy (nread, buf);
if ((size_t) nread == sizeof (buf)) {
#ifdef PORT_DEBUG
cout << "SurfacePort::read recursive" << endl;
#endif
retval << read();
}
}
else
{
if ( errno != EAGAIN )
{
} else {
if (errno != EAGAIN) {
ostringstream os;
os << "Surface: error reading from port: " << input_port().name();
os << ": " << errno << fetch_errmsg( errno );
os << ": " << errno << fetch_errmsg (errno);
cout << os.str() << endl;
inactive_event();
throw MackieControlException( os.str() );
throw MackieControlException (os.str());
}
}
#ifdef PORT_DEBUG
@ -139,8 +136,12 @@ MidiByteArray SurfacePort::read()
return retval;
}
void SurfacePort::write( const MidiByteArray & mba )
void SurfacePort::write (const MidiByteArray & mba)
{
if (mba.empty()) {
return;
}
#ifdef PORT_DEBUG
cout << "SurfacePort::write: " << mba << " to " << output_port().name() << endl;
#endif
@ -148,22 +149,18 @@ void SurfacePort::write( const MidiByteArray & mba )
// check active before and after lock - to make sure
// that the destructor doesn't destroy the mutex while
// it's still in use
if ( !active() ) return;
Glib::RecMutex::Lock lock( _rwlock );
if ( !active() ) return;
if (!active()) return;
Glib::RecMutex::Lock lock (_rwlock);
if (!active()) return;
int count = output_port().write( mba.bytes().get(), mba.size(), 0);
if ( count != (int)mba.size() )
{
if ( errno == 0 )
{
int count = output_port().write (mba.bytes().get(), mba.size(), 0);
if (count != (int)mba.size()) {
if (errno == 0) {
cout << "port overflow on " << output_port().name() << ". Did not write all of " << mba << endl;
}
else if ( errno != EAGAIN )
{
} else if (errno != EAGAIN) {
ostringstream os;
os << "Surface: couldn't write to port " << output_port().name();
os << ", error: " << fetch_errmsg( errno ) << "(" << errno << ")";
os << ", error: " << fetch_errmsg (errno) << "(" << errno << ")";
cout << os.str() << endl;
inactive_event();
@ -174,21 +171,25 @@ void SurfacePort::write( const MidiByteArray & mba )
#endif
}
void SurfacePort::write_sysex( const MidiByteArray & mba )
void SurfacePort::write_sysex (const MidiByteArray & mba)
{
if (mba.empty()) {
return;
}
MidiByteArray buf;
buf << sysex_hdr() << mba << MIDI::eox;
write( buf );
write (buf);
}
void SurfacePort::write_sysex( MIDI::byte msg )
void SurfacePort::write_sysex (MIDI::byte msg)
{
MidiByteArray buf;
buf << sysex_hdr() << msg << MIDI::eox;
write( buf );
write (buf);
}
ostream & Mackie::operator << ( ostream & os, const SurfacePort & port )
ostream & Mackie::operator << (ostream & os, const SurfacePort & port)
{
os << "{ ";
os << "name: " << port.input_port().name() << " " << port.output_port().name();
@ -226,13 +227,13 @@ SurfacePort::add_in_use_timeout (Control& in_use_control, Control* touch_control
{
in_use_control.in_use_connection.disconnect ();
/* XXX should this use the GUI event loop (default) or the MIDI UI event loop? */
Glib::RefPtr<Glib::TimeoutSource> timeout (Glib::TimeoutSource::create (250));
/* timeout after 250ms */
in_use_control.in_use_connection = Glib::signal_timeout().connect (
sigc::bind (sigc::mem_fun (*this, &SurfacePort::control_in_use_timeout), &in_use_control, touch_control),
250
);
in_use_control.in_use_connection = timeout->connect (
sigc::bind (sigc::mem_fun (*this, &SurfacePort::control_in_use_timeout), &in_use_control, touch_control));
/* XXX need to access main event loop of MackieControlProtocol */
in_use_control.in_use_touch_control = touch_control;
}

View File

@ -34,7 +34,7 @@ namespace Mackie
/**
Make a relationship between a midi port and a Mackie device.
*/
class SurfacePort
class SurfacePort : public PBD::ScopedConnectionList
{
public:
SurfacePort (MIDI::Port & input_port, MIDI::Port & output_port, int number);