diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-04-08 14:11:00 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-04-08 14:11:00 +0000 |
commit | c72287e67d82e254f4cd089f8e17a16bf89e2335 (patch) | |
tree | 51984ca003e84f74d40839313ab3161267fda0b2 /libs/surfaces | |
parent | 05b36d00929a28a65e19ffffddb2a1b624b780d5 (diff) |
MCP: major redesign of control instantiation; continuing code reformatting
git-svn-id: svn://localhost/ardour2/branches/3.0@11824 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces')
-rw-r--r-- | libs/surfaces/mackie/bcf_surface_generated.cc | 144 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.cc | 274 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.h | 135 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_port.cc | 228 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_port.h | 9 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_surface.cc | 706 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.cc | 12 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface_port.cc | 87 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface_port.h | 2 |
9 files changed, 547 insertions, 1050 deletions
diff --git a/libs/surfaces/mackie/bcf_surface_generated.cc b/libs/surfaces/mackie/bcf_surface_generated.cc index 6f493b1972..05bbd1328a 100644 --- a/libs/surfaces/mackie/bcf_surface_generated.cc +++ b/libs/surfaces/mackie/bcf_surface_generated.cc @@ -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; diff --git a/libs/surfaces/mackie/controls.cc b/libs/surfaces/mackie/controls.cc index 9369bb2b62..c26d0cd709 100644 --- a/libs/surfaces/mackie/controls.cc +++ b/libs/surfaces/mackie/controls.cc @@ -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}() -{ - if ( _#{x.name} == 0 ) - throw MackieControlException( "#{x.name} is null" ); - return *_#{x.name}; -} -EOF -end -*/ -Fader & Strip::gain() +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; +} diff --git a/libs/surfaces/mackie/controls.h b/libs/surfaces/mackie/controls.h index e2157b49ff..f2bca00630 100644 --- a/libs/surfaces/mackie/controls.h +++ b/libs/surfaces/mackie/controls.h @@ -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&); }; } diff --git a/libs/surfaces/mackie/mackie_port.cc b/libs/surfaces/mackie/mackie_port.cc index 02d52207cb..eba8270329 100644 --- a/libs/surfaces/mackie/mackie_port.cc +++ b/libs/surfaces/mackie/mackie_port.cc @@ -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)); - - try - { - // ignore sysex messages - if (raw_bytes[0] == MIDI::sysex) { - return; - } - - // 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()); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackiePort::handle_midi_controller %1 = %2\n", ev->controller_number, ev->value)); + + Control* control; + + 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; - control.set_in_use (true); - add_in_use_timeout (control, &control); - - // emit the control event - control_event (*this, control, state); - 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. + */ + 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)); } diff --git a/libs/surfaces/mackie/mackie_port.h b/libs/surfaces/mackie/mackie_port.h index d12de3a099..7a51e28cd4 100644 --- a/libs/surfaces/mackie/mackie_port.h +++ b/libs/surfaces/mackie/mackie_port.h @@ -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: /** diff --git a/libs/surfaces/mackie/mackie_surface.cc b/libs/surfaces/mackie/mackie_surface.cc index b05f6be0ab..8b406ea4c1 100644 --- a/libs/surfaces/mackie/mackie_surface.cc +++ b/libs/surfaces/mackie/mackie_surface.cc @@ -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; + char name[32]; + 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); + 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); + } -} +} + diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index 863c3ca643..cf6cc7b478 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -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; } } diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc index 031009cd3d..ca04a4214f 100644 --- a/libs/surfaces/mackie/surface_port.cc +++ b/libs/surfaces/mackie/surface_port.cc @@ -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; - - int count = output_port().write( mba.bytes().get(), mba.size(), 0); - if ( count != (int)mba.size() ) - { - if ( errno == 0 ) - { + 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) { 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; } diff --git a/libs/surfaces/mackie/surface_port.h b/libs/surfaces/mackie/surface_port.h index fb2d8d0019..91ca21c0b0 100644 --- a/libs/surfaces/mackie/surface_port.h +++ b/libs/surfaces/mackie/surface_port.h @@ -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); |