diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-04-14 19:02:54 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-04-14 19:02:54 +0000 |
commit | 2ed2b6122410fcd3e08c9bf8f753de512aa5c6b0 (patch) | |
tree | 2c3792dd3eced9a3008fedefdaf9b3816bed53e7 | |
parent | 32766ce215fc2c668c65a54dc1d9436cd11ca413 (diff) |
MCP: redesign to allow device-specific button IDs, since we know that at least one device (nucleus) does not honor mackie's specification document
git-svn-id: svn://localhost/ardour2/branches/3.0@11972 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/surfaces/mackie/button.cc | 85 | ||||
-rw-r--r-- | libs/surfaces/mackie/button.h | 169 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.cc | 10 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.h | 2 | ||||
-rw-r--r-- | libs/surfaces/mackie/device_info.cc | 123 | ||||
-rw-r--r-- | libs/surfaces/mackie/device_info.h | 27 | ||||
-rw-r--r-- | libs/surfaces/mackie/fader.h | 2 | ||||
-rw-r--r-- | libs/surfaces/mackie/jog.cc | 36 | ||||
-rw-r--r-- | libs/surfaces/mackie/jog.h | 4 | ||||
-rw-r--r-- | libs/surfaces/mackie/led.cc | 6 | ||||
-rw-r--r-- | libs/surfaces/mackie/led.h | 6 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.cc | 106 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.h | 6 | ||||
-rw-r--r-- | libs/surfaces/mackie/pot.cc | 2 | ||||
-rw-r--r-- | libs/surfaces/mackie/pot.h | 4 | ||||
-rw-r--r-- | libs/surfaces/mackie/strip.cc | 86 | ||||
-rw-r--r-- | libs/surfaces/mackie/strip.h | 3 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.cc | 138 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.h | 7 | ||||
-rw-r--r-- | libs/surfaces/mackie/wscript | 1 | ||||
-rw-r--r-- | mcp_devices/nucleus.xml | 12 |
21 files changed, 517 insertions, 318 deletions
diff --git a/libs/surfaces/mackie/button.cc b/libs/surfaces/mackie/button.cc index 714294ed7d..588c11d984 100644 --- a/libs/surfaces/mackie/button.cc +++ b/libs/surfaces/mackie/button.cc @@ -24,11 +24,92 @@ using namespace Mackie; Control* -Button::factory (Surface& surface, int id, const char* name, Group& group) +Button::factory (Surface& surface, Button::ID bid, int id, const std::string& name, Group& group) { - Button* b = new Button (id, name, group); + Button* b = new Button (bid, id, name, group); + /* store button with the device-specific ID */ surface.buttons[id] = b; surface.controls.push_back (b); group.add (*b); return b; } + +int +Button::name_to_id (const std::string& name) +{ + if (name == "IO") { return IO; } + if (name == "Sends") { return Sends; } + if (name == "Pan") { return Pan; } + if (name == "Plugin") { return Plugin; } + if (name == "Eq") { return Eq; } + if (name == "Dyn") { return Dyn; } + if (name == "Left") { return Left; } + if (name == "Right") { return Right; } + if (name == "ChannelLeft") { return ChannelLeft; } + if (name == "ChannelRight") { return ChannelRight; } + if (name == "Flip") { return Flip; } + if (name == "Edit") { return Edit; } + if (name == "NameValue") { return NameValue; } + if (name == "TimecodeBeats") { return TimecodeBeats; } + if (name == "F1") { return F1; } + if (name == "F2") { return F2; } + if (name == "F3") { return F3; } + if (name == "F4") { return F4; } + if (name == "F5") { return F5; } + if (name == "F6") { return F6; } + if (name == "F7") { return F7; } + if (name == "F8") { return F8; } + if (name == "F9") { return F9; } + if (name == "F10") { return F10; } + if (name == "F11") { return F11; } + if (name == "F12") { return F12; } + if (name == "F13") { return F13; } + if (name == "F14") { return F14; } + if (name == "F15") { return F15; } + if (name == "F16") { return F16; } + if (name == "Shift") { return Shift; } + if (name == "Option") { return Option; } + if (name == "Ctrl") { return Ctrl; } + if (name == "CmdAlt") { return CmdAlt; } + if (name == "On") { return On; } + if (name == "RecReady") { return RecReady; } + if (name == "Undo") { return Undo; } + if (name == "Save") { return Save; } + if (name == "Touch") { return Touch; } + if (name == "Redo") { return Redo; } + if (name == "Marker") { return Marker; } + if (name == "Enter") { return Enter; } + if (name == "Cancel") { return Cancel; } + if (name == "Mixer") { return Mixer; } + if (name == "FrmLeft") { return FrmLeft; } + if (name == "FrmRight") { return FrmRight; } + if (name == "Loop") { return Loop; } + if (name == "PunchIn") { return PunchIn; } + if (name == "PunchOut") { return PunchOut; } + if (name == "Home") { return Home; } + if (name == "End") { return End; } + if (name == "Rewind") { return Rewind; } + if (name == "Ffwd") { return Ffwd; } + if (name == "Stop") { return Stop; } + if (name == "Play") { return Play; } + if (name == "Record") { return Record; } + if (name == "CursorUp") { return CursorUp; } + if (name == "CursorDown") { return CursorDown; } + if (name == "CursorLeft") { return CursorLeft; } + if (name == "CursorRight") { return CursorRight; } + if (name == "Zoom") { return Zoom; } + if (name == "Scrub") { return Scrub; } + if (name == "UserA") { return UserA; } + if (name == "UserB") { return UserB; } + + /* Strip buttons */ + + if (name == "RecEnable") { return RecEnable; } + if (name == "Solo") { return Solo; } + if (name == "Mute") { return Mute; } + if (name == "Select") { return Select; } + if (name == "VSelect") { return VSelect; } + if (name == "FaderTouch") { return FaderTouch; } + + return -1; +} diff --git a/libs/surfaces/mackie/button.h b/libs/surfaces/mackie/button.h index 2702452750..48ea9c5919 100644 --- a/libs/surfaces/mackie/button.h +++ b/libs/surfaces/mackie/button.h @@ -30,92 +30,105 @@ class Surface; class Button : public Control { public: - enum base_id_t { - recenable_base_id = 0x0, - solo_base_id = 0x08, - mute_base_id = 0x10, - select_base_id = 0x18, - vselect_base_id = 0x20, - fader_touch_base_id = 0x68, // 0xe0, - }; +/* These values uniquely identify each possible button that an MCP device may + send. Each DeviceInfo object contains its own set of button definitions that + define what device ID will be sent for each button, and there is no reason + for them to be the same. */ - enum ButtonID { - Io = 0x28, - Sends = 0x29, - Pan = 0x2a, - Plugin = 0x2b, - Eq = 0x2c, - Dyn = 0x2d, - Left = 0x2e, - Right = 0x2f, - ChannelLeft = 0x30, - ChannelRight = 0x31, - Flip = 0x32, - Edit = 0x33, - NameValue = 0x34, - TimecodeBeats = 0x35, - F1 = 0x36, - F2 = 0x37, - F3 = 0x38, - F4 = 0x39, - F5 = 0x3a, - F6 = 0x3b, - F7 = 0x3c, - F8 = 0x3d, - F9 = 0x3e, - F10 = 0x3f, - F11 = 0x40, - F12 = 0x41, - F13 = 0x42, - F14 = 0x43, - F15 = 0x44, - F16 = 0x45, - Shift = 0x46, - Option = 0x47, - Ctrl = 0x48, - CmdAlt = 0x49, - On = 0x4a, - RecReady = 0x4b, - Undo = 0x4c, - Save = 0x4d, - Touch = 0x4e, - Redo = 0x4f, - Marker = 0x50, - Enter = 0x51, - Cancel = 0x52, - Mixer = 0x53, - FrmLeft = 0x54, - FrmRight = 0x55, - Loop = 0x56, - PunchIn = 0x57, - PunchOut = 0x58, - Home = 0x59, - End = 0x5a, - Rewind = 0x5b, - Ffwd = 0x5c, - Stop = 0x5d, - Play = 0x5e, - Record = 0x5f, - CursorUp = 0x60, - CursorDown = 0x61, - CursorLeft = 0x62, - CursorRight = 0x63, - Zoom = 0x64, - Scrub = 0x65, - UserA = 0x66, - UserB = 0x67, + enum ID { + /* Global Buttons */ + + IO, + Sends, + Pan, + Plugin, + Eq, + Dyn, + Left, + Right, + ChannelLeft, + ChannelRight, + Flip, + Edit, + NameValue, + TimecodeBeats, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + Shift, + Option, + Ctrl, + CmdAlt, + On, + RecReady, + Undo, + Save, + Touch, + Redo, + Marker, + Enter, + Cancel, + Mixer, + FrmLeft, + FrmRight, + Loop, + PunchIn, + PunchOut, + Home, + End, + Rewind, + Ffwd, + Stop, + Play, + Record, + CursorUp, + CursorDown, + CursorLeft, + CursorRight, + Zoom, + Scrub, + UserA, + UserB, + + /* Strip buttons */ + + RecEnable, + Solo, + Mute, + Select, + VSelect, + FaderTouch, }; - Button (int id, std::string name, Group & group) - : Control (id, name, group) - , _led (id, name + "_led", group) {} + + Button (ID bid, int did, std::string name, Group & group) + : Control (did, name, group) + , _bid (bid) + , _led (did, name + "_led", group) {} MidiByteArray zero() { return _led.zero (); } MidiByteArray set_state (LedState ls) { return _led.set_state (ls); } - - static Control* factory (Surface&, int id, const char*, Group&); + ID bid() const { return _bid; } + + static Control* factory (Surface& surface, Button::ID bid, int id, const std::string&, Group& group); + static int name_to_id (const std::string& name); + private: + ID _bid; /* device independent button ID */ Led _led; }; diff --git a/libs/surfaces/mackie/controls.cc b/libs/surfaces/mackie/controls.cc index 0e95d6ee95..24b59fd744 100644 --- a/libs/surfaces/mackie/controls.cc +++ b/libs/surfaces/mackie/controls.cc @@ -83,16 +83,6 @@ ostream & Mackie::operator << (ostream & os, const Mackie::Control & control) return os; } -Control* -Jog::factory (Surface& surface, int id, const char* name, Group& group) -{ - Jog* j = new Jog (id, name, group); - surface.controls.push_back (j); - surface.controls_by_name["jog"] = j; - group.add (*j); - return j; -} - void Control::set_normal_control (boost::shared_ptr<AutomationControl> ac) { diff --git a/libs/surfaces/mackie/controls.h b/libs/surfaces/mackie/controls.h index 8538cace88..eb9a691972 100644 --- a/libs/surfaces/mackie/controls.h +++ b/libs/surfaces/mackie/controls.h @@ -85,7 +85,7 @@ public: boost::shared_ptr<ARDOUR::AutomationControl> modified_ac; private: - int _id; + int _id; /* possibly device-dependent ID */ std::string _name; Group& _group; bool _in_use; diff --git a/libs/surfaces/mackie/device_info.cc b/libs/surfaces/mackie/device_info.cc index 9b15baf208..1ec9c2e788 100644 --- a/libs/surfaces/mackie/device_info.cc +++ b/libs/surfaces/mackie/device_info.cc @@ -17,6 +17,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <cstdlib> #include <cstring> #include <glibmm/miscutils.h> @@ -50,7 +51,83 @@ DeviceInfo::DeviceInfo() , _has_touch_sense_faders (true) , _name (X_("Mackie Control Universal Pro")) { - + /* these definitions are based on Mackie's specification for Mackie + * Control Protocol. + * + * Any given device info file can override any or all of these for any reason. + */ + + _global_buttons[Button::IO] = GlobalButtonInfo ("io", "assignment", 0x28); + _global_buttons[Button::Sends] = GlobalButtonInfo ("sends", "assignment", 0x29); + _global_buttons[Button::Pan] = GlobalButtonInfo ("pan", "assignment", 0x2a); + _global_buttons[Button::Plugin] = GlobalButtonInfo ("plugin", "assignment", 0x2b); + _global_buttons[Button::Eq] = GlobalButtonInfo ("eq", "assignment", 0x2c); + _global_buttons[Button::Dyn] = GlobalButtonInfo ("dyn", "assignment", 0x2d); + _global_buttons[Button::Left] = GlobalButtonInfo ("left", "bank", 0x2e); + _global_buttons[Button::Right] = GlobalButtonInfo ("right", "bank", 0x2f); + _global_buttons[Button::ChannelLeft] = GlobalButtonInfo ("channel left", "bank", 0x30); + _global_buttons[Button::ChannelRight] = GlobalButtonInfo ("channelright", "bank", 0x31); + _global_buttons[Button::Flip] = GlobalButtonInfo ("flip", "none", 0x32); + _global_buttons[Button::Edit] = GlobalButtonInfo ("edit", "none", 0x33); + _global_buttons[Button::NameValue] = GlobalButtonInfo ("name/value", "display", 0x34); + _global_buttons[Button::TimecodeBeats] = GlobalButtonInfo ("timecode/beats", "display", 0x35); + _global_buttons[Button::F1] = GlobalButtonInfo ("F1", "none", 0x36); + _global_buttons[Button::F2] = GlobalButtonInfo ("F2", "none", 0x37); + _global_buttons[Button::F3] = GlobalButtonInfo ("F3", "none", 0x38); + _global_buttons[Button::F4] = GlobalButtonInfo ("F4", "none", 0x39); + _global_buttons[Button::F5] = GlobalButtonInfo ("F5", "none", 0x3a); + _global_buttons[Button::F6] = GlobalButtonInfo ("F6", "none", 0x3b); + _global_buttons[Button::F7] = GlobalButtonInfo ("F7", "none", 0x3c); + _global_buttons[Button::F8] = GlobalButtonInfo ("F8", "none", 0x3d); + _global_buttons[Button::F9] = GlobalButtonInfo ("F9", "none", 0x3e); + _global_buttons[Button::F10] = GlobalButtonInfo ("F10", "none", 0x3f); + _global_buttons[Button::F11] = GlobalButtonInfo ("F11", "none", 0x40); + _global_buttons[Button::F12] = GlobalButtonInfo ("F12", "none", 0x41); + _global_buttons[Button::F13] = GlobalButtonInfo ("F13", "none", 0x42); + _global_buttons[Button::F14] = GlobalButtonInfo ("F14", "none", 0x43); + _global_buttons[Button::F15] = GlobalButtonInfo ("F15", "none", 0x44); + _global_buttons[Button::F16] = GlobalButtonInfo ("F16", "none", 0x45); + _global_buttons[Button::Shift] = GlobalButtonInfo ("shift", "modifiers", 0x46); + _global_buttons[Button::Option] = GlobalButtonInfo ("option", "modifiers", 0x47); + _global_buttons[Button::Ctrl] = GlobalButtonInfo ("control", "modifiers", 0x48); + _global_buttons[Button::CmdAlt] = GlobalButtonInfo ("cmd_alt", "modifiers", 0x49); + _global_buttons[Button::On] = GlobalButtonInfo ("on", "automation", 0x4a); + _global_buttons[Button::RecReady] = GlobalButtonInfo ("rec_ready", "automation", 0x4b); + _global_buttons[Button::Undo] = GlobalButtonInfo ("undo", "functions", 0x4c); + _global_buttons[Button::Save] = GlobalButtonInfo ("save", "automation", 0x4d); + _global_buttons[Button::Touch] = GlobalButtonInfo ("touch", "automation", 0x4e); + _global_buttons[Button::Redo] = GlobalButtonInfo ("redo", "functions", 0x4f); + _global_buttons[Button::Marker] = GlobalButtonInfo ("marker", "functions", 0x50); + _global_buttons[Button::Enter] = GlobalButtonInfo ("enter", "functions", 0x51); + _global_buttons[Button::Cancel] = GlobalButtonInfo ("cancel", "functions", 0x52); + _global_buttons[Button::Mixer] = GlobalButtonInfo ("mixer", "functions", 0x53); + _global_buttons[Button::FrmLeft] = GlobalButtonInfo ("frm left", "transport", 0x54); + _global_buttons[Button::FrmRight] = GlobalButtonInfo ("frm right", "transport", 0x55); + _global_buttons[Button::Loop] = GlobalButtonInfo ("loop", "transport", 0x56); + _global_buttons[Button::PunchIn] = GlobalButtonInfo ("punch in", "transport", 0x57); + _global_buttons[Button::PunchOut] = GlobalButtonInfo ("punch out", "transport", 0x58); + _global_buttons[Button::Home] = GlobalButtonInfo ("home", "transport", 0x59); + _global_buttons[Button::End] = GlobalButtonInfo ("end", "transport", 0x5a); + _global_buttons[Button::Rewind] = GlobalButtonInfo ("rewind", "transport", 0x5b); + _global_buttons[Button::Ffwd] = GlobalButtonInfo ("ffwd", "transport", 0x5c); + _global_buttons[Button::Stop] = GlobalButtonInfo ("stop", "transport", 0x5d); + _global_buttons[Button::Play] = GlobalButtonInfo ("play", "transport", 0x5e); + _global_buttons[Button::Record] = GlobalButtonInfo ("record", "transport", 0x5f); + _global_buttons[Button::CursorUp] = GlobalButtonInfo ("cursor up", "cursor", 0x60); + _global_buttons[Button::CursorDown] = GlobalButtonInfo ("cursor down", "cursor", 0x61); + _global_buttons[Button::CursorLeft] = GlobalButtonInfo ("cursor left", "cursor", 0x62); + _global_buttons[Button::CursorRight] = GlobalButtonInfo ("cursor right", "cursor", 0x63); + _global_buttons[Button::Zoom] = GlobalButtonInfo ("zoom", "none", 0x64); + _global_buttons[Button::Scrub] = GlobalButtonInfo ("scrub", "none", 0x65); + _global_buttons[Button::UserA] = GlobalButtonInfo ("user a", "user", 0x66); + _global_buttons[Button::UserB] = GlobalButtonInfo ("user b", "user", 0x67); + + _strip_buttons[Button::RecEnable], StripButtonInfo (0x0, "recenable"); + _strip_buttons[Button::Solo] = StripButtonInfo (0x08, "solo"); + _strip_buttons[Button::Mute] = StripButtonInfo (0x10, "mute"); + _strip_buttons[Button::Select] = StripButtonInfo (0x18, "select"); + _strip_buttons[Button::VSelect] = StripButtonInfo (0x20, "vselect"); + _strip_buttons[Button::FaderTouch] = StripButtonInfo (0x68, "fader touch"); } DeviceInfo::~DeviceInfo() @@ -134,6 +211,50 @@ DeviceInfo::set_state (const XMLNode& node, int /* version */) _has_touch_sense_faders = string_is_affirmative (prop->value()); } } + if ((child = node.child ("Buttons")) != 0) { + XMLNodeConstIterator i; + const XMLNodeList& nlist (child->children()); + + for (i = nlist.begin(); i != nlist.end(); ++i) { + if ((*i)->name() == "GlobalButton") { + if ((prop = (*i)->property ("name")) != 0) { + int id = Button::name_to_id (prop->value()); + if (id >= 0) { + Button::ID bid = (Button::ID) id; + if ((prop = (*i)->property ("id")) != 0) { + int val = strtol (prop->value().c_str(), 0, 0); + std::map<Button::ID,GlobalButtonInfo>::iterator b = _global_buttons.find (bid); + if (b != _global_buttons.end()) { + b->second.id = val; + + if ((prop = (*i)->property ("label")) != 0) { + b->second.label = prop->value(); + } + } + } + } + + } + + } else if ((*i)->name() == "StripButton") { + if ((prop = (*i)->property ("name")) != 0) { + int id = Button::name_to_id (prop->value()); + if (id >= 0) { + Button::ID bid = (Button::ID) id; + if ((prop = (*i)->property ("baseid")) != 0) { + int val = strtol (prop->value().c_str(), 0, 0); + std::map<Button::ID,StripButtonInfo>::iterator b = _strip_buttons.find (bid); + if (b != _strip_buttons.end()) { + b->second.base_id = val; + } + } + } + + } + + } + } + } return 0; } diff --git a/libs/surfaces/mackie/device_info.h b/libs/surfaces/mackie/device_info.h index 191ccfc4ce..9ca51cae71 100644 --- a/libs/surfaces/mackie/device_info.h +++ b/libs/surfaces/mackie/device_info.h @@ -25,10 +25,31 @@ #include <string> #include <map> +#include "button.h" + class XMLNode; namespace Mackie { +struct GlobalButtonInfo { + std::string label; // visible to user + std::string group; // in case we want to present in a GUI + int32_t id; // value sent by device + + GlobalButtonInfo () : id (-1) {} + GlobalButtonInfo (const std::string& l, const std::string& g, uint32_t i) + : label (l), group (g), id (i) {} +}; + +struct StripButtonInfo { + int32_t base_id; + std::string name; + + StripButtonInfo () : base_id (-1) {} + StripButtonInfo (uint32_t i, const std::string& n) + : base_id (i), name (n) {} +}; + class DeviceInfo { public: @@ -51,6 +72,9 @@ class DeviceInfo static std::map<std::string,DeviceInfo> device_info; static void reload_device_info(); + const std::map<Button::ID,GlobalButtonInfo>& global_buttons() const { return _global_buttons; } + const std::map<Button::ID,StripButtonInfo>& strip_buttons() const { return _strip_buttons; } + private: uint32_t _strip_cnt; uint32_t _extenders; @@ -62,6 +86,9 @@ class DeviceInfo bool _has_jog_wheel; bool _has_touch_sense_faders; std::string _name; + + std::map<Button::ID,GlobalButtonInfo> _global_buttons; + std::map<Button::ID,StripButtonInfo> _strip_buttons; }; class DeviceProfile diff --git a/libs/surfaces/mackie/fader.h b/libs/surfaces/mackie/fader.h index 3520699e98..ed8e72eb50 100644 --- a/libs/surfaces/mackie/fader.h +++ b/libs/surfaces/mackie/fader.h @@ -20,7 +20,7 @@ class Fader : public Control MidiByteArray update_message (); static Control* factory (Surface&, int id, const char*, Group&); - + private: float position; }; diff --git a/libs/surfaces/mackie/jog.cc b/libs/surfaces/mackie/jog.cc new file mode 100644 index 0000000000..dc832868ed --- /dev/null +++ b/libs/surfaces/mackie/jog.cc @@ -0,0 +1,36 @@ +/* + Copyright (C) 2006,2007 John Anderson + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "jog.h" +#include "surface.h" +#include "control_group.h" + +using namespace Mackie; + +const int Jog::ID = 0x3c; + +Control* +Jog::factory (Surface& surface, int id, const char* name, Group& group) +{ + Jog* j = new Jog (id, name, group); + surface.pots[id] = j; + surface.controls.push_back (j); + group.add (*j); + return j; +} diff --git a/libs/surfaces/mackie/jog.h b/libs/surfaces/mackie/jog.h index a4a6b739de..23451f92b2 100644 --- a/libs/surfaces/mackie/jog.h +++ b/libs/surfaces/mackie/jog.h @@ -28,9 +28,7 @@ namespace Mackie { class Jog : public Pot { public: - enum base_id_t { - base_id = 0x3c - }; + static const int ID; Jog (int id, std::string name, Group & group) : Pot (id, name, group) diff --git a/libs/surfaces/mackie/led.cc b/libs/surfaces/mackie/led.cc index 342db049a5..38aa5c7f3b 100644 --- a/libs/surfaces/mackie/led.cc +++ b/libs/surfaces/mackie/led.cc @@ -23,6 +23,12 @@ using namespace Mackie; +const int Led::FaderTouch = 0x70; +const int Led::Timecode = 0x71; +const int Led::Beats = 0x72; +const int Led::RudeSolo = 0x73; +const int Led::RelayClick = 0x74; + Control* Led::factory (Surface& surface, int id, const char* name, Group& group) { diff --git a/libs/surfaces/mackie/led.h b/libs/surfaces/mackie/led.h index fca9b78a43..fdbeb8cd9c 100644 --- a/libs/surfaces/mackie/led.h +++ b/libs/surfaces/mackie/led.h @@ -29,6 +29,12 @@ namespace Mackie { class Led : public Control { public: + static const int FaderTouch; + static const int Timecode; + static const int Beats; + static const int RudeSolo; + static const int RelayClick; + Led (int id, std::string name, Group & group) : Control (id, name, group) , state (off) diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index 7aa78d8c02..3f98e98ac9 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -409,12 +409,12 @@ MackieControlProtocol::update_timecode_beats_led() { switch (_timecode_type) { case ARDOUR::AnyTime::BBT: - update_global_led ("beats", on); - update_global_led ("timecode", off); + update_global_led (Led::Beats, on); + update_global_led (Led::Timecode, off); break; case ARDOUR::AnyTime::Timecode: - update_global_led ("timecode", on); - update_global_led ("beats", off); + update_global_led (Led::Timecode, on); + update_global_led (Led::Beats, off); break; default: ostringstream os; @@ -424,7 +424,7 @@ MackieControlProtocol::update_timecode_beats_led() } void -MackieControlProtocol::update_global_button (const string & name, LedState ls) +MackieControlProtocol::update_global_button (int id, LedState ls) { boost::shared_ptr<Surface> surface = surfaces.front(); @@ -432,16 +432,17 @@ MackieControlProtocol::update_global_button (const string & name, LedState ls) return; } - if (surface->controls_by_name.find (name) != surface->controls_by_name.end()) { - Button * button = dynamic_cast<Button*> (surface->controls_by_name[name]); + map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (id); + if (x != surface->controls_by_device_independent_id.end()) { + Button * button = dynamic_cast<Button*> (x->second); surface->write (button->set_state (ls)); } else { - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Button %1 not found\n", name)); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Button %1 not found\n", id)); } } void -MackieControlProtocol::update_global_led (const string & name, LedState ls) +MackieControlProtocol::update_global_led (int id, LedState ls) { boost::shared_ptr<Surface> surface = surfaces.front(); @@ -449,11 +450,12 @@ MackieControlProtocol::update_global_led (const string & name, LedState ls) return; } - if (surface->controls_by_name.find (name) != surface->controls_by_name.end()) { - Led * led = dynamic_cast<Led*> (surface->controls_by_name[name]); + map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (id); + if (x != surface->controls_by_device_independent_id.end()) { + Led * led = dynamic_cast<Led*> (x->second); surface->write (led->set_state (ls)); } else { - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Led %1 not found\n", name)); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Led %1 not found\n", id)); } } @@ -755,11 +757,11 @@ MackieControlProtocol::update_timecode_display() void MackieControlProtocol::notify_parameter_changed (std::string const & p) { if (p == "punch-in") { - update_global_button ("punch_in", session->config.get_punch_in()); + update_global_button (Button::PunchIn, session->config.get_punch_in()); } else if (p == "punch-out") { - update_global_button ("punch_out", session->config.get_punch_out()); + update_global_button (Button::PunchOut, session->config.get_punch_out()); } else if (p == "clicking") { - update_global_button ("clicking", Config->get_clicking()); + // update_global_button (Button::RelayClick, Config->get_clicking()); } else { DEBUG_TRACE (DEBUG::MackieControl, string_compose ("parameter changed: %1\n", p)); } @@ -789,10 +791,12 @@ MackieControlProtocol::notify_solo_active_changed (bool active) { boost::shared_ptr<Surface> surface = surfaces.front(); - Led* rude_solo = dynamic_cast<Led*> (surface->controls_by_name["solo"]); - - if (rude_solo) { - surface->write (rude_solo->set_state (active ? flashing : off)); + map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (Led::RudeSolo); + if (x != surface->controls_by_device_independent_id.end()) { + Led* rude_solo = dynamic_cast<Led*> (x->second); + if (rude_solo) { + surface->write (rude_solo->set_state (active ? flashing : off)); + } } } @@ -821,17 +825,17 @@ MackieControlProtocol::notify_remote_id_changed() void MackieControlProtocol::notify_loop_state_changed() { - update_global_button ("loop", session->get_play_loop()); + update_global_button (Button::Loop, session->get_play_loop()); } void MackieControlProtocol::notify_transport_state_changed() { // switch various play and stop buttons on / off - update_global_button ("play", session->transport_speed() == 1.0); - update_global_button ("stop", !session->transport_rolling()); - update_global_button ("rewind", session->transport_speed() < 0.0); - update_global_button ("ffwd", session->transport_speed() > 1.0); + update_global_button (Button::Play, session->transport_speed() == 1.0); + update_global_button (Button::Stop, !session->transport_rolling()); + update_global_button (Button::Rewind, session->transport_speed() < 0.0); + update_global_button (Button::Ffwd, session->transport_speed() > 1.0); _transport_previously_rolling = session->transport_rolling(); } @@ -839,31 +843,33 @@ MackieControlProtocol::notify_transport_state_changed() void MackieControlProtocol::notify_record_state_changed () { - /* rec is a tristate */ - + boost::shared_ptr<Surface> surface = surfaces.front(); - Button * rec = reinterpret_cast<Button*> (surfaces.front()->controls_by_name["record"]); - if (rec) { - LedState ls; + /* rec is a tristate */ - switch (session->record_status()) { - case Session::Disabled: - DEBUG_TRACE (DEBUG::MackieControl, "record state changed to disabled, LED off\n"); - ls = off; - break; - case Session::Recording: - DEBUG_TRACE (DEBUG::MackieControl, "record state changed to recording, LED on\n"); - ls = on; - break; - case Session::Enabled: - DEBUG_TRACE (DEBUG::MackieControl, "record state changed to enabled, LED flashing\n"); - ls = flashing; - break; + map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (Button::Record); + if (x != surface->controls_by_device_independent_id.end()) { + Button * rec = dynamic_cast<Button*> (x->second); + if (rec) { + LedState ls; + + switch (session->record_status()) { + case Session::Disabled: + DEBUG_TRACE (DEBUG::MackieControl, "record state changed to disabled, LED off\n"); + ls = off; + break; + case Session::Recording: + DEBUG_TRACE (DEBUG::MackieControl, "record state changed to recording, LED on\n"); + ls = on; + break; + case Session::Enabled: + DEBUG_TRACE (DEBUG::MackieControl, "record state changed to enabled, LED flashing\n"); + ls = flashing; + break; + } + + surface->write (rec->set_state (ls)); } - - surfaces.front()->write (rec->set_state (ls)); - } else { - DEBUG_TRACE (DEBUG::MackieControl, "record button control not found\n"); } } @@ -969,9 +975,9 @@ MackieControlProtocol::update_led (Surface& surface, Button& button, Mackie::Led void MackieControlProtocol::build_button_map () { -#define DEFINE_BUTTON_HANDLER(b,p,r) button_map.insert (pair<int,ButtonHandlers> ((b), ButtonHandlers ((p),(r)))); +#define DEFINE_BUTTON_HANDLER(b,p,r) button_map.insert (pair<Button::ID,ButtonHandlers> ((b), ButtonHandlers ((p),(r)))); - DEFINE_BUTTON_HANDLER (Button::Io, &MackieControlProtocol::io_press, &MackieControlProtocol::io_release); + DEFINE_BUTTON_HANDLER (Button::IO, &MackieControlProtocol::io_press, &MackieControlProtocol::io_release); DEFINE_BUTTON_HANDLER (Button::Sends, &MackieControlProtocol::sends_press, &MackieControlProtocol::sends_release); DEFINE_BUTTON_HANDLER (Button::Pan, &MackieControlProtocol::pan_press, &MackieControlProtocol::pan_release); DEFINE_BUTTON_HANDLER (Button::Plugin, &MackieControlProtocol::plugin_press, &MackieControlProtocol::plugin_release); @@ -1047,7 +1053,9 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2\n", (bs == press ? "press" : "release"), button.id())); - ButtonMap::iterator b = button_map.find (button.id()); + /* lookup using the device-INDEPENDENT button ID */ + + ButtonMap::iterator b = button_map.find (button.bid()); if (b != button_map.end()) { diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index 83b77bd7f2..c4cda58c26 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -171,8 +171,8 @@ class MackieControlProtocol /// this is called to generate the midi to send in response to a button press. void update_led(Mackie::Surface&, Mackie::Button & button, Mackie::LedState); - void update_global_button(const std::string & name, Mackie::LedState); - void update_global_led(const std::string & name, Mackie::LedState); + void update_global_button (int id, Mackie::LedState); + void update_global_led (int id, Mackie::LedState); ARDOUR::Session & get_session() { return *session; } framepos_t transport_frame() const; @@ -247,7 +247,7 @@ class MackieControlProtocol , release (r) {} }; - typedef std::map<int,ButtonHandlers> ButtonMap; + typedef std::map<Mackie::Button::ID,ButtonHandlers> ButtonMap; typedef std::list<GSource*> PortSources; static MackieControlProtocol* _instance; diff --git a/libs/surfaces/mackie/pot.cc b/libs/surfaces/mackie/pot.cc index 1320512e92..0b3062be8c 100644 --- a/libs/surfaces/mackie/pot.cc +++ b/libs/surfaces/mackie/pot.cc @@ -24,6 +24,8 @@ using namespace Mackie; +int const Pot::External = 0x2e; + Control* Pot::factory (Surface& surface, int id, const char* name, Group& group) { diff --git a/libs/surfaces/mackie/pot.h b/libs/surfaces/mackie/pot.h index e8a6b0dc43..5aa4f297d1 100644 --- a/libs/surfaces/mackie/pot.h +++ b/libs/surfaces/mackie/pot.h @@ -27,9 +27,7 @@ namespace Mackie { class Pot : public Control { public: - enum base_id_t { - base_id = 0x10, - }; + static int const External; enum Mode { dot = 0, diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc index dc7a15fe6a..2d65b663ca 100644 --- a/libs/surfaces/mackie/strip.cc +++ b/libs/surfaces/mackie/strip.cc @@ -59,7 +59,7 @@ using namespace PBD; extern PBD::EventLoop::InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int); #define invalidator() __invalidator (*(MackieControlProtocol::instance()), __FILE__, __LINE__) -Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefinition* ctls) +Strip::Strip (Surface& s, const std::string& name, int index, const map<Button::ID,StripButtonInfo>& strip_buttons) : Group (name) , _solo (0) , _recenable (0) @@ -76,75 +76,51 @@ Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefini , _last_gain_position_written (-1.0) , _last_pan_position_written (-1.0) { - /* build the controls for this track, which will automatically add them - to the Group - */ + _fader = dynamic_cast<Fader*> (Fader::factory (*_surface, index, "fader", *this)); + _vpot = dynamic_cast<Pot*> (Pot::factory (*_surface, index, "vpot", *this)); + _meter = dynamic_cast<Meter*> (Meter::factory (*_surface, index, "meter", *this)); - for (uint32_t i = 0; ctls[i].name[0]; ++i) { - ctls[i].factory (*_surface, ctls[i].base_id + index, ctls[i].name, *this); + for (map<Button::ID,StripButtonInfo>::const_iterator b = strip_buttons.begin(); b != strip_buttons.end(); ++b) { + (void) Button::factory (*_surface, b->first, b->second.base_id + index, b->second.name, *this); } } Strip::~Strip () { + /* surface is responsible for deleting all controls */ } -/** - TODO could optimise this to use enum, but it's only - called during the protocol class instantiation. -*/ -void Strip::add (Control & control) +void +Strip::add (Control & control) { - Group::add (control); - - Fader* fader; - Pot* pot; Button* button; - Meter* meter; - - if ((fader = dynamic_cast<Fader*>(&control)) != 0) { - _fader = fader; - - } else if ((pot = dynamic_cast<Pot*>(&control)) != 0) { - - _vpot = pot; + Group::add (control); - } else if ((button = dynamic_cast<Button*>(&control)) != 0) { + /* fader, vpot, meter were all set explicitly */ - if (control.id() >= Button::recenable_base_id && - control.id() < Button::recenable_base_id + 8) { - + if ((button = dynamic_cast<Button*>(&control)) != 0) { + switch (button->bid()) { + case Button::RecEnable: _recenable = button; - - } else if (control.id() >= Button::mute_base_id && - control.id() < Button::mute_base_id + 8) { - + break; + case Button::Mute: _mute = button; - - } else if (control.id() >= Button::solo_base_id && - control.id() < Button::solo_base_id + 8) { - + break; + case Button::Solo: _solo = button; - - } else if (control.id() >= Button::select_base_id && - control.id() < Button::select_base_id + 8) { - + break; + case Button::Select: _select = button; - - } else if (control.id() >= Button::vselect_base_id && - control.id() < Button::vselect_base_id + 8) { - + break; + case Button::VSelect: _vselect = button; - - } else if (control.id() >= Button::fader_touch_base_id && - control.id() < Button::fader_touch_base_id + 8) { - + break; + case Button::FaderTouch: _fader_touch = button; + default: + break; } - - } else if ((meter = dynamic_cast<Meter*>(&control)) != 0) { - _meter = meter; } } @@ -385,14 +361,13 @@ Strip::handle_button (Button& button, ButtonState bs) button.set_in_use (false); } - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 handling button %2 press ? %3\n", _index, button.id(), (bs == press))); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 handling button %2 press ? %3\n", _index, button.bid(), (bs == press))); int lock_mod = (MackieControlProtocol::MODIFIER_CONTROL|MackieControlProtocol::MODIFIER_SHIFT); int ms = _surface->mcp().modifier_state(); bool modified = (ms & MackieControlProtocol::MODIFIER_CONTROL); - if (button.id() >= Button::select_base_id && - button.id() < Button::select_base_id + 8) { + if (button.bid() == Button::Select) { DEBUG_TRACE (DEBUG::MackieControl, string_compose ("select touch, lock ? %1\n", ((ms & lock_mod) == lock_mod) ? 1 : 0)); @@ -415,9 +390,8 @@ Strip::handle_button (Button& button, ButtonState bs) return; } - - if ((button.id() >= Button::fader_touch_base_id && - button.id() < Button::fader_touch_base_id + 8)) { + + if (button.bid() == Button::FaderTouch) { DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader touch, press ? %1\n", (bs == press))); diff --git a/libs/surfaces/mackie/strip.h b/libs/surfaces/mackie/strip.h index 2324f84447..56c6a2f720 100644 --- a/libs/surfaces/mackie/strip.h +++ b/libs/surfaces/mackie/strip.h @@ -13,6 +13,7 @@ #include "control_group.h" #include "types.h" #include "midi_byte_array.h" +#include "device_info.h" namespace ARDOUR { class Route; @@ -47,7 +48,7 @@ struct GlobalControlDefinition { class Strip : public Group { public: - Strip (Surface&, const std::string & name, int index, StripControlDefinition* ctls); + Strip (Surface&, const std::string & name, int index, const std::map<Button::ID,StripButtonInfo>&); ~Strip(); boost::shared_ptr<ARDOUR::Route> route() const { return _route; } diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index 2f87b844f0..6d47393f60 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -50,81 +50,6 @@ static MidiByteArray mackie_sysex_hdr_xt (5, MIDI::sysex, 0x0, 0x0, 0x66, 0x15) static MidiByteArray empty_midi_byte_array; -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", Button::F1, Button::factory, "none" }, - { "F2", Button::F2, Button::factory, "none" }, - { "F3", Button::F3, Button::factory, "none" }, - { "F4", Button::F4, Button::factory, "none" }, - { "F5", Button::F5, Button::factory, "none" }, - { "F6", Button::F6, Button::factory, "none" }, - { "F7", Button::F7, Button::factory, "none" }, - { "F8", Button::F8, Button::factory, "none" }, - { "F9", Button::F9, Button::factory, "none" }, - { "F10", Button::F10, Button::factory, "none" }, - { "F11", Button::F11, Button::factory, "none" }, - { "F12", Button::F12, Button::factory, "none" }, - { "F13", Button::F13, Button::factory, "none" }, - { "F14", Button::F14, Button::factory, "none" }, - { "F15", Button::F15, Button::factory, "none" }, - { "F16", Button::F16, 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" }, - { "save", Button::Save, Button::factory, "automation" }, - { "touch", Button::Touch, Button::factory, "automation" }, - { "redo", Button::Redo, Button::factory, "functions" }, - { "marker", Button::Marker, Button::factory, "functions" }, - { "enter", Button::Enter, Button::factory, "functions" }, - { "cancel", Button::Cancel, Button::factory, "functions" }, - { "mixer", Button::Mixer, Button::factory, "functions" }, - { "frm_left", 0x54, Button::factory, "transport" }, - { "frm_right", 0x55, Button::factory, "transport" }, - { "loop", Button::Loop, Button::factory, "transport" }, - { "punch_in", 0x57, Button::factory, "transport" }, - { "punch_out", 0x58, Button::factory, "transport" }, - { "home", Button::Home, Button::factory, "transport" }, - { "end", Button::End, Button::factory, "transport" }, - { "rewind", Button::Rewind, Button::factory, "transport" }, - { "ffwd", Button::Ffwd, Button::factory, "transport" }, - { "stop", Button::Stop, Button::factory, "transport" }, - { "play", Button::Play, Button::factory, "transport" }, - { "record", Button::Record, Button::factory, "transport" }, - { "cursor_up", Button::CursorUp, Button::factory, "cursor" }, - { "cursor_down", Button::CursorDown, Button::factory, "cursor" }, - { "cursor_left", Button::CursorLeft, Button::factory, "cursor" }, - { "cursor_right", Button::CursorRight, Button::factory, "cursor" }, - { "zoom", Button::Zoom, Button::factory, "none" }, - { "scrub", Button::Scrub, Button::factory, "none" }, - { "user_a", Button::UserA, Button::factory, "user" }, - { "user_b", Button::UserB, 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, "" } -}; - Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, uint32_t number, surface_type_t stype) : _mcp (mcp) , _stype (stype) @@ -138,12 +63,12 @@ Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, ui _port = new SurfacePort (*this); - if (_mcp.device_info().has_global_controls()) { - init_controls (); - } + /* only the first Surface object has global controls */ - if (_mcp.device_info().has_jog_wheel()) { - _jog_wheel = new Mackie::JogWheel (_mcp); + if (_number == 0) { + if (_mcp.device_info().has_global_controls()) { + init_controls (); + } } uint32_t n = _mcp.device_info().strip_cnt(); @@ -204,6 +129,16 @@ Surface::sysex_hdr() const return mackie_sysex_hdr; } +static GlobalControlDefinition mackie_global_controls[] = { + { "external", Pot::External, Pot::factory, "none" }, + { "fader_touch", Led::FaderTouch, Led::factory, "master" }, + { "timecode", Led::Timecode, Led::factory, "none" }, + { "beats", Led::Beats, Led::factory, "none" }, + { "solo", Led::RudeSolo, Led::factory, "none" }, + { "relay_click", Led::RelayClick, Led::factory, "none" }, + { "", 0, Led::factory, "" } +}; + void Surface::init_controls() { @@ -220,38 +155,39 @@ Surface::init_controls() groups["transport"] = new Group ("transport"); groups["user"] = new Group ("user"); groups["master"] = new Group ("master"); + + if (_mcp.device_info().has_jog_wheel()) { + _jog_wheel = new Mackie::JogWheel (_mcp); + } 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, mackie_global_controls[n].name, *group); - controls_by_name[mackie_global_controls[n].name] = control; - group->add (*control); - } -} - -static StripControlDefinition mackie_strip_controls[] = { - { "gain", 0, Fader::factory, }, - { "vpot", Pot::base_id, Pot::factory, }, - { "recenable", Button::recenable_base_id, Button::factory, }, - { "solo", Button::solo_base_id, Button::factory, }, - { "mute", Button::mute_base_id, Button::factory, }, - { "select", Button::select_base_id, Button::factory, }, - { "vselect", Button::vselect_base_id, Button::factory, }, - { "fader_touch", Button::fader_touch_base_id, Button::factory, }, - { "meter", 0, Meter::factory, }, - { "", 0, Button::factory, } -}; + controls_by_device_independent_id[mackie_global_controls[n].id] = control; + } + + /* add global buttons */ + + const map<Button::ID,GlobalButtonInfo>& global_buttons (_mcp.device_info().global_buttons()); + + for (map<Button::ID,GlobalButtonInfo>::const_iterator b = global_buttons.begin(); b != global_buttons.end(); ++b){ + group = groups[b->second.group]; + controls_by_device_independent_id[b->first] = Button::factory (*this, b->first, b->second.id, b->second.label, *group); + } +} void Surface::init_strips (uint32_t n) { + const map<Button::ID,StripButtonInfo>& strip_buttons (_mcp.device_info().strip_buttons()); + for (uint32_t i = 0; i < n; ++i) { char name[32]; snprintf (name, sizeof (name), "strip_%d", (8* _number) + i); - Strip* strip = new Strip (*this, name, i, mackie_strip_controls); + Strip* strip = new Strip (*this, name, i, strip_buttons); groups[name] = strip; strips.push_back (strip); @@ -280,7 +216,7 @@ Surface::display_bank_start (uint32_t current_bank) void Surface::blank_jog_ring () { - Control* control = controls_by_name["jog"]; + Control* control = controls_by_device_independent_id[Jog::ID]; if (control) { Pot* pot = dynamic_cast<Pot*> (control); @@ -395,10 +331,6 @@ Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev Pot* pot = pots[ev->controller_number]; - if (!pot && ev->controller_number == Jog::base_id) { - pot = dynamic_cast<Pot*> (controls_by_name["jog"]); - } - if (pot) { ControlState state; diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h index 6bdb575847..5bcd9ebde9 100644 --- a/libs/surfaces/mackie/surface.h +++ b/libs/surfaces/mackie/surface.h @@ -53,13 +53,10 @@ public: std::map<int,Fader*> faders; std::map<int,Pot*> pots; - std::map<int,Button*> buttons; + std::map<int,Button*> buttons; // index is device-DEPENDENT std::map<int,Led*> leds; std::map<int,Meter*> meters; - - /// no strip controls in here because they usually - /// have the same names. - std::map<std::string,Control*> controls_by_name; + std::map<int,Control*> controls_by_device_independent_id; Mackie::JogWheel* jog_wheel() const { return _jog_wheel; } diff --git a/libs/surfaces/mackie/wscript b/libs/surfaces/mackie/wscript index d21c9d9aef..ed573ab798 100644 --- a/libs/surfaces/mackie/wscript +++ b/libs/surfaces/mackie/wscript @@ -27,6 +27,7 @@ def build(bld): fader.cc gui.cc interface.cc + jog.cc led.cc mackie_control_protocol.cc mackie_jog_wheel.cc diff --git a/mcp_devices/nucleus.xml b/mcp_devices/nucleus.xml index 5d38ddfec9..d03ad558fc 100644 --- a/mcp_devices/nucleus.xml +++ b/mcp_devices/nucleus.xml @@ -2,12 +2,20 @@ <MackieProtocolDevice> <Name value="SSL Nucleus"/> <Strips value="8"/> + <Extenders value="1"/> <MasterFader value="no"/> <SegmentedDisplay value="yes"/> <TimecodeDisplay value="no"/> <TwoCharacterDisplay value="yes"/> - <Extenders value="1"/> <GlobalControls value="yes"/> - <JogWheel value="no"/> + <JogWheel value="yes"/> <TouchSenseFaders value="yes"/> + <SendsModifiers value="0x3"/> + <Quirks> + <ButtonOffNonZero/> + </Quirks> + <Buttons> + <GlobalButton name="Marker" id="0x48" label="instrument"/> + <StripButton name="FaderTouch" baseid="0x68"/> + </Buttons> </MackieProtocolDevice> |