summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-01-19 10:02:00 +0000
committerDavid Robillard <d@drobilla.net>2013-01-19 10:02:00 +0000
commitb1bc353f0d770a28a0a4c2d91959cc0d2acc1216 (patch)
tree80a01791f7a50b5271e5274e912e1977fdf6b676
parent05a397b20c5896a232d202a3e05ff5a1882a924e (diff)
Add standard MIDI midnam file and remove hard coded equivalent.
Accordingly, make "generic" MIDI truly generic, just numbered controllers. Break up MIDI name UI stuff into manageable functions of reasonable size. Add convenient method to MIDINameDocument for getting the names for a device. Tolerate comments in MIDINameDocument ControlNameList. Can't remove the MIDI name code just yet, since it's still erroneously used by Automatable::describe_parameter(). This is the cause of a bug where the name on the automation lane does not match that in the menu. The plan is to make a very simple pure abstract interface for getting MIDI names, and make it possible to set one for Automatable (or perhaps pass it to describe_parameter()). Thus we'll be on the way to supporting names from sources other than midnam files, namely plugins. git-svn-id: svn://localhost/ardour2/branches/3.0@13895 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/midi_time_axis.cc294
-rw-r--r--gtk2_ardour/midi_time_axis.h3
-rw-r--r--libs/midi++2/midi++/midnam_patch.h2
-rw-r--r--libs/midi++2/midnam_patch.cc18
-rw-r--r--patchfiles/Standard_Midi.midnam282
5 files changed, 465 insertions, 134 deletions
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc
index 82faf1890c..a0bd56e04a 100644
--- a/gtk2_ardour/midi_time_axis.cc
+++ b/gtk2_ardour/midi_time_axis.cc
@@ -227,14 +227,8 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
}
_midnam_model_selector.set_active_text (gui_property (X_("midnam-model-name")));
- model_changed();
_midnam_custom_device_mode_selector.set_active_text (gui_property (X_("midnam-custom-device-mode")));
- _midnam_model_selector.signal_changed().connect(
- sigc::mem_fun(*this, &MidiTimeAxisView::model_changed));
- _midnam_custom_device_mode_selector.signal_changed().connect(
- sigc::mem_fun(*this, &MidiTimeAxisView::custom_device_mode_changed));
-
ARDOUR_UI::instance()->set_tip (_midnam_model_selector, _("External MIDI Device"));
ARDOUR_UI::instance()->set_tip (_midnam_custom_device_mode_selector, _("External Device Mode"));
@@ -258,6 +252,15 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
_midi_controls_box.attach(_channel_selector, 0, 1, 0, 1);
}
+ model_changed();
+ custom_device_mode_changed();
+
+ _midnam_model_selector.signal_changed().connect(
+ sigc::mem_fun(*this, &MidiTimeAxisView::model_changed));
+ _midnam_custom_device_mode_selector.signal_changed().connect(
+ sigc::mem_fun(*this, &MidiTimeAxisView::custom_device_mode_changed));
+
+
controls_vbox.pack_start(_midi_controls_box, false, false);
// restore channel selector settings
@@ -354,7 +357,7 @@ MidiTimeAxisView::model_changed()
const Glib::ustring model = _midnam_model_selector.get_active_text();
set_gui_property (X_("midnam-model-name"), model);
- std::list<std::string> device_modes = MIDI::Name::MidiPatchManager::instance()
+ const std::list<std::string> device_modes = MIDI::Name::MidiPatchManager::instance()
.custom_device_mode_names_by_model(model);
_midnam_custom_device_mode_selector.clear_items();
@@ -643,6 +646,105 @@ MidiTimeAxisView::add_channel_command_menu_item (Menu_Helpers::MenuList& items,
}
}
+/** Add a single menu item for a controller on one channel. */
+void
+MidiTimeAxisView::add_single_channel_controller_item(Menu_Helpers::MenuList& ctl_items,
+ int ctl,
+ const std::string& name)
+{
+ using namespace Menu_Helpers;
+
+ const uint16_t selected_channels = _channel_selector.get_selected_channels();
+ for (uint8_t chn = 0; chn < 16; chn++) {
+ if (selected_channels & (0x0001 << chn)) {
+
+ Evoral::Parameter fully_qualified_param (MidiCCAutomation, chn, ctl);
+ ctl_items.push_back (
+ CheckMenuElem (
+ string_compose ("<b>%1</b>: %2 [%3]", ctl, name, int (chn)),
+ sigc::bind (
+ sigc::mem_fun (*this, &RouteTimeAxisView::toggle_automation_track),
+ fully_qualified_param)));
+ dynamic_cast<Label*> (ctl_items.back().get_child())->set_use_markup (true);
+
+ boost::shared_ptr<AutomationTimeAxisView> track = automation_child (
+ fully_qualified_param);
+
+ bool visible = false;
+ if (track) {
+ if (track->marked_for_display()) {
+ visible = true;
+ }
+ }
+
+ CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&ctl_items.back());
+ _controller_menu_map[fully_qualified_param] = cmi;
+ cmi->set_active (visible);
+
+ /* one channel only */
+ break;
+ }
+ }
+}
+
+/** Add a submenu with 1 item per channel for a controller on many channels. */
+void
+MidiTimeAxisView::add_multi_channel_controller_item(Menu_Helpers::MenuList& ctl_items,
+ int ctl,
+ const std::string& name)
+{
+ using namespace Menu_Helpers;
+
+ const uint16_t selected_channels = _channel_selector.get_selected_channels();
+
+ Menu* chn_menu = manage (new Menu);
+ MenuList& chn_items (chn_menu->items());
+
+ /* add a couple of items to hide/show this controller on all channels */
+
+ Evoral::Parameter param_without_channel (MidiCCAutomation, 0, ctl);
+ chn_items.push_back (
+ MenuElem (_("Hide all channels"),
+ sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::change_all_channel_tracks_visibility),
+ false, param_without_channel)));
+ chn_items.push_back (
+ MenuElem (_("Show all channels"),
+ sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::change_all_channel_tracks_visibility),
+ true, param_without_channel)));
+
+ for (uint8_t chn = 0; chn < 16; chn++) {
+ if (selected_channels & (0x0001 << chn)) {
+
+ /* for each selected channel, add a menu item for this controller */
+
+ Evoral::Parameter fully_qualified_param (MidiCCAutomation, chn, ctl);
+ chn_items.push_back (
+ CheckMenuElem (string_compose (_("Channel %1"), chn+1),
+ sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::toggle_automation_track),
+ fully_qualified_param)));
+
+ boost::shared_ptr<AutomationTimeAxisView> track = automation_child (
+ fully_qualified_param);
+ bool visible = false;
+
+ if (track) {
+ if (track->marked_for_display()) {
+ visible = true;
+ }
+ }
+
+ CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&chn_items.back());
+ _controller_menu_map[fully_qualified_param] = cmi;
+ cmi->set_active (visible);
+ }
+ }
+
+ /* add the per-channel menu to the list of controllers, with the name of the controller */
+ ctl_items.push_back (MenuElem (string_compose ("<b>%1</b>: %2", ctl, name),
+ *chn_menu));
+ dynamic_cast<Label*> (ctl_items.back().get_child())->set_use_markup (true);
+}
+
void
MidiTimeAxisView::build_controller_menu ()
{
@@ -680,146 +782,76 @@ MidiTimeAxisView::build_controller_menu ()
const Glib::ustring model = _midnam_model_selector.get_active_text();
boost::shared_ptr<MIDINameDocument> midnam = MidiPatchManager::instance()
.document_by_model(model);
- boost::shared_ptr<MasterDeviceNames> device_names;
- if (midnam && !midnam->master_device_names_by_model().empty()) {
- device_names = boost::shared_ptr<MasterDeviceNames>(
- midnam->master_device_names_by_model().begin()->second);
- }
+ boost::shared_ptr<MasterDeviceNames> device_names = midnam->master_device_names(
+ model);
if (device_names && !device_names->controls().empty()) {
- /* Controllers names available from the midnam file,
- generate a custom controller menu */
+ /* Controllers names available in midnam file, generate fancy menu */
+ unsigned n_items = 0;
+ unsigned n_groups = 0;
for (MasterDeviceNames::ControlNameLists::const_iterator l = device_names->controls().begin();
l != device_names->controls().end(); ++l) {
boost::shared_ptr<ControlNameList> name_list = *l;
-
- int chn = 0; // TODO
- Menu* group_menu = manage(new Menu());
- MenuList& group_items(group_menu->items());
+ Menu* ctl_menu = NULL;
for (ControlNameList::Controls::const_iterator c = (*l)->controls().begin();
c != (*l)->controls().end(); ++c) {
- Evoral::Parameter fully_qualified_param(MidiCCAutomation, chn, atoi((*c)->number().c_str()));
- group_items.push_back(
- CheckMenuElem(string_compose("<b>%1</b>: %2 [%3]",
- (*c)->number(), (*c)->name(), int(chn)),
- sigc::bind(
- sigc::mem_fun(*this, &RouteTimeAxisView::toggle_automation_track),
- fully_qualified_param)));
- dynamic_cast<Label*> (group_items.back().get_child())->set_use_markup (true);
- }
- items.push_back(MenuElem(name_list->name(), *group_menu));
- }
- return;
- }
-
- /* loop over all 127 MIDI controllers, in groups of 16; except don't offer
- bank select controllers, as they are handled by the `patch' code */
-
- for (int i = 0; i < 127; i += 16) {
-
- Menu* ctl_menu = manage (new Menu);
- MenuList& ctl_items (ctl_menu->items());
-
- /* for each controller, consider whether to create a submenu or a single item */
-
- for (int ctl = i; ctl < i+16; ++ctl) {
-
- if (ctl == MIDI_CTL_MSB_BANK || ctl == MIDI_CTL_LSB_BANK) {
- continue;
- }
-
- if (chn_cnt > 1) {
-
- /* multiple channels - create a submenu, with 1 item per channel */
-
- Menu* chn_menu = manage (new Menu);
- MenuList& chn_items (chn_menu->items());
-
- /* add a couple of items to hide/show this controller on all channels */
-
- Evoral::Parameter param_without_channel (MidiCCAutomation, 0, ctl);
- chn_items.push_back (
- MenuElem (_("Hide all channels"),
- sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::change_all_channel_tracks_visibility),
- false, param_without_channel)));
- chn_items.push_back (
- MenuElem (_("Show all channels"),
- sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::change_all_channel_tracks_visibility),
- true, param_without_channel)));
-
- for (uint8_t chn = 0; chn < 16; chn++) {
- if (selected_channels & (0x0001 << chn)) {
-
- /* for each selected channel, add a menu item for this controller */
-
- Evoral::Parameter fully_qualified_param (MidiCCAutomation, chn, ctl);
- chn_items.push_back (
- CheckMenuElem (string_compose (_("Channel %1"), chn+1),
- sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::toggle_automation_track),
- fully_qualified_param)));
-
- boost::shared_ptr<AutomationTimeAxisView> track = automation_child (
- fully_qualified_param);
- bool visible = false;
-
- if (track) {
- if (track->marked_for_display()) {
- visible = true;
- }
- }
-
- CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&chn_items.back());
- _controller_menu_map[fully_qualified_param] = cmi;
- cmi->set_active (visible);
- }
+ const int ctl = atoi((*c)->number().c_str());
+ if (ctl == MIDI_CTL_MSB_BANK || ctl == MIDI_CTL_LSB_BANK) {
+ /* Skip bank select controllers since they're handled specially */
+ continue;
}
- /* add the per-channel menu to the list of controllers, with the name of the controller */
- ctl_items.push_back (MenuElem (string_compose ("<b>%1</b>: %2", ctl, midi_name (ctl)),
- *chn_menu));
- dynamic_cast<Label*> (ctl_items.back().get_child())->set_use_markup (true);
-
- } else {
-
- /* just one channel - create a single menu item for this ctl+channel combination */
-
- for (uint8_t chn = 0; chn < 16; chn++) {
- if (selected_channels & (0x0001 << chn)) {
-
- Evoral::Parameter fully_qualified_param (MidiCCAutomation, chn, ctl);
- ctl_items.push_back (
- CheckMenuElem (
- string_compose ("<b>%1</b>: %2 [%3]", ctl, midi_name (ctl), int (chn)),
- sigc::bind (
- sigc::mem_fun (*this, &RouteTimeAxisView::toggle_automation_track),
- fully_qualified_param)));
- dynamic_cast<Label*> (ctl_items.back().get_child())->set_use_markup (true);
-
- boost::shared_ptr<AutomationTimeAxisView> track = automation_child (
- fully_qualified_param);
-
- bool visible = false;
- if (track) {
- if (track->marked_for_display()) {
- visible = true;
- }
- }
-
- CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&ctl_items.back());
- _controller_menu_map[fully_qualified_param] = cmi;
- cmi->set_active (visible);
+ if (n_items == 0) {
+ /* Create a new submenu */
+ ctl_menu = manage (new Menu);
+ }
- /* one channel only */
- break;
- }
+ MenuList& ctl_items (ctl_menu->items());
+ if (chn_cnt > 1) {
+ add_multi_channel_controller_item(ctl_items, ctl, (*c)->name());
+ } else {
+ add_single_channel_controller_item(ctl_items, ctl, (*c)->name());
+ }
+
+ if (++n_items == 16 || c == (*l)->controls().end()) {
+ /* Submenu has 16 items, add it to controller menu and reset */
+ items.push_back(
+ MenuElem(string_compose(_("Controllers %1-%2"),
+ (16 * n_groups), (16 * n_groups) + n_items - 1),
+ *ctl_menu));
+ ctl_menu = NULL;
+ n_items = 0;
+ ++n_groups;
}
}
}
+ } else {
+ /* No controllers names, generate generic numeric menu */
+ for (int i = 0; i < 127; i += 16) {
+ Menu* ctl_menu = manage (new Menu);
+ MenuList& ctl_items (ctl_menu->items());
+
+ for (int ctl = i; ctl < i+16; ++ctl) {
+ if (ctl == MIDI_CTL_MSB_BANK || ctl == MIDI_CTL_LSB_BANK) {
+ /* Skip bank select controllers since they're handled specially */
+ continue;
+ }
- /* add the menu for this block of controllers to the overall controller menu */
+ if (chn_cnt > 1) {
+ add_multi_channel_controller_item(
+ ctl_items, ctl, string_compose(_("Controller %1"), ctl));
+ } else {
+ add_single_channel_controller_item(
+ ctl_items, ctl, string_compose(_("Controller %1"), ctl));
+ }
+ }
- items.push_back (MenuElem (string_compose (_("Controllers %1-%2"), i, i+15), *ctl_menu));
+ /* Add submenu for this block of controllers to controller menu */
+ items.push_back (
+ MenuElem (string_compose (_("Controllers %1-%2"), i, i + 15),
+ *ctl_menu));
+ }
}
}
diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h
index 10ad5f8f10..04e37913b5 100644
--- a/gtk2_ardour/midi_time_axis.h
+++ b/gtk2_ardour/midi_time_axis.h
@@ -143,6 +143,9 @@ class MidiTimeAxisView : public RouteTimeAxisView
void add_channel_command_menu_item (Gtk::Menu_Helpers::MenuList& items, const std::string& label, ARDOUR::AutomationType auto_type, uint8_t cmd);
Gtk::Menu* controller_menu;
+
+ void add_single_channel_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, int ctl, const std::string& name);
+ void add_multi_channel_controller_item (Gtk::Menu_Helpers::MenuList& ctl_items, int ctl, const std::string& name);
void build_controller_menu ();
void set_channel_mode (ARDOUR::ChannelMode, uint16_t);
diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h
index bae5241f98..a759e503dd 100644
--- a/libs/midi++2/midi++/midnam_patch.h
+++ b/libs/midi++2/midi++/midnam_patch.h
@@ -387,6 +387,8 @@ public:
const std::string& author() const { return _author; }
void set_author(const std::string an_author) { _author = an_author; }
+ boost::shared_ptr<MasterDeviceNames> master_device_names(const std::string& model);
+
const MasterDeviceNamesList& master_device_names_by_model() const { return _master_device_names_list; }
const MasterDeviceNames::Models& all_models() const { return _all_models; }
diff --git a/libs/midi++2/midnam_patch.cc b/libs/midi++2/midnam_patch.cc
index 1608b418b0..3509d1e021 100644
--- a/libs/midi++2/midnam_patch.cc
+++ b/libs/midi++2/midnam_patch.cc
@@ -216,9 +216,11 @@ ControlNameList::set_state (const XMLTree& tree, const XMLNode& node)
for (XMLNodeList::const_iterator i = node.children().begin();
i != node.children().end(); ++i) {
- boost::shared_ptr<Control> control(new Control());
- control->set_state (tree, *(*i));
- _controls.push_back(control);
+ if ((*i)->name() != "comment") {
+ boost::shared_ptr<Control> control(new Control());
+ control->set_state (tree, *(*i));
+ _controls.push_back(control);
+ }
}
return 0;
@@ -646,6 +648,16 @@ MIDINameDocument::get_state(void)
return nothing;
}
+boost::shared_ptr<MasterDeviceNames>
+MIDINameDocument::master_device_names(const std::string& model)
+{
+ MasterDeviceNamesList::const_iterator m = _master_device_names_list.find(model);
+ if (m != _master_device_names_list.end()) {
+ return boost::shared_ptr<MasterDeviceNames>(m->second);
+ }
+ return boost::shared_ptr<MasterDeviceNames>();
+}
+
const char* general_midi_program_names[128] = {
"Acoustic Grand Piano",
"Bright Acoustic Piano",
diff --git a/patchfiles/Standard_Midi.midnam b/patchfiles/Standard_Midi.midnam
new file mode 100644
index 0000000000..cb3b948eeb
--- /dev/null
+++ b/patchfiles/Standard_Midi.midnam
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE MIDINameDocument PUBLIC "-//MIDI Manufacturers Association//DTD MIDINameDocument 1.0//EN" "http://www.midi.org/dtds/MIDINameDocument10.dtd">
+<MIDINameDocument>
+ <Author>David Robillard</Author>
+ <MasterDeviceNames>
+ <Manufacturer>MMA</Manufacturer>
+ <Model>Standard MIDI</Model>
+ <CustomDeviceMode Name="Mode">
+ <ChannelNameSetAssignments>
+ <ChannelNameSetAssign Channel="1" NameSet="Names"/>
+ </ChannelNameSetAssignments>
+ </CustomDeviceMode>
+ <ChannelNameSet Name="Names">
+ <AvailableForChannels>
+ <AvailableChannel Channel="1" Available="true"/>
+ </AvailableForChannels>
+ <UsesControlNameList Name="Control Names"/>
+ <PatchBank Name="Patches">
+ <PatchNameList>
+ <Patch Number="1" Name="Patch 1" ProgramChange="0"/>
+ <Patch Number="2" Name="Patch 2" ProgramChange="1"/>
+ <Patch Number="3" Name="Patch 3" ProgramChange="2"/>
+ <Patch Number="4" Name="Patch 4" ProgramChange="3"/>
+ <Patch Number="5" Name="Patch 5" ProgramChange="4"/>
+ <Patch Number="6" Name="Patch 6" ProgramChange="5"/>
+ <Patch Number="7" Name="Patch 7" ProgramChange="6"/>
+ <Patch Number="8" Name="Patch 8" ProgramChange="7"/>
+ <Patch Number="9" Name="Patch 9" ProgramChange="8"/>
+ <Patch Number="10" Name="Patch 10" ProgramChange="9"/>
+ <Patch Number="11" Name="Patch 11" ProgramChange="10"/>
+ <Patch Number="12" Name="Patch 12" ProgramChange="11"/>
+ <Patch Number="13" Name="Patch 13" ProgramChange="12"/>
+ <Patch Number="14" Name="Patch 14" ProgramChange="13"/>
+ <Patch Number="15" Name="Patch 15" ProgramChange="14"/>
+ <Patch Number="16" Name="Patch 16" ProgramChange="15"/>
+ <Patch Number="17" Name="Patch 17" ProgramChange="16"/>
+ <Patch Number="18" Name="Patch 18" ProgramChange="17"/>
+ <Patch Number="19" Name="Patch 19" ProgramChange="18"/>
+ <Patch Number="20" Name="Patch 20" ProgramChange="19"/>
+ <Patch Number="21" Name="Patch 21" ProgramChange="20"/>
+ <Patch Number="22" Name="Patch 22" ProgramChange="21"/>
+ <Patch Number="23" Name="Patch 23" ProgramChange="22"/>
+ <Patch Number="24" Name="Patch 24" ProgramChange="23"/>
+ <Patch Number="25" Name="Patch 25" ProgramChange="24"/>
+ <Patch Number="26" Name="Patch 26" ProgramChange="25"/>
+ <Patch Number="27" Name="Patch 27" ProgramChange="26"/>
+ <Patch Number="28" Name="Patch 28" ProgramChange="27"/>
+ <Patch Number="29" Name="Patch 29" ProgramChange="28"/>
+ <Patch Number="30" Name="Patch 30" ProgramChange="29"/>
+ <Patch Number="31" Name="Patch 31" ProgramChange="30"/>
+ <Patch Number="32" Name="Patch 32" ProgramChange="31"/>
+ <Patch Number="33" Name="Patch 33" ProgramChange="32"/>
+ <Patch Number="34" Name="Patch 34" ProgramChange="33"/>
+ <Patch Number="35" Name="Patch 35" ProgramChange="34"/>
+ <Patch Number="36" Name="Patch 36" ProgramChange="35"/>
+ <Patch Number="37" Name="Patch 37" ProgramChange="36"/>
+ <Patch Number="38" Name="Patch 38" ProgramChange="37"/>
+ <Patch Number="39" Name="Patch 39" ProgramChange="38"/>
+ <Patch Number="40" Name="Patch 40" ProgramChange="39"/>
+ <Patch Number="41" Name="Patch 41" ProgramChange="40"/>
+ <Patch Number="42" Name="Patch 42" ProgramChange="41"/>
+ <Patch Number="43" Name="Patch 43" ProgramChange="42"/>
+ <Patch Number="44" Name="Patch 44" ProgramChange="43"/>
+ <Patch Number="45" Name="Patch 45" ProgramChange="44"/>
+ <Patch Number="46" Name="Patch 46" ProgramChange="45"/>
+ <Patch Number="47" Name="Patch 47" ProgramChange="46"/>
+ <Patch Number="48" Name="Patch 48" ProgramChange="47"/>
+ <Patch Number="49" Name="Patch 49" ProgramChange="48"/>
+ <Patch Number="50" Name="Patch 50" ProgramChange="49"/>
+ <Patch Number="51" Name="Patch 51" ProgramChange="50"/>
+ <Patch Number="52" Name="Patch 52" ProgramChange="51"/>
+ <Patch Number="53" Name="Patch 53" ProgramChange="52"/>
+ <Patch Number="54" Name="Patch 54" ProgramChange="53"/>
+ <Patch Number="55" Name="Patch 55" ProgramChange="54"/>
+ <Patch Number="56" Name="Patch 56" ProgramChange="55"/>
+ <Patch Number="57" Name="Patch 57" ProgramChange="56"/>
+ <Patch Number="58" Name="Patch 58" ProgramChange="57"/>
+ <Patch Number="59" Name="Patch 59" ProgramChange="58"/>
+ <Patch Number="60" Name="Patch 60" ProgramChange="59"/>
+ <Patch Number="61" Name="Patch 61" ProgramChange="60"/>
+ <Patch Number="62" Name="Patch 62" ProgramChange="61"/>
+ <Patch Number="63" Name="Patch 63" ProgramChange="62"/>
+ <Patch Number="64" Name="Patch 64" ProgramChange="63"/>
+ <Patch Number="65" Name="Patch 65" ProgramChange="64"/>
+ <Patch Number="66" Name="Patch 66" ProgramChange="65"/>
+ <Patch Number="67" Name="Patch 67" ProgramChange="66"/>
+ <Patch Number="68" Name="Patch 68" ProgramChange="67"/>
+ <Patch Number="69" Name="Patch 69" ProgramChange="68"/>
+ <Patch Number="70" Name="Patch 70" ProgramChange="69"/>
+ <Patch Number="71" Name="Patch 71" ProgramChange="70"/>
+ <Patch Number="72" Name="Patch 72" ProgramChange="71"/>
+ <Patch Number="73" Name="Patch 73" ProgramChange="72"/>
+ <Patch Number="74" Name="Patch 74" ProgramChange="73"/>
+ <Patch Number="75" Name="Patch 75" ProgramChange="74"/>
+ <Patch Number="76" Name="Patch 76" ProgramChange="75"/>
+ <Patch Number="77" Name="Patch 77" ProgramChange="76"/>
+ <Patch Number="78" Name="Patch 78" ProgramChange="77"/>
+ <Patch Number="79" Name="Patch 79" ProgramChange="78"/>
+ <Patch Number="80" Name="Patch 80" ProgramChange="79"/>
+ <Patch Number="81" Name="Patch 81" ProgramChange="80"/>
+ <Patch Number="82" Name="Patch 82" ProgramChange="81"/>
+ <Patch Number="83" Name="Patch 83" ProgramChange="82"/>
+ <Patch Number="84" Name="Patch 84" ProgramChange="83"/>
+ <Patch Number="85" Name="Patch 85" ProgramChange="84"/>
+ <Patch Number="86" Name="Patch 86" ProgramChange="85"/>
+ <Patch Number="87" Name="Patch 87" ProgramChange="86"/>
+ <Patch Number="88" Name="Patch 88" ProgramChange="87"/>
+ <Patch Number="89" Name="Patch 89" ProgramChange="88"/>
+ <Patch Number="90" Name="Patch 90" ProgramChange="89"/>
+ <Patch Number="91" Name="Patch 91" ProgramChange="90"/>
+ <Patch Number="92" Name="Patch 92" ProgramChange="91"/>
+ <Patch Number="93" Name="Patch 93" ProgramChange="92"/>
+ <Patch Number="94" Name="Patch 94" ProgramChange="93"/>
+ <Patch Number="95" Name="Patch 95" ProgramChange="94"/>
+ <Patch Number="96" Name="Patch 96" ProgramChange="95"/>
+ <Patch Number="97" Name="Patch 97" ProgramChange="96"/>
+ <Patch Number="98" Name="Patch 98" ProgramChange="97"/>
+ <Patch Number="99" Name="Patch 99" ProgramChange="98"/>
+ <Patch Number="100" Name="Patch 100" ProgramChange="99"/>
+ <Patch Number="101" Name="Patch 101" ProgramChange="100"/>
+ <Patch Number="102" Name="Patch 102" ProgramChange="101"/>
+ <Patch Number="103" Name="Patch 103" ProgramChange="102"/>
+ <Patch Number="104" Name="Patch 104" ProgramChange="103"/>
+ <Patch Number="105" Name="Patch 105" ProgramChange="104"/>
+ <Patch Number="106" Name="Patch 106" ProgramChange="105"/>
+ <Patch Number="107" Name="Patch 107" ProgramChange="106"/>
+ <Patch Number="108" Name="Patch 108" ProgramChange="107"/>
+ <Patch Number="109" Name="Patch 109" ProgramChange="108"/>
+ <Patch Number="110" Name="Patch 110" ProgramChange="109"/>
+ <Patch Number="111" Name="Patch 111" ProgramChange="110"/>
+ <Patch Number="112" Name="Patch 112" ProgramChange="111"/>
+ <Patch Number="113" Name="Patch 113" ProgramChange="112"/>
+ <Patch Number="114" Name="Patch 114" ProgramChange="113"/>
+ <Patch Number="115" Name="Patch 115" ProgramChange="114"/>
+ <Patch Number="116" Name="Patch 116" ProgramChange="115"/>
+ <Patch Number="117" Name="Patch 117" ProgramChange="116"/>
+ <Patch Number="118" Name="Patch 118" ProgramChange="117"/>
+ <Patch Number="119" Name="Patch 119" ProgramChange="118"/>
+ <Patch Number="120" Name="Patch 120" ProgramChange="119"/>
+ <Patch Number="121" Name="Patch 121" ProgramChange="120"/>
+ <Patch Number="122" Name="Patch 122" ProgramChange="121"/>
+ <Patch Number="123" Name="Patch 123" ProgramChange="122"/>
+ <Patch Number="124" Name="Patch 124" ProgramChange="123"/>
+ <Patch Number="125" Name="Patch 125" ProgramChange="124"/>
+ <Patch Number="126" Name="Patch 126" ProgramChange="125"/>
+ <Patch Number="127" Name="Patch 127" ProgramChange="126"/>
+ <Patch Number="128" Name="Patch 128" ProgramChange="127"/>
+ </PatchNameList>
+ </PatchBank>
+ </ChannelNameSet>
+ <ControlNameList Name="Controls">
+ <Control Type="7bit" Number="0" Name="Bank Select"/>
+ <Control Type="7bit" Number="1" Name="Modulation Wheel or Lever"/>
+ <Control Type="7bit" Number="2" Name="Breath Controller"/>
+ <Control Type="7bit" Number="3" Name="Undefined"/>
+ <Control Type="7bit" Number="4" Name="Foot Controller"/>
+ <Control Type="7bit" Number="5" Name="Portamento Time"/>
+ <Control Type="7bit" Number="6" Name="Data Entry MSB"/>
+ <Control Type="7bit" Number="7" Name="Channel Volume"/>
+ <Control Type="7bit" Number="8" Name="Balance"/>
+ <Control Type="7bit" Number="9" Name="Undefined"/>
+ <Control Type="7bit" Number="10" Name="Pan"/>
+ <Control Type="7bit" Number="11" Name="Expression Controller"/>
+ <Control Type="7bit" Number="12" Name="Effect Control 1"/>
+ <Control Type="7bit" Number="13" Name="Effect Control 2"/>
+ <Control Type="7bit" Number="14" Name="Undefined"/>
+ <Control Type="7bit" Number="15" Name="Undefined"/>
+ <Control Type="7bit" Number="16" Name="General Purpose Controller 1"/>
+ <Control Type="7bit" Number="17" Name="General Purpose Controller 2"/>
+ <Control Type="7bit" Number="18" Name="General Purpose Controller 3"/>
+ <Control Type="7bit" Number="19" Name="General Purpose Controller 4"/>
+ <Control Type="7bit" Number="20" Name="Undefined"/>
+ <Control Type="7bit" Number="21" Name="Undefined"/>
+ <Control Type="7bit" Number="22" Name="Undefined"/>
+ <Control Type="7bit" Number="23" Name="Undefined"/>
+ <Control Type="7bit" Number="24" Name="Undefined"/>
+ <Control Type="7bit" Number="25" Name="Undefined"/>
+ <Control Type="7bit" Number="26" Name="Undefined"/>
+ <Control Type="7bit" Number="27" Name="Undefined"/>
+ <Control Type="7bit" Number="28" Name="Undefined"/>
+ <Control Type="7bit" Number="29" Name="Undefined"/>
+ <Control Type="7bit" Number="30" Name="Undefined"/>
+ <Control Type="7bit" Number="31" Name="Undefined"/>
+ <Control Type="7bit" Number="32" Name="LSB for Control 0 (Bank Select) (Fine)"/>
+ <Control Type="7bit" Number="33" Name="LSB for Control 1 (Modulation Wheel or Lever) (Fine)"/>
+ <Control Type="7bit" Number="34" Name="LSB for Control 2 (Breath Controller) (Fine)"/>
+ <Control Type="7bit" Number="35" Name="LSB for Control 3 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="36" Name="LSB for Control 4 (Foot Controller) (Fine)"/>
+ <Control Type="7bit" Number="37" Name="LSB for Control 5 (Portamento Time) (Fine)"/>
+ <Control Type="7bit" Number="38" Name="LSB for Control 6 (Data Entry) (Fine)"/>
+ <Control Type="7bit" Number="39" Name="LSB for Control 7 (Channel Volume) (Fine)"/>
+ <Control Type="7bit" Number="40" Name="LSB for Control 8 (Balance) (Fine)"/>
+ <Control Type="7bit" Number="41" Name="LSB for Control 9 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="42" Name="LSB for Control 10 (Pan) (Fine)"/>
+ <Control Type="7bit" Number="43" Name="LSB for Control 11 (Expression Controller) (Fine)"/>
+ <Control Type="7bit" Number="44" Name="LSB for Control 12 (Effect control 1) (Fine)"/>
+ <Control Type="7bit" Number="45" Name="LSB for Control 13 (Effect control 2) (Fine)"/>
+ <Control Type="7bit" Number="46" Name="LSB for Control 14 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="47" Name="LSB for Control 15 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="48" Name="LSB for Control 16 (General Purpose Controller 1) (Fine)"/>
+ <Control Type="7bit" Number="49" Name="LSB for Control 17 (General Purpose Controller 2) (Fine)"/>
+ <Control Type="7bit" Number="50" Name="LSB for Control 18 (General Purpose Controller 3) (Fine)"/>
+ <Control Type="7bit" Number="51" Name="LSB for Control 19 (General Purpose Controller 4) (Fine)"/>
+ <Control Type="7bit" Number="52" Name="LSB for Control 20 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="53" Name="LSB for Control 21 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="54" Name="LSB for Control 22 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="55" Name="LSB for Control 23 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="56" Name="LSB for Control 24 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="57" Name="LSB for Control 25 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="58" Name="LSB for Control 26 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="59" Name="LSB for Control 27 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="60" Name="LSB for Control 28 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="61" Name="LSB for Control 29 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="62" Name="LSB for Control 30 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="63" Name="LSB for Control 31 (Undefined) (Fine)"/>
+ <Control Type="7bit" Number="64" Name="Damper Pedal on/off (Sustain) ≤63 off, ≥64 on"/>
+ <Control Type="7bit" Number="65" Name="Portamento On/Off ≤63 off, ≥64 on"/>
+ <Control Type="7bit" Number="66" Name="Sostenuto On/Off ≤63 off, ≥64 on"/>
+ <Control Type="7bit" Number="67" Name="Soft Pedal On/Off ≤63 off, ≥64 on"/>
+ <Control Type="7bit" Number="68" Name="Legato Footswitch ≤63 Normal, ≥64 Legato"/>
+ <Control Type="7bit" Number="69" Name="Hold 2 ≤63 off, ≥64 on"/>
+ <Control Type="7bit" Number="70" Name="Sound Controller 1 (default: Sound Variation) (Fine)"/>
+ <Control Type="7bit" Number="71" Name="Sound Controller 2 (default: Timbre/Harmonic Intens.) (Fine)"/>
+ <Control Type="7bit" Number="72" Name="Sound Controller 3 (default: Release Time) (Fine)"/>
+ <Control Type="7bit" Number="73" Name="Sound Controller 4 (default: Attack Time) (Fine)"/>
+ <Control Type="7bit" Number="74" Name="Sound Controller 5 (default: Brightness) (Fine)"/>
+ <Control Type="7bit" Number="75" Name="Sound Controller 6 (default: Decay Time) (Fine)"/>
+ <Control Type="7bit" Number="76" Name="Sound Controller 7 (default: Vibrato Rate) (Fine)"/>
+ <Control Type="7bit" Number="77" Name="Sound Controller 8 (default: Vibrato Depth) (Fine)"/>
+ <Control Type="7bit" Number="78" Name="Sound Controller 9 (default: Vibrato Delay) (Fine)"/>
+ <Control Type="7bit" Number="79" Name="Sound Controller 10 (default undefined) (Fine)"/>
+ <Control Type="7bit" Number="80" Name="General Purpose Controller 5 (Fine)"/>
+ <Control Type="7bit" Number="81" Name="General Purpose Controller 6 (Fine)"/>
+ <Control Type="7bit" Number="82" Name="General Purpose Controller 7 (Fine)"/>
+ <Control Type="7bit" Number="83" Name="General Purpose Controller 8 (Fine)"/>
+ <Control Type="7bit" Number="84" Name="Portamento Control (Fine)"/>
+ <Control Type="7bit" Number="85" Name="(Undefined)"/>
+ <Control Type="7bit" Number="86" Name="(Undefined)"/>
+ <Control Type="7bit" Number="87" Name="(Undefined)"/>
+ <Control Type="7bit" Number="88" Name="High Resolution Velocity Prefix (Velocity LSB)"/>
+ <Control Type="7bit" Number="89" Name="(Undefined)"/>
+ <Control Type="7bit" Number="90" Name="(Undefined)"/>
+ <Control Type="7bit" Number="91" Name="Effects 1 Depth (default: Reverb Send Level)"/>
+ <Control Type="7bit" Number="92" Name="Effects 2 Depth"/>
+ <Control Type="7bit" Number="93" Name="Effects 3 Depth (default: Chorus Send Level)"/>
+ <Control Type="7bit" Number="94" Name="Effects 4 Depth"/>
+ <Control Type="7bit" Number="95" Name="Effects 5 Depth"/>
+ <Control Type="7bit" Number="96" Name="Data Increment (Data Entry +1)"/>
+ <Control Type="7bit" Number="97" Name="Data Decrement (Data Entry -1)"/>
+ <Control Type="7bit" Number="98" Name="Non-Registered Parameter Number LSB"/>
+ <Control Type="7bit" Number="99" Name="Non-Registered Parameter Number MSB"/>
+ <Control Type="7bit" Number="100" Name="Registered Parameter Number LSB"/>
+ <Control Type="7bit" Number="101" Name="Registered Parameter Number MSB"/>
+ <Control Type="7bit" Number="102" Name="(Undefined)"/>
+ <Control Type="7bit" Number="103" Name="(Undefined)"/>
+ <Control Type="7bit" Number="104" Name="(Undefined)"/>
+ <Control Type="7bit" Number="105" Name="(Undefined)"/>
+ <Control Type="7bit" Number="106" Name="(Undefined)"/>
+ <Control Type="7bit" Number="107" Name="(Undefined)"/>
+ <Control Type="7bit" Number="108" Name="(Undefined)"/>
+ <Control Type="7bit" Number="109" Name="(Undefined)"/>
+ <Control Type="7bit" Number="110" Name="(Undefined)"/>
+ <Control Type="7bit" Number="111" Name="(Undefined)"/>
+ <Control Type="7bit" Number="112" Name="(Undefined)"/>
+ <Control Type="7bit" Number="113" Name="(Undefined)"/>
+ <Control Type="7bit" Number="114" Name="(Undefined)"/>
+ <Control Type="7bit" Number="115" Name="(Undefined)"/>
+ <Control Type="7bit" Number="116" Name="(Undefined)"/>
+ <Control Type="7bit" Number="117" Name="(Undefined)"/>
+ <Control Type="7bit" Number="118" Name="(Undefined)"/>
+ <Control Type="7bit" Number="119" Name="(Undefined)"/>
+ <Control Type="7bit" Number="120" Name="[Channel Mode Message] All Sound Off"/>
+ <Control Type="7bit" Number="121" Name="[Channel Mode Message] Reset All Controllers"/>
+ <Control Type="7bit" Number="122" Name="[Channel Mode Message] Local Control On/Off 0 off, 127 on"/>
+ <Control Type="7bit" Number="123" Name="[Channel Mode Message] All Notes Off"/>
+ <Control Type="7bit" Number="124" Name="[Channel Mode Message] Omni Mode Off (+ all notes off)"/>
+ <Control Type="7bit" Number="125" Name="[Channel Mode Message] Omni Mode On (+ all notes off)"/>
+ <Control Type="7bit" Number="126" Name="[Channel Mode Message] Mono Mode On (+ poly off, + all notes off)"/>
+ <Control Type="7bit" Number="127" Name="[Channel Mode Message] Poly Mode On (+ mono off, +all notes off) 0"/>
+ </ControlNameList>
+ </MasterDeviceNames>
+</MIDINameDocument>