2 Copyright (C) 2008 Hans Baier
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "midi++/midnam_patch.h"
25 #include "pbd/compose.h"
26 #include "pbd/convert.h"
27 #include "pbd/error.h"
28 #include "pbd/failed_constructor.h"
39 Patch::Patch (std::string name, uint8_t p_number, uint16_t b_number)
41 , _id (p_number, b_number)
46 string_to_int(const XMLTree& tree, const std::string& str)
49 const int i = strtol(str.c_str(), &endptr, 10);
50 if (str.empty() || *endptr != '\0') {
51 PBD::error << string_compose("%1: Bad number `%2'", tree.filename(), str)
58 initialize_primary_key_from_commands (
59 const XMLTree& tree, PatchPrimaryKey& id, const XMLNode* node)
64 const XMLNodeList events = node->children();
65 for (XMLNodeList::const_iterator i = events.begin(); i != events.end(); ++i) {
68 if (node->name() == "ControlChange") {
69 const string& control = node->property("Control")->value();
70 const string& value = node->property("Value")->value();
73 bank |= string_to_int(tree, value) << 7;
74 } else if (control == "32") {
75 bank |= string_to_int(tree, value);
78 } else if (node->name() == "ProgramChange") {
79 const string& number = node->property("Number")->value();
81 program = string_to_int(tree, number);
85 id = PatchPrimaryKey(program, bank);
90 Patch::get_state (void)
92 XMLNode* node = new XMLNode("Patch");
94 /* XXX this is totally wrong */
96 node->set_property("Number", _id.program());
97 node->set_property("Name", _name);
100 typedef std::list< boost::shared_ptr< Evoral::Event<Temporal::Beats> > > PatchMidiCommands;
101 XMLNode* commands = node->add_child("PatchMIDICommands");
102 for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
103 event != _patch_midi_commands.end();
105 commands->add_child_copy(Evoral::MIDIXML::midi_to_xml(*event));
113 Patch::set_state (const XMLTree& tree, const XMLNode& node)
115 if (node.name() != "Patch") {
116 cerr << "Incorrect node type '" << node.name() << "' handed to Patch" << endl;
120 /* Note there is a "Number" attribute, but it's really more like a label
121 and is often not numeric. We currently do not use it. */
123 const XMLProperty* program_change = node.property("ProgramChange");
124 if (program_change) {
125 _id = PatchPrimaryKey(string_to_int(tree, program_change->value()), _id.bank());
128 const XMLProperty* name = node.property("Name");
132 _name = name->value();
134 XMLNode* commands = node.child("PatchMIDICommands");
136 if (initialize_primary_key_from_commands(tree, _id, commands) &&
138 return -1; // Failed to find a program number anywhere
142 XMLNode* use_note_name_list = node.child("UsesNoteNameList");
143 if (use_note_name_list) {
144 _note_list_name = use_note_name_list->property ("Name")->value();
151 Note::get_state (void)
153 XMLNode* node = new XMLNode("Note");
154 node->set_property("Number", _number);
155 node->set_property("Name", _name);
161 Note::set_state (const XMLTree& tree, const XMLNode& node)
163 assert(node.name() == "Note");
165 const int num = string_to_int(tree, node.property("Number")->value());
167 PBD::warning << string_compose("%1: Note number %2 (%3) out of range",
168 tree.filename(), num, _name)
174 _name = node.property("Name")->value();
180 NoteNameList::get_state (void)
182 XMLNode* node = new XMLNode("NoteNameList");
183 node->set_property("Name", _name);
189 add_note_from_xml (NoteNameList::Notes& notes, const XMLTree& tree, const XMLNode& node)
191 boost::shared_ptr<Note> note(new Note());
192 if (!note->set_state (tree, node)) {
193 if (!notes[note->number()]) {
194 notes[note->number()] = note;
197 << string_compose("%1: Duplicate note number %2 (%3) ignored",
198 tree.filename(), (int)note->number(), note->name())
205 NoteNameList::set_state (const XMLTree& tree, const XMLNode& node)
207 assert(node.name() == "NoteNameList");
208 _name = node.property("Name")->value();
212 for (XMLNodeList::const_iterator i = node.children().begin();
213 i != node.children().end(); ++i) {
214 if ((*i)->name() == "Note") {
215 add_note_from_xml(_notes, tree, **i);
216 } else if ((*i)->name() == "NoteGroup") {
217 for (XMLNodeList::const_iterator j = (*i)->children().begin();
218 j != (*i)->children().end(); ++j) {
219 if ((*j)->name() == "Note") {
220 add_note_from_xml(_notes, tree, **j);
222 PBD::warning << string_compose("%1: Invalid NoteGroup child %2 ignored",
223 tree.filename(), (*j)->name())
234 Control::get_state (void)
236 XMLNode* node = new XMLNode("Control");
237 node->set_property("Type", _type);
238 node->set_property("Number", _number);
239 node->set_property("Name", _name);
245 Control::set_state (const XMLTree& tree, const XMLNode& node)
247 assert(node.name() == "Control");
248 if (node.property("Type")) {
249 _type = node.property("Type")->value();
253 _number = string_to_int(tree, node.property("Number")->value());
254 _name = node.property("Name")->value();
256 for (XMLNodeList::const_iterator i = node.children().begin();
257 i != node.children().end(); ++i) {
258 if ((*i)->name() == "Values") {
259 // <Values> has Min and Max properties, but we don't care
260 for (XMLNodeList::const_iterator j = (*i)->children().begin();
261 j != (*i)->children().end(); ++j) {
262 if ((*j)->name() == "ValueNameList") {
263 _value_name_list = boost::shared_ptr<ValueNameList>(new ValueNameList());
264 _value_name_list->set_state(tree, **j);
265 } else if ((*j)->name() == "UsesValueNameList") {
266 _value_name_list_name = (*j)->property("Name")->value();
276 ControlNameList::get_state (void)
278 XMLNode* node = new XMLNode("ControlNameList");
279 node->set_property("Name", _name);
285 ControlNameList::set_state (const XMLTree& tree, const XMLNode& node)
287 assert(node.name() == "ControlNameList");
288 _name = node.property("Name")->value();
291 for (XMLNodeList::const_iterator i = node.children().begin();
292 i != node.children().end(); ++i) {
293 if ((*i)->name() == "Control") {
294 boost::shared_ptr<Control> control(new Control());
295 control->set_state (tree, *(*i));
296 if (_controls.find(control->number()) == _controls.end()) {
297 _controls.insert(make_pair(control->number(), control));
299 PBD::warning << string_compose("%1: Duplicate control %2 ignored",
300 tree.filename(), control->number())
309 boost::shared_ptr<const Control>
310 ControlNameList::control(uint16_t num) const
312 Controls::const_iterator i = _controls.find(num);
313 if (i != _controls.end()) {
316 return boost::shared_ptr<const Control>();
320 Value::get_state (void)
322 XMLNode* node = new XMLNode("Value");
323 node->set_property("Number", _number);
324 node->set_property("Name", _name);
330 Value::set_state (const XMLTree& tree, const XMLNode& node)
332 assert(node.name() == "Value");
333 _number = string_to_int(tree, node.property("Number")->value());
334 _name = node.property("Name")->value();
340 ValueNameList::get_state (void)
342 XMLNode* node = new XMLNode("ValueNameList");
343 node->set_property("Name", _name);
349 ValueNameList::set_state (const XMLTree& tree, const XMLNode& node)
351 assert(node.name() == "ValueNameList");
352 const XMLProperty* name_prop = node.property("Name");
354 // May be anonymous if written inline within a single <Control> tag
355 _name = name_prop->value();
359 for (XMLNodeList::const_iterator i = node.children().begin();
360 i != node.children().end(); ++i) {
361 if ((*i)->name() == "Value") {
362 boost::shared_ptr<Value> value(new Value());
363 value->set_state (tree, *(*i));
364 if (_values.find(value->number()) == _values.end()) {
365 _values.insert(make_pair(value->number(), value));
367 PBD::warning << string_compose("%1: Duplicate value %2 ignored",
368 tree.filename(), value->number())
377 boost::shared_ptr<const Value>
378 ValueNameList::value(uint16_t num) const
380 Values::const_iterator i = _values.find(num);
381 if (i != _values.end()) {
384 return boost::shared_ptr<const Value>();
387 boost::shared_ptr<const Value>
388 ValueNameList::max_value_below(uint16_t num) const
390 Values::const_iterator i = _values.lower_bound(num);
391 if (i->first == num) {
394 } else if (i == _values.begin()) {
396 return boost::shared_ptr<const Value>();
398 // Found the smallest element >= num, so the previous one is our result
405 PatchBank::get_state (void)
407 XMLNode* node = new XMLNode("PatchBank");
408 node->set_property("Name", _name);
409 XMLNode* patch_name_list = node->add_child("PatchNameList");
410 for (PatchNameList::iterator patch = _patch_name_list.begin();
411 patch != _patch_name_list.end();
413 patch_name_list->add_child_nocopy((*patch)->get_state());
420 PatchBank::set_state (const XMLTree& tree, const XMLNode& node)
422 assert(node.name() == "PatchBank");
423 _name = node.property("Name")->value();
425 XMLNode* commands = node.child("MIDICommands");
427 PatchPrimaryKey id (0, 0);
428 if (initialize_primary_key_from_commands (tree, id, commands)) {
434 XMLNode* patch_name_list = node.child("PatchNameList");
436 if (patch_name_list) {
437 const XMLNodeList patches = patch_name_list->children();
438 for (XMLNodeList::const_iterator i = patches.begin(); i != patches.end(); ++i) {
439 boost::shared_ptr<Patch> patch (new Patch (string(), 0, _number));
440 if (0 == patch->set_state(tree, *(*i))) {
441 _patch_name_list.push_back(patch);
445 XMLNode* use_patch_name_list = node.child ("UsesPatchNameList");
446 if (use_patch_name_list) {
447 _patch_list_name = use_patch_name_list->property ("Name")->value();
449 error << "Patch without patch name list - patchfile will be ignored" << endmsg;
458 PatchBank::set_patch_name_list (const PatchNameList& pnl)
460 _patch_name_list = pnl;
461 _patch_list_name = "";
463 for (PatchNameList::iterator p = _patch_name_list.begin(); p != _patch_name_list.end(); p++) {
464 (*p)->set_bank_number (_number);
471 operator<< (std::ostream& os, const ChannelNameSet& cns)
473 os << "Channel Name Set: name = " << cns._name << endl
474 << "Map size " << cns._patch_map.size () << endl
475 << "List size " << cns._patch_list.size() << endl
476 << "Patch list name = [" << cns._patch_list_name << ']' << endl
477 << "Available channels : ";
478 for (set<uint8_t>::const_iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) {
479 os << (int) (*x) << ' ';
483 for (ChannelNameSet::PatchBanks::const_iterator pbi = cns._patch_banks.begin(); pbi != cns._patch_banks.end(); ++pbi) {
484 os << "\tPatch Bank " << (*pbi)->name() << " with " << (*pbi)->patch_name_list().size() << " patches\n";
485 for (PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
486 os << "\t\tPatch name " << (*pni)->name() << " prog " << (int) (*pni)->program_number() << " bank " << (*pni)->bank_number() << endl;
494 ChannelNameSet::set_patch_banks (const ChannelNameSet::PatchBanks& pb)
499 _patch_list.clear ();
500 _patch_list_name = "";
501 _available_for_channels.clear ();
503 for (PatchBanks::const_iterator pbi = _patch_banks.begin(); pbi != _patch_banks.end(); ++pbi) {
504 for (PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
505 _patch_map[(*pni)->patch_primary_key()] = (*pni);
506 _patch_list.push_back ((*pni)->patch_primary_key());
510 for (uint8_t n = 0; n < 16; ++n) {
511 _available_for_channels.insert (n);
516 ChannelNameSet::use_patch_name_list (const PatchNameList& pnl)
518 for (PatchNameList::const_iterator p = pnl.begin(); p != pnl.end(); ++p) {
519 _patch_map[(*p)->patch_primary_key()] = (*p);
520 _patch_list.push_back ((*p)->patch_primary_key());
525 ChannelNameSet::get_state (void)
527 XMLNode* node = new XMLNode("ChannelNameSet");
528 node->set_property("Name", _name);
530 XMLNode* available_for_channels = node->add_child("AvailableForChannels");
531 assert(available_for_channels);
533 for (uint8_t channel = 0; channel < 16; ++channel) {
534 XMLNode* available_channel = available_for_channels->add_child("AvailableChannel");
535 assert(available_channel);
537 available_channel->set_property("Channel", channel);
539 if (_available_for_channels.find(channel) != _available_for_channels.end()) {
540 available_channel->set_property("Available", "true");
542 available_channel->set_property("Available", "false");
546 for (PatchBanks::iterator patch_bank = _patch_banks.begin();
547 patch_bank != _patch_banks.end();
549 node->add_child_nocopy((*patch_bank)->get_state());
556 ChannelNameSet::set_state (const XMLTree& tree, const XMLNode& node)
558 assert(node.name() == "ChannelNameSet");
559 _name = node.property("Name")->value();
561 const XMLNodeList children = node.children();
562 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
565 if (node->name() == "AvailableForChannels") {
566 boost::shared_ptr<XMLSharedNodeList> channels =
567 tree.find("//AvailableChannel[@Available = 'true']/@Channel", node);
568 for (XMLSharedNodeList::const_iterator i = channels->begin();
569 i != channels->end();
572 _available_for_channels.insert(
573 string_to_int(tree, (*i)->attribute_value()));
574 } catch (XMLException &e) {
575 cerr << "ChannelNameSet::set_state: " << e.what () << endl;
578 } else if (node->name() == "PatchBank") {
579 boost::shared_ptr<PatchBank> bank (new PatchBank ());
580 bank->set_state(tree, *node);
581 _patch_banks.push_back(bank);
582 const PatchNameList& patches = bank->patch_name_list();
583 for (PatchNameList::const_iterator patch = patches.begin();
584 patch != patches.end();
586 _patch_map[(*patch)->patch_primary_key()] = *patch;
587 _patch_list.push_back((*patch)->patch_primary_key());
589 } else if (node->name() == "UsesNoteNameList") {
590 _note_list_name = node->property ("Name")->value();
591 } else if (node->name() == "UsesControlNameList") {
592 _control_list_name = node->property ("Name")->value();
600 CustomDeviceMode::set_state(const XMLTree& tree, const XMLNode& a_node)
602 assert(a_node.name() == "CustomDeviceMode");
604 _name = a_node.property("Name")->value();
606 boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
607 tree.find("//ChannelNameSetAssign", const_cast<XMLNode *>(&a_node));
608 for (XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
609 i != channel_name_set_assignments->end();
611 const int channel = string_to_int(tree, (*i)->property("Channel")->value());
612 const string& name_set = (*i)->property("NameSet")->value();
613 assert( 1 <= channel && channel <= 16 );
614 _channel_name_set_assignments[channel - 1] = name_set;
620 CustomDeviceMode::get_state(void)
622 XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
623 custom_device_mode->set_property("Name", _name);
624 XMLNode* channel_name_set_assignments =
625 custom_device_mode->add_child("ChannelNameSetAssignments");
626 for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
627 XMLNode* channel_name_set_assign =
628 channel_name_set_assignments->add_child("ChannelNameSetAssign");
629 channel_name_set_assign->set_property("Channel", i + 1);
630 channel_name_set_assign->set_property("NameSet", _channel_name_set_assignments[i]);
633 return *custom_device_mode;
636 boost::shared_ptr<const ValueNameList>
637 MasterDeviceNames::value_name_list_by_control(const std::string& mode, uint8_t channel, uint8_t number)
639 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(mode, channel);
641 return boost::shared_ptr<const ValueNameList>();
644 boost::shared_ptr<ControlNameList> control_names = control_name_list(chan_names->control_list_name());
645 if (!control_names) {
646 return boost::shared_ptr<const ValueNameList>();
649 boost::shared_ptr<const Control> control = control_names->control(number);
651 return boost::shared_ptr<const ValueNameList>();
654 if (!control->value_name_list_name().empty()) {
655 return value_name_list(control->value_name_list_name());
657 return control->value_name_list();
661 boost::shared_ptr<CustomDeviceMode>
662 MasterDeviceNames::custom_device_mode_by_name(const std::string& mode_name)
664 return _custom_device_modes[mode_name];
667 boost::shared_ptr<ChannelNameSet>
668 MasterDeviceNames::channel_name_set_by_channel(const std::string& mode, uint8_t channel)
670 boost::shared_ptr<CustomDeviceMode> cdm = custom_device_mode_by_name(mode);
671 boost::shared_ptr<ChannelNameSet> cns = _channel_name_sets[cdm->channel_name_set_name_by_channel(channel)];
675 boost::shared_ptr<Patch>
676 MasterDeviceNames::find_patch(const std::string& mode, uint8_t channel, const PatchPrimaryKey& key)
678 boost::shared_ptr<ChannelNameSet> cns = channel_name_set_by_channel(mode, channel);
679 if (!cns) return boost::shared_ptr<Patch>();
680 return cns->find_patch(key);
683 boost::shared_ptr<ChannelNameSet>
684 MasterDeviceNames::channel_name_set(const std::string& name)
686 ChannelNameSets::const_iterator i = _channel_name_sets.find(name);
687 if (i != _channel_name_sets.end()) {
690 return boost::shared_ptr<ChannelNameSet>();
693 boost::shared_ptr<ControlNameList>
694 MasterDeviceNames::control_name_list(const std::string& name)
696 ControlNameLists::const_iterator i = _control_name_lists.find(name);
697 if (i != _control_name_lists.end()) {
700 return boost::shared_ptr<ControlNameList>();
703 boost::shared_ptr<ValueNameList>
704 MasterDeviceNames::value_name_list(const std::string& name)
706 ValueNameLists::const_iterator i = _value_name_lists.find(name);
707 if (i != _value_name_lists.end()) {
710 return boost::shared_ptr<ValueNameList>();
713 boost::shared_ptr<NoteNameList>
714 MasterDeviceNames::note_name_list(const std::string& name)
716 NoteNameLists::const_iterator i = _note_name_lists.find(name);
717 if (i != _note_name_lists.end()) {
720 return boost::shared_ptr<NoteNameList>();
724 MasterDeviceNames::note_name(const std::string& mode_name,
734 boost::shared_ptr<const NoteNameList> note_names;
735 boost::shared_ptr<const Patch> patch(
736 find_patch(mode_name, channel, PatchPrimaryKey(program, bank)));
738 note_names = note_name_list(patch->note_list_name());
742 /* No note names specific to this patch, check the ChannelNameSet */
743 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(
746 note_names = note_name_list(chan_names->note_list_name());
753 boost::shared_ptr<const Note> note(note_names->notes()[number]);
754 return note ? note->name() : "";
758 MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode&)
761 boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer");
762 assert(manufacturer->size() == 1);
763 _manufacturer = manufacturer->front()->children().front()->content();
766 boost::shared_ptr<XMLSharedNodeList> models = tree.find("//Model");
767 assert(models->size() >= 1);
768 for (XMLSharedNodeList::iterator i = models->begin();
771 const XMLNodeList& contents = (*i)->children();
772 assert(contents.size() == 1);
773 XMLNode * content = *(contents.begin());
774 assert(content->is_content());
775 _models.insert(content->content());
779 boost::shared_ptr<XMLSharedNodeList> custom_device_modes = tree.find("//CustomDeviceMode");
780 for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
781 i != custom_device_modes->end();
783 boost::shared_ptr<CustomDeviceMode> custom_device_mode(new CustomDeviceMode());
784 custom_device_mode->set_state(tree, *(*i));
786 _custom_device_modes[custom_device_mode->name()] = custom_device_mode;
787 _custom_device_mode_names.push_back(custom_device_mode->name());
791 boost::shared_ptr<XMLSharedNodeList> channel_name_sets = tree.find("//ChannelNameSet");
792 for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
793 i != channel_name_sets->end();
795 boost::shared_ptr<ChannelNameSet> channel_name_set(new ChannelNameSet());
796 channel_name_set->set_state(tree, *(*i));
797 _channel_name_sets[channel_name_set->name()] = channel_name_set;
801 boost::shared_ptr<XMLSharedNodeList> note_name_lists = tree.find("//NoteNameList");
802 for (XMLSharedNodeList::iterator i = note_name_lists->begin();
803 i != note_name_lists->end();
805 boost::shared_ptr<NoteNameList> note_name_list(new NoteNameList());
806 note_name_list->set_state (tree, *(*i));
807 _note_name_lists[note_name_list->name()] = note_name_list;
811 boost::shared_ptr<XMLSharedNodeList> control_name_lists = tree.find("//ControlNameList");
812 for (XMLSharedNodeList::iterator i = control_name_lists->begin();
813 i != control_name_lists->end();
815 boost::shared_ptr<ControlNameList> control_name_list(new ControlNameList());
816 control_name_list->set_state (tree, *(*i));
817 _control_name_lists[control_name_list->name()] = control_name_list;
821 boost::shared_ptr<XMLSharedNodeList> value_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::ValueNameList");
822 for (XMLSharedNodeList::iterator i = value_name_lists->begin();
823 i != value_name_lists->end();
825 boost::shared_ptr<ValueNameList> value_name_list(new ValueNameList());
826 value_name_list->set_state (tree, *(*i));
827 _value_name_lists[value_name_list->name()] = value_name_list;
830 // global/post-facto PatchNameLists
831 boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList");
832 for (XMLSharedNodeList::iterator i = patch_name_lists->begin();
833 i != patch_name_lists->end();
836 PatchNameList patch_name_list;
837 const XMLNodeList patches = (*i)->children();
839 for (XMLNodeList::const_iterator p = patches.begin(); p != patches.end(); ++p) {
840 boost::shared_ptr<Patch> patch (new Patch ());
841 patch->set_state(tree, *(*p));
842 patch_name_list.push_back(patch);
845 if (!patch_name_list.empty()) {
846 _patch_name_lists[(*i)->property ("Name")->value()] = patch_name_list;
850 /* now traverse patches and hook up anything that used UsePatchNameList
851 * to the right patch list
854 for (ChannelNameSets::iterator cns = _channel_name_sets.begin(); cns != _channel_name_sets.end(); ++cns) {
855 ChannelNameSet::PatchBanks pbs = cns->second->patch_banks();
856 PatchNameLists::iterator p;
858 for (ChannelNameSet::PatchBanks::iterator pb = pbs.begin(); pb != pbs.end(); ++pb) {
859 const std::string& pln = (*pb)->patch_list_name();
861 if ((p = _patch_name_lists.find (pln)) != _patch_name_lists.end()) {
862 if ((*pb)->set_patch_name_list (p->second)) {
865 cns->second->use_patch_name_list (p->second);
867 error << string_compose ("Patch list name %1 was not found - patch file ignored", pln) << endmsg;
879 MasterDeviceNames::get_state(void)
881 static XMLNode nothing("<nothing>");
885 MIDINameDocument::MIDINameDocument (const string& file_path)
886 : _file_path(file_path)
889 if (!document.read (file_path)) {
890 throw failed_constructor ();
893 document.set_filename (file_path);
894 set_state (document, *document.root());
898 MIDINameDocument::set_state (const XMLTree& tree, const XMLNode&)
902 boost::shared_ptr<XMLSharedNodeList> author = tree.find("//Author");
903 if (author->size() < 1) {
904 error << "No author information in MIDNAM file" << endmsg;
908 if (author->front()->children().size() > 0) {
909 _author = author->front()->children().front()->content();
914 boost::shared_ptr<XMLSharedNodeList> master_device_names_list = tree.find ("//MasterDeviceNames");
916 for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
917 i != master_device_names_list->end();
919 boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
921 if (master_device_names->set_state(tree, *(*i))) {
925 for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
926 model != master_device_names->models().end();
928 _master_device_names_list.insert(
929 std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
930 (*model, master_device_names));
932 _all_models.insert(*model);
940 MIDINameDocument::get_state(void)
942 static XMLNode nothing("<nothing>");
946 boost::shared_ptr<MasterDeviceNames>
947 MIDINameDocument::master_device_names(const std::string& model)
949 MasterDeviceNamesList::const_iterator m = _master_device_names_list.find(model);
950 if (m != _master_device_names_list.end()) {
951 return boost::shared_ptr<MasterDeviceNames>(m->second);
953 return boost::shared_ptr<MasterDeviceNames>();
956 const char* general_midi_program_names[128] = {
957 "Acoustic Grand Piano",
958 "Bright Acoustic Piano",
959 "Electric Grand Piano",
981 "Acoustic Guitar (nylon)",
982 "Acoustic Guitar (steel)",
983 "Electric Guitar (jazz)",
984 "Electric Guitar (clean)",
985 "Electric Guitar (muted)",
990 "Electric Bass (finger)",
991 "Electric Bass (pick)",
1002 "Pizzicato Strings",
1005 "String Ensemble 1",
1006 "String Ensemble 2",
1038 "Lead 2 (sawtooth)",
1039 "Lead 3 (calliope lead)",
1040 "Lead 4 (chiff lead)",
1044 "Lead 8 (bass + lead)",
1047 "Pad 3 (polysynth)",
1054 "FX 2 (soundtrack)",
1056 "FX 4 (atmosphere)",
1057 "FX 5 (brightness)",
1077 "Guitar Fret Noise",