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)
63 const XMLNodeList events = node->children();
64 for (XMLNodeList::const_iterator i = events.begin(); i != events.end(); ++i) {
67 if (node->name() == "ControlChange") {
68 const string& control = node->property("Control")->value();
69 const string& value = node->property("Value")->value();
72 id.bank_number |= string_to_int(tree, value) << 7;
73 } else if (control == "32") {
74 id.bank_number |= string_to_int(tree, value);
77 } else if (node->name() == "ProgramChange") {
78 const string& number = node->property("Number")->value();
80 id.program_number = string_to_int(tree, number);
88 Patch::get_state (void)
90 XMLNode* node = new XMLNode("Patch");
92 /* XXX this is totally wrong */
94 node->add_property("Number", string_compose ("%1", _id.program_number));
95 node->add_property("Name", _name);
98 typedef std::list< boost::shared_ptr< Evoral::MIDIEvent<Evoral::MusicalTime> > > PatchMidiCommands;
99 XMLNode* commands = node->add_child("PatchMIDICommands");
100 for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
101 event != _patch_midi_commands.end();
103 commands->add_child_copy(*((((Evoral::MIDIEvent&)*event)).to_xml()));
111 Patch::set_state (const XMLTree& tree, const XMLNode& node)
113 if (node.name() != "Patch") {
114 cerr << "Incorrect node " << node.name() << " handed to Patch" << endl;
118 /* Note there is a "Number" attribute, but it's really more like a label
119 and is often not numeric. We currently do not use it. */
121 const XMLProperty* program_change = node.property("ProgramChange");
122 if (program_change) {
123 _id.program_number = string_to_int(tree, program_change->value());
126 const XMLProperty* name = node.property("Name");
130 _name = name->value();
132 XMLNode* commands = node.child("PatchMIDICommands");
134 if (initialize_primary_key_from_commands(tree, _id, commands) &&
136 return -1; // Failed to find a program number anywhere
140 XMLNode* use_note_name_list = node.child("UsesNoteNameList");
141 if (use_note_name_list) {
142 _note_list_name = use_note_name_list->property ("Name")->value();
149 Note::get_state (void)
151 XMLNode* node = new XMLNode("Note");
152 node->add_property("Number", _number + 1);
153 node->add_property("Name", _name);
159 Note::set_state (const XMLTree& tree, const XMLNode& node)
161 assert(node.name() == "Note");
163 const int num = string_to_int(tree, node.property("Number")->value());
164 if (num < 1 || num > 128) {
165 PBD::warning << string_compose("%1: Note number %2 (%3) out of range",
166 tree.filename(), num, _name)
172 _name = node.property("Name")->value();
178 NoteNameList::get_state (void)
180 XMLNode* node = new XMLNode("NoteNameList");
181 node->add_property("Name", _name);
187 add_note_from_xml (NoteNameList::Notes& notes, const XMLTree& tree, const XMLNode& node)
189 boost::shared_ptr<Note> note(new Note());
190 if (!note->set_state (tree, node)) {
191 if (!notes[note->number()]) {
192 notes[note->number()] = note;
195 << string_compose("%1: Duplicate note number %2 (%3) ignored",
196 tree.filename(), (int)note->number(), note->name())
203 NoteNameList::set_state (const XMLTree& tree, const XMLNode& node)
205 assert(node.name() == "NoteNameList");
206 _name = node.property("Name")->value();
210 for (XMLNodeList::const_iterator i = node.children().begin();
211 i != node.children().end(); ++i) {
212 if ((*i)->name() == "Note") {
213 add_note_from_xml(_notes, tree, **i);
214 } else if ((*i)->name() == "NoteGroup") {
215 for (XMLNodeList::const_iterator j = (*i)->children().begin();
216 j != (*i)->children().end(); ++j) {
217 if ((*j)->name() == "Note") {
218 add_note_from_xml(_notes, tree, **j);
220 PBD::warning << string_compose("%1: Invalid NoteGroup child %2 ignored",
221 tree.filename(), (*j)->name())
232 Control::get_state (void)
234 XMLNode* node = new XMLNode("Control");
235 node->add_property("Type", _type);
236 node->add_property("Number", _number);
237 node->add_property("Name", _name);
243 Control::set_state (const XMLTree& tree, const XMLNode& node)
245 assert(node.name() == "Control");
246 if (node.property("Type")) {
247 _type = node.property("Type")->value();
251 _number = string_to_int(tree, node.property("Number")->value());
252 _name = node.property("Name")->value();
254 for (XMLNodeList::const_iterator i = node.children().begin();
255 i != node.children().end(); ++i) {
256 if ((*i)->name() == "Values") {
257 // <Values> has Min and Max properties, but we don't care
258 for (XMLNodeList::const_iterator j = (*i)->children().begin();
259 j != (*i)->children().end(); ++j) {
260 if ((*j)->name() == "ValueNameList") {
261 _value_name_list = boost::shared_ptr<ValueNameList>(new ValueNameList());
262 _value_name_list->set_state(tree, **j);
263 } else if ((*j)->name() == "UsesValueNameList") {
264 _value_name_list_name = (*j)->property("Name")->value();
274 ControlNameList::get_state (void)
276 XMLNode* node = new XMLNode("ControlNameList");
277 node->add_property("Name", _name);
283 ControlNameList::set_state (const XMLTree& tree, const XMLNode& node)
285 assert(node.name() == "ControlNameList");
286 _name = node.property("Name")->value();
289 for (XMLNodeList::const_iterator i = node.children().begin();
290 i != node.children().end(); ++i) {
291 if ((*i)->name() == "Control") {
292 boost::shared_ptr<Control> control(new Control());
293 control->set_state (tree, *(*i));
294 if (_controls.find(control->number()) == _controls.end()) {
295 _controls.insert(make_pair(control->number(), control));
297 PBD::warning << string_compose("%1: Duplicate control %2 ignored",
298 tree.filename(), control->number())
307 boost::shared_ptr<const Control>
308 ControlNameList::control(uint16_t num) const
310 Controls::const_iterator i = _controls.find(num);
311 if (i != _controls.end()) {
314 return boost::shared_ptr<const Control>();
318 Value::get_state (void)
320 XMLNode* node = new XMLNode("Value");
321 node->add_property("Number", _number);
322 node->add_property("Name", _name);
328 Value::set_state (const XMLTree& tree, const XMLNode& node)
330 assert(node.name() == "Value");
331 _number = string_to_int(tree, node.property("Number")->value());
332 _name = node.property("Name")->value();
338 ValueNameList::get_state (void)
340 XMLNode* node = new XMLNode("ValueNameList");
341 node->add_property("Name", _name);
347 ValueNameList::set_state (const XMLTree& tree, const XMLNode& node)
349 assert(node.name() == "ValueNameList");
350 const XMLProperty* name_prop = node.property("Name");
352 // May be anonymous if written inline within a single <Control> tag
353 _name = name_prop->value();
357 for (XMLNodeList::const_iterator i = node.children().begin();
358 i != node.children().end(); ++i) {
359 if ((*i)->name() == "Value") {
360 boost::shared_ptr<Value> value(new Value());
361 value->set_state (tree, *(*i));
362 if (_values.find(value->number()) == _values.end()) {
363 _values.insert(make_pair(value->number(), value));
365 PBD::warning << string_compose("%1: Duplicate value %2 ignored",
366 tree.filename(), value->number())
375 boost::shared_ptr<const Value>
376 ValueNameList::value(uint16_t num) const
378 Values::const_iterator i = _values.find(num);
379 if (i != _values.end()) {
382 return boost::shared_ptr<const Value>();
385 boost::shared_ptr<const Value>
386 ValueNameList::max_value_below(uint16_t num) const
388 Values::const_iterator i = _values.lower_bound(num);
389 if (i->first == num) {
392 } else if (i == _values.begin()) {
394 return boost::shared_ptr<const Value>();
396 // Found the smallest element >= num, so the previous one is our result
403 PatchBank::get_state (void)
405 XMLNode* node = new XMLNode("PatchBank");
406 node->add_property("Name", _name);
407 XMLNode* patch_name_list = node->add_child("PatchNameList");
408 for (PatchNameList::iterator patch = _patch_name_list.begin();
409 patch != _patch_name_list.end();
411 patch_name_list->add_child_nocopy((*patch)->get_state());
418 PatchBank::set_state (const XMLTree& tree, const XMLNode& node)
420 assert(node.name() == "PatchBank");
421 _name = node.property("Name")->value();
423 XMLNode* commands = node.child("MIDICommands");
425 PatchPrimaryKey id (0, 0);
426 if (initialize_primary_key_from_commands (tree, id, commands)) {
429 _number = id.bank_number;
432 XMLNode* patch_name_list = node.child("PatchNameList");
434 if (patch_name_list) {
435 const XMLNodeList patches = patch_name_list->children();
436 for (XMLNodeList::const_iterator i = patches.begin(); i != patches.end(); ++i) {
437 boost::shared_ptr<Patch> patch (new Patch (string(), 0, _number));
438 patch->set_state(tree, *(*i));
439 _patch_name_list.push_back(patch);
442 XMLNode* use_patch_name_list = node.child ("UsesPatchNameList");
443 if (use_patch_name_list) {
444 _patch_list_name = use_patch_name_list->property ("Name")->value();
446 error << "Patch without patch name list - patchfile will be ignored" << endmsg;
455 PatchBank::set_patch_name_list (const PatchNameList& pnl)
457 _patch_name_list = pnl;
458 _patch_list_name = "";
460 for (PatchNameList::iterator p = _patch_name_list.begin(); p != _patch_name_list.end(); p++) {
461 (*p)->set_bank_number (_number);
468 operator<< (std::ostream& os, const ChannelNameSet& cns)
470 os << "Channel Name Set: name = " << cns._name << endl
471 << "Map size " << cns._patch_map.size () << endl
472 << "List size " << cns._patch_list.size() << endl
473 << "Patch list name = [" << cns._patch_list_name << ']' << endl
474 << "Available channels : ";
475 for (set<uint8_t>::const_iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) {
476 os << (int) (*x) << ' ';
480 for (ChannelNameSet::PatchBanks::const_iterator pbi = cns._patch_banks.begin(); pbi != cns._patch_banks.end(); ++pbi) {
481 os << "\tPatch Bank " << (*pbi)->name() << " with " << (*pbi)->patch_name_list().size() << " patches\n";
482 for (PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
483 os << "\t\tPatch name " << (*pni)->name() << " prog " << (int) (*pni)->program_number() << " bank " << (*pni)->bank_number() << endl;
491 ChannelNameSet::set_patch_banks (const ChannelNameSet::PatchBanks& pb)
496 _patch_list.clear ();
497 _patch_list_name = "";
498 _available_for_channels.clear ();
500 for (PatchBanks::const_iterator pbi = _patch_banks.begin(); pbi != _patch_banks.end(); ++pbi) {
501 for (PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
502 _patch_map[(*pni)->patch_primary_key()] = (*pni);
503 _patch_list.push_back ((*pni)->patch_primary_key());
507 for (uint8_t n = 0; n < 16; ++n) {
508 _available_for_channels.insert (n);
513 ChannelNameSet::use_patch_name_list (const PatchNameList& pnl)
515 for (PatchNameList::const_iterator p = pnl.begin(); p != pnl.end(); ++p) {
516 _patch_map[(*p)->patch_primary_key()] = (*p);
517 _patch_list.push_back ((*p)->patch_primary_key());
522 ChannelNameSet::get_state (void)
524 XMLNode* node = new XMLNode("ChannelNameSet");
525 node->add_property("Name", _name);
527 XMLNode* available_for_channels = node->add_child("AvailableForChannels");
528 assert(available_for_channels);
530 for (uint8_t channel = 0; channel < 16; ++channel) {
531 XMLNode* available_channel = available_for_channels->add_child("AvailableChannel");
532 assert(available_channel);
534 available_channel->add_property("Channel", (long) channel);
536 if (_available_for_channels.find(channel) != _available_for_channels.end()) {
537 available_channel->add_property("Available", "true");
539 available_channel->add_property("Available", "false");
543 for (PatchBanks::iterator patch_bank = _patch_banks.begin();
544 patch_bank != _patch_banks.end();
546 node->add_child_nocopy((*patch_bank)->get_state());
553 ChannelNameSet::set_state (const XMLTree& tree, const XMLNode& node)
555 assert(node.name() == "ChannelNameSet");
556 _name = node.property("Name")->value();
558 const XMLNodeList children = node.children();
559 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
562 if (node->name() == "AvailableForChannels") {
563 boost::shared_ptr<XMLSharedNodeList> channels =
564 tree.find("//AvailableChannel[@Available = 'true']/@Channel", node);
565 for (XMLSharedNodeList::const_iterator i = channels->begin();
566 i != channels->end();
568 _available_for_channels.insert(
569 string_to_int(tree, (*i)->attribute_value()));
571 } else if (node->name() == "PatchBank") {
572 boost::shared_ptr<PatchBank> bank (new PatchBank ());
573 bank->set_state(tree, *node);
574 _patch_banks.push_back(bank);
575 const PatchNameList& patches = bank->patch_name_list();
576 for (PatchNameList::const_iterator patch = patches.begin();
577 patch != patches.end();
579 _patch_map[(*patch)->patch_primary_key()] = *patch;
580 _patch_list.push_back((*patch)->patch_primary_key());
582 } else if (node->name() == "UsesNoteNameList") {
583 _note_list_name = node->property ("Name")->value();
584 } else if (node->name() == "UsesControlNameList") {
585 _control_list_name = node->property ("Name")->value();
593 CustomDeviceMode::set_state(const XMLTree& tree, const XMLNode& a_node)
595 assert(a_node.name() == "CustomDeviceMode");
597 _name = a_node.property("Name")->value();
599 boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
600 tree.find("//ChannelNameSetAssign", const_cast<XMLNode *>(&a_node));
601 for (XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
602 i != channel_name_set_assignments->end();
604 const int channel = string_to_int(tree, (*i)->property("Channel")->value());
605 const string& name_set = (*i)->property("NameSet")->value();
606 assert( 1 <= channel && channel <= 16 );
607 _channel_name_set_assignments[channel - 1] = name_set;
613 CustomDeviceMode::get_state(void)
615 XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
616 custom_device_mode->add_property("Name", _name);
617 XMLNode* channel_name_set_assignments =
618 custom_device_mode->add_child("ChannelNameSetAssignments");
619 for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
620 XMLNode* channel_name_set_assign =
621 channel_name_set_assignments->add_child("ChannelNameSetAssign");
622 channel_name_set_assign->add_property("Channel", i + 1);
623 channel_name_set_assign->add_property("NameSet", _channel_name_set_assignments[i]);
626 return *custom_device_mode;
629 boost::shared_ptr<const ValueNameList>
630 MasterDeviceNames::value_name_list_by_control(const std::string& mode, uint8_t channel, uint8_t number)
632 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(mode, channel);
634 return boost::shared_ptr<const ValueNameList>();
637 boost::shared_ptr<ControlNameList> control_names = control_name_list(chan_names->control_list_name());
638 if (!control_names) {
639 return boost::shared_ptr<const ValueNameList>();
642 boost::shared_ptr<const Control> control = control_names->control(number);
644 return boost::shared_ptr<const ValueNameList>();
647 if (!control->value_name_list_name().empty()) {
648 return value_name_list(control->value_name_list_name());
650 return control->value_name_list();
654 boost::shared_ptr<CustomDeviceMode>
655 MasterDeviceNames::custom_device_mode_by_name(const std::string& mode_name)
657 return _custom_device_modes[mode_name];
660 boost::shared_ptr<ChannelNameSet>
661 MasterDeviceNames::channel_name_set_by_channel(const std::string& mode, uint8_t channel)
663 boost::shared_ptr<CustomDeviceMode> cdm = custom_device_mode_by_name(mode);
664 boost::shared_ptr<ChannelNameSet> cns = _channel_name_sets[cdm->channel_name_set_name_by_channel(channel)];
668 boost::shared_ptr<Patch>
669 MasterDeviceNames::find_patch(const std::string& mode, uint8_t channel, const PatchPrimaryKey& key)
671 boost::shared_ptr<ChannelNameSet> cns = channel_name_set_by_channel(mode, channel);
672 if (!cns) return boost::shared_ptr<Patch>();
673 return cns->find_patch(key);
676 boost::shared_ptr<ChannelNameSet>
677 MasterDeviceNames::channel_name_set(const std::string& name)
679 ChannelNameSets::const_iterator i = _channel_name_sets.find(name);
680 if (i != _channel_name_sets.end()) {
683 return boost::shared_ptr<ChannelNameSet>();
686 boost::shared_ptr<ControlNameList>
687 MasterDeviceNames::control_name_list(const std::string& name)
689 ControlNameLists::const_iterator i = _control_name_lists.find(name);
690 if (i != _control_name_lists.end()) {
693 return boost::shared_ptr<ControlNameList>();
696 boost::shared_ptr<ValueNameList>
697 MasterDeviceNames::value_name_list(const std::string& name)
699 ValueNameLists::const_iterator i = _value_name_lists.find(name);
700 if (i != _value_name_lists.end()) {
703 return boost::shared_ptr<ValueNameList>();
706 boost::shared_ptr<NoteNameList>
707 MasterDeviceNames::note_name_list(const std::string& name)
709 NoteNameLists::const_iterator i = _note_name_lists.find(name);
710 if (i != _note_name_lists.end()) {
713 return boost::shared_ptr<NoteNameList>();
717 MasterDeviceNames::note_name(const std::string& mode_name,
727 boost::shared_ptr<const NoteNameList> note_names;
728 boost::shared_ptr<const Patch> patch(
729 find_patch(mode_name, channel, PatchPrimaryKey(program, bank)));
731 note_names = note_name_list(patch->note_list_name());
735 /* No note names specific to this patch, check the ChannelNameSet */
736 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(
739 note_names = note_name_list(chan_names->note_list_name());
746 boost::shared_ptr<const Note> note(note_names->notes()[number]);
747 return note ? note->name() : "";
751 MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode&)
754 boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer");
755 assert(manufacturer->size() == 1);
756 _manufacturer = manufacturer->front()->children().front()->content();
759 boost::shared_ptr<XMLSharedNodeList> models = tree.find("//Model");
760 assert(models->size() >= 1);
761 for (XMLSharedNodeList::iterator i = models->begin();
764 const XMLNodeList& contents = (*i)->children();
765 assert(contents.size() == 1);
766 XMLNode * content = *(contents.begin());
767 assert(content->is_content());
768 _models.insert(content->content());
772 boost::shared_ptr<XMLSharedNodeList> custom_device_modes = tree.find("//CustomDeviceMode");
773 for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
774 i != custom_device_modes->end();
776 boost::shared_ptr<CustomDeviceMode> custom_device_mode(new CustomDeviceMode());
777 custom_device_mode->set_state(tree, *(*i));
779 _custom_device_modes[custom_device_mode->name()] = custom_device_mode;
780 _custom_device_mode_names.push_back(custom_device_mode->name());
784 boost::shared_ptr<XMLSharedNodeList> channel_name_sets = tree.find("//ChannelNameSet");
785 for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
786 i != channel_name_sets->end();
788 boost::shared_ptr<ChannelNameSet> channel_name_set(new ChannelNameSet());
789 channel_name_set->set_state(tree, *(*i));
790 _channel_name_sets[channel_name_set->name()] = channel_name_set;
794 boost::shared_ptr<XMLSharedNodeList> note_name_lists = tree.find("//NoteNameList");
795 for (XMLSharedNodeList::iterator i = note_name_lists->begin();
796 i != note_name_lists->end();
798 boost::shared_ptr<NoteNameList> note_name_list(new NoteNameList());
799 note_name_list->set_state (tree, *(*i));
800 _note_name_lists[note_name_list->name()] = note_name_list;
804 boost::shared_ptr<XMLSharedNodeList> control_name_lists = tree.find("//ControlNameList");
805 for (XMLSharedNodeList::iterator i = control_name_lists->begin();
806 i != control_name_lists->end();
808 boost::shared_ptr<ControlNameList> control_name_list(new ControlNameList());
809 control_name_list->set_state (tree, *(*i));
810 _control_name_lists[control_name_list->name()] = control_name_list;
814 boost::shared_ptr<XMLSharedNodeList> value_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::ValueNameList");
815 for (XMLSharedNodeList::iterator i = value_name_lists->begin();
816 i != value_name_lists->end();
818 boost::shared_ptr<ValueNameList> value_name_list(new ValueNameList());
819 value_name_list->set_state (tree, *(*i));
820 _value_name_lists[value_name_list->name()] = value_name_list;
823 // global/post-facto PatchNameLists
824 boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList");
825 for (XMLSharedNodeList::iterator i = patch_name_lists->begin();
826 i != patch_name_lists->end();
829 PatchNameList patch_name_list;
830 const XMLNodeList patches = (*i)->children();
832 for (XMLNodeList::const_iterator p = patches.begin(); p != patches.end(); ++p) {
833 boost::shared_ptr<Patch> patch (new Patch ());
834 patch->set_state(tree, *(*p));
835 patch_name_list.push_back(patch);
838 if (!patch_name_list.empty()) {
839 _patch_name_lists[(*i)->property ("Name")->value()] = patch_name_list;
843 /* now traverse patches and hook up anything that used UsePatchNameList
844 * to the right patch list
847 for (ChannelNameSets::iterator cns = _channel_name_sets.begin(); cns != _channel_name_sets.end(); ++cns) {
848 ChannelNameSet::PatchBanks pbs = cns->second->patch_banks();
849 PatchNameLists::iterator p;
851 for (ChannelNameSet::PatchBanks::iterator pb = pbs.begin(); pb != pbs.end(); ++pb) {
852 const std::string& pln = (*pb)->patch_list_name();
854 if ((p = _patch_name_lists.find (pln)) != _patch_name_lists.end()) {
855 if ((*pb)->set_patch_name_list (p->second)) {
858 cns->second->use_patch_name_list (p->second);
860 error << string_compose ("Patch list name %1 was not found - patch file ignored", pln) << endmsg;
872 MasterDeviceNames::get_state(void)
874 static XMLNode nothing("<nothing>");
878 MIDINameDocument::MIDINameDocument (const string& filename)
881 if (!document.read (filename)) {
882 throw failed_constructor ();
885 document.set_filename (filename);
886 set_state (document, *document.root());
890 MIDINameDocument::set_state (const XMLTree& tree, const XMLNode&)
894 boost::shared_ptr<XMLSharedNodeList> author = tree.find("//Author");
895 if (author->size() < 1) {
896 error << "No author information in MIDNAM file" << endmsg;
900 if (author->front()->children().size() > 0) {
901 _author = author->front()->children().front()->content();
906 boost::shared_ptr<XMLSharedNodeList> master_device_names_list = tree.find ("//MasterDeviceNames");
908 for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
909 i != master_device_names_list->end();
911 boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
913 if (master_device_names->set_state(tree, *(*i))) {
917 for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
918 model != master_device_names->models().end();
920 _master_device_names_list.insert(
921 std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
922 (*model, master_device_names));
924 _all_models.insert(*model);
932 MIDINameDocument::get_state(void)
934 static XMLNode nothing("<nothing>");
938 boost::shared_ptr<MasterDeviceNames>
939 MIDINameDocument::master_device_names(const std::string& model)
941 MasterDeviceNamesList::const_iterator m = _master_device_names_list.find(model);
942 if (m != _master_device_names_list.end()) {
943 return boost::shared_ptr<MasterDeviceNames>(m->second);
945 return boost::shared_ptr<MasterDeviceNames>();
948 const char* general_midi_program_names[128] = {
949 "Acoustic Grand Piano",
950 "Bright Acoustic Piano",
951 "Electric Grand Piano",
973 "Acoustic Guitar (nylon)",
974 "Acoustic Guitar (steel)",
975 "Electric Guitar (jazz)",
976 "Electric Guitar (clean)",
977 "Electric Guitar (muted)",
982 "Electric Bass (finger)",
983 "Electric Bass (pick)",
1030 "Lead 2 (sawtooth)",
1031 "Lead 3 (calliope lead)",
1032 "Lead 4 (chiff lead)",
1036 "Lead 8 (bass + lead)",
1039 "Pad 3 (polysynth)",
1046 "FX 2 (soundtrack)",
1048 "FX 4 (atmosphere)",
1049 "FX 5 (brightness)",
1069 "Guitar Fret Noise",