diff options
author | David Robillard <d@drobilla.net> | 2013-01-16 08:24:31 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2013-01-16 08:24:31 +0000 |
commit | e092fe33afc5cfd566e156f0d565cb1d0c1194f2 (patch) | |
tree | 167ab7737a1d946adc8a1de722dd68b86b9c4d4d | |
parent | 65da5a7cc2c68475019b457f1ea3e60d5b37ceb4 (diff) |
Preliminary support for named MIDI controllers via midname files.
Add midnam file for Moog Minitaur controller names.
git-svn-id: svn://localhost/ardour2/branches/3.0@13852 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/midi_time_axis.cc | 35 | ||||
-rw-r--r-- | libs/midi++2/midi++/midnam_patch.h | 57 | ||||
-rw-r--r-- | libs/midi++2/midnam_patch.cc | 62 | ||||
-rw-r--r-- | patchfiles/Moog_Minitaur.midnam | 90 |
4 files changed, 239 insertions, 5 deletions
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 87d453c1d7..9db4a18ef4 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -626,6 +626,41 @@ MidiTimeAxisView::build_controller_menu () } } + using namespace MIDI::Name; + const string& 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); + } + + if (device_names && !device_names->controls().empty()) { + /* Controllers names available from the midnam file, generate a custom controller menu */ + 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()); + + 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 */ diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h index 63d12d322d..20e1b95714 100644 --- a/libs/midi++2/midi++/midnam_patch.h +++ b/libs/midi++2/midi++/midnam_patch.h @@ -255,6 +255,57 @@ private: Notes _notes; }; +class Control +{ +public: + Control() {} + Control(const std::string& type, + const std::string& number, + const std::string& name) + : _type(type) + , _number(number) + , _name(name) + {} + + const std::string& type() const { return _type; } + const std::string& number() const { return _number; } + const std::string& name() const { return _name; } + + void set_type(const std::string& type) { _type = type; } + void set_number(const std::string& number) { _number = number; } + void set_name(const std::string& name) { _name = name; } + + XMLNode& get_state(void); + int set_state(const XMLTree&, const XMLNode&); + +private: + std::string _type; + std::string _number; + std::string _name; +}; + +class ControlNameList +{ +public: + typedef std::list< boost::shared_ptr<Control> > Controls; + + ControlNameList() {} + ControlNameList(const std::string& name) : _name(name) {} + + const std::string& name() const { return _name; } + + void set_name(const std::string name) { _name = name; } + + const Controls& controls() const { return _controls; } + + XMLNode& get_state(void); + int set_state(const XMLTree&, const XMLNode&); + +private: + std::string _name; + Controls _controls; +}; + class CustomDeviceMode { public: @@ -291,6 +342,7 @@ public: /// maps name to ChannelNameSet typedef std::map<std::string, boost::shared_ptr<ChannelNameSet> > ChannelNameSets; typedef std::list<boost::shared_ptr<NoteNameList> > NoteNameLists; + typedef std::list<boost::shared_ptr<ControlNameList> > ControlNameLists; typedef std::map<std::string, PatchBank::PatchNameList> PatchNameLists; MasterDeviceNames() {}; @@ -301,7 +353,9 @@ public: const Models& models() const { return _models; } void set_models(const Models some_models) { _models = some_models; } - + + const ControlNameLists& controls() const { return _control_name_lists; } + const CustomDeviceModeNames& custom_device_mode_names() const { return _custom_device_mode_names; } boost::shared_ptr<CustomDeviceMode> custom_device_mode_by_name(std::string mode_name); @@ -319,6 +373,7 @@ private: ChannelNameSets _channel_name_sets; NoteNameLists _note_name_lists; PatchNameLists _patch_name_lists; + ControlNameLists _control_name_lists; }; class MIDINameDocument diff --git a/libs/midi++2/midnam_patch.cc b/libs/midi++2/midnam_patch.cc index f48ae7b6e2..1608b418b0 100644 --- a/libs/midi++2/midnam_patch.cc +++ b/libs/midi++2/midnam_patch.cc @@ -129,7 +129,6 @@ Patch::set_state (const XMLTree&, const XMLNode& node) _id.program_number = PBD::atoi(program_change); } - return 0; } @@ -143,7 +142,6 @@ Note::get_state (void) return *node; } - int Note::set_state (const XMLTree&, const XMLNode& node) { @@ -179,6 +177,52 @@ NoteNameList::set_state (const XMLTree& tree, const XMLNode& node) return 0; } +XMLNode& +Control::get_state (void) +{ + XMLNode* node = new XMLNode("Control"); + node->add_property("Type", _type); + node->add_property("Number", _number); + node->add_property("Name", _name); + + return *node; +} + +int +Control::set_state (const XMLTree&, const XMLNode& node) +{ + assert(node.name() == "Control"); + _type = node.property("Type")->value(); + _number = node.property("Number")->value(); + _name = node.property("Name")->value(); + + return 0; +} + +XMLNode& +ControlNameList::get_state (void) +{ + XMLNode* node = new XMLNode("ControlNameList"); + node->add_property("Name", _name); + + return *node; +} + +int +ControlNameList::set_state (const XMLTree& tree, const XMLNode& node) +{ + assert(node.name() == "ControlNameList"); + _name = node.property("Name")->value(); + + 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); + } + + return 0; +} XMLNode& PatchBank::get_state (void) @@ -427,7 +471,7 @@ MasterDeviceNames::find_patch(std::string mode, uint8_t channel, PatchPrimaryKey } int -MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode& a_node) +MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode&) { // Manufacturer boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer"); @@ -479,6 +523,16 @@ MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode& a_node) _note_name_lists.push_back(note_name_list); } + // ControlNameLists + boost::shared_ptr<XMLSharedNodeList> control_name_lists = tree.find("//ControlNameList"); + for (XMLSharedNodeList::iterator i = control_name_lists->begin(); + i != control_name_lists->end(); + ++i) { + boost::shared_ptr<ControlNameList> control_name_list(new ControlNameList()); + control_name_list->set_state (tree, *(*i)); + _control_name_lists.push_back(control_name_list); + } + // global/post-facto PatchNameLists boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList"); for (XMLSharedNodeList::iterator i = patch_name_lists->begin(); @@ -544,7 +598,7 @@ MIDINameDocument::MIDINameDocument (const string& filename) } int -MIDINameDocument::set_state (const XMLTree& tree, const XMLNode& a_node) +MIDINameDocument::set_state (const XMLTree& tree, const XMLNode&) { // Author diff --git a/patchfiles/Moog_Minitaur.midnam b/patchfiles/Moog_Minitaur.midnam new file mode 100644 index 0000000000..52ed35f33c --- /dev/null +++ b/patchfiles/Moog_Minitaur.midnam @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE MIDINameDocument PUBLIC "-//MIDI Manufacturers Association//DTD MIDINameDocument 0.7//EN" "http://www.sonosphere.com/dtds/MIDINameDocument.dtd"> + +<MIDINameDocument> + <Author>David Robillard</Author> + <MasterDeviceNames> + <Manufacturer>Moog</Manufacturer> + <Model>Minitaur</Model> + <ControlNameList Name="Modulation"> + <Control Type="7bit" Number="3" Name="LFO Rate (Coarse)" /> + <Control Type="7bit" Number="35" Name="LFO Rate (Fine)" /> + <Control Type="7bit" Number="13" Name="LFO VCO Amount (Coarse)" /> + <Control Type="7bit" Number="45" Name="LFO VCO Amount (Fine)" /> + <Control Type="7bit" Number="12" Name="LFO VCF Amount (Coarse)" /> + <Control Type="7bit" Number="44" Name="LFO VCF Amount (Fine)" /> + <Control Type="7bit" Number="87" Name="LFO MIDI Sync" /> + <Control Type="7bit" Number="86" Name="LFO Sync Clock Div" /> + <Control Type="7bit" Number="82" Name="LFO Key Trigger" /> + </ControlNameList> + <ControlNameList Name="Oscillators"> + <Control Type="7bit" Number="70" Name="VCO 1 Wave" /> + <Control Type="7bit" Number="71" Name="VCO 2 Wave" /> + <Control Type="7bit" Number="17" Name="VCO 2 Freq (Coarse)" /> + <Control Type="7bit" Number="49" Name="VCO 2 Freq (Fine)" /> + <Control Type="7bit" Number="18" Name="VCO 2 Beat (Coarse)" /> + <Control Type="7bit" Number="50" Name="VCO 2 Beat (Fine)" /> + <Control Type="7bit" Number="81" Name="Note Sync" /> + <Control Type="7bit" Number="5" Name="Glide Rate" /> + <Control Type="7bit" Number="65" Name="Glide Switch" /> + <Control Type="7bit" Number="92" Name="Glide Type" /> + <Control Type="7bit" Number="83" Name="Legato Glide" /> + </ControlNameList> + <ControlNameList Name="Mixer"> + <Control Type="7bit" Number="15" Name="VCO 1 (Coarse)" /> + <Control Type="7bit" Number="47" Name="VCO 1 (Fine)" /> + <Control Type="7bit" Number="16" Name="VCO 2 (Coarse)" /> + <Control Type="7bit" Number="48" Name="VCO 2 (Fine)" /> + <Control Type="7bit" Number="27" Name="External In (Coarse)" /> + <Control Type="7bit" Number="59" Name="External In (Fine)" /> + </ControlNameList> + <ControlNameList Name="Filter"> + <Control Type="7bit" Number="19" Name="Cutoff (Coarse)" /> + <Control Type="7bit" Number="51" Name="Cutoff (Fine)" /> + <Control Type="7bit" Number="19" Name="Resonance (Coarse)" /> + <Control Type="7bit" Number="51" Name="Resonance (Fine)" /> + <Control Type="7bit" Number="22" Name="EG Amount (Coarse)" /> + <Control Type="7bit" Number="50" Name="EG Amount (Fine)" /> + <Control Type="7bit" Number="20" Name="KB Track (Coarse)" /> + <Control Type="7bit" Number="54" Name="KB Track (Fine)" /> + <Control Type="7bit" Number="89" Name="Filter Velocity Sensitivity" /> + </ControlNameList> + <ControlNameList Name="Envelopes"> + <Control Type="7bit" Number="23" Name="VCF Attack (Coarse)" /> + <Control Type="7bit" Number="55" Name="VCF Attack (Fine)" /> + <Control Type="7bit" Number="24" Name="VCF Decay/Release (Coarse)" /> + <Control Type="7bit" Number="56" Name="VCF Decay/Release (Fine)" /> + <Control Type="7bit" Number="25" Name="VCF Sustain (Coarse)" /> + <Control Type="7bit" Number="57" Name="VCF Sustain (Fine)" /> + <Control Type="7bit" Number="28" Name="VCA Attack (Coarse)" /> + <Control Type="7bit" Number="60" Name="VCA Attack (Fine)" /> + <Control Type="7bit" Number="29" Name="VCA Decay/Release (Coarse)" /> + <Control Type="7bit" Number="61" Name="VCA Decay/Release (Fine)" /> + <Control Type="7bit" Number="30" Name="VCA Sustain (Coarse)" /> + <Control Type="7bit" Number="62" Name="VCA Sustain (Fine)" /> + <Control Type="7bit" Number="72" Name="Release Switch" /> + <Control Type="7bit" Number="73" Name="Trigger Mode" /> + </ControlNameList> + <ControlNameList Name="Volume"> + <Control Type="7bit" Number="7" Name="Volume (Coarse)" /> + <Control Type="7bit" Number="39" Name="Volume (Fine)" /> + <Control Type="7bit" Number="90" Name="Volume Velocity Sensitivity" /> + </ControlNameList> + <ControlNameList Name="Keyboard Response"> + <Control Type="7bit" Number="91" Name="Key Priority" /> + </ControlNameList> + <ControlNameList Name="Mod Wheel Response"> + <Control Type="7bit" Number="1" Name="Mod Wheel (Coarse)" /> + <Control Type="7bit" Number="33" Name="Mod Wheel (Fine)" /> + </ControlNameList> + <ControlNameList Name="Pitch Wheel Response"> + <Control Type="7bit" Number="107" Name="Bend Up Amount" /> + <Control Type="7bit" Number="108" Name="Bend Down Amount" /> + </ControlNameList> + <ControlNameList Name="Control"> + <Control Type="7bit" Number="122" Name="Local Control Off" /> + <Control Type="7bit" Number="122" Name="All Sounds Off" /> + <Control Type="7bit" Number="123" Name="All Notes Off" /> + </ControlNameList> + </MasterDeviceNames> +</MIDINameDocument> |