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->add_property("Number", string_compose ("%1", _id.program()));
97 node->add_property("Name", _name);
100 typedef std::list< boost::shared_ptr< Evoral::MIDIEvent<Evoral::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::MIDIEvent&)*event)).to_xml()));
113 Patch::set_state (const XMLTree& tree, const XMLNode& node)
115 if (node.name() != "Patch") {
116 cerr << "Incorrect node " << 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->add_property("Number", _number);
155 node->add_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->add_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->add_property("Type", _type);
238 node->add_property("Number", _number);
239 node->add_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->add_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->add_property("Number", _number);
324 node->add_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->add_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->add_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 patch->set_state(tree, *(*i));
441 _patch_name_list.push_back(patch);
444 XMLNode* use_patch_name_list = node.child ("UsesPatchNameList");
445 if (use_patch_name_list) {
446 _patch_list_name = use_patch_name_list->property ("Name")->value();
448 error << "Patch without patch name list - patchfile will be ignored" << endmsg;
457 PatchBank::set_patch_name_list (const PatchNameList& pnl)
459 _patch_name_list = pnl;
460 _patch_list_name = "";
462 for (PatchNameList::iterator p = _patch_name_list.begin(); p != _patch_name_list.end(); p++) {
463 (*p)->set_bank_number (_number);
470 operator<< (std::ostream& os, const ChannelNameSet& cns)
472 os << "Channel Name Set: name = " << cns._name << endl
473 << "Map size " << cns._patch_map.size () << endl
474 << "List size " << cns._patch_list.size() << endl
475 << "Patch list name = [" << cns._patch_list_name << ']' << endl
476 << "Available channels : ";
477 for (set<uint8_t>::const_iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) {
478 os << (int) (*x) << ' ';
482 for (ChannelNameSet::PatchBanks::const_iterator pbi = cns._patch_banks.begin(); pbi != cns._patch_banks.end(); ++pbi) {
483 os << "\tPatch Bank " << (*pbi)->name() << " with " << (*pbi)->patch_name_list().size() << " patches\n";
484 for (PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
485 os << "\t\tPatch name " << (*pni)->name() << " prog " << (int) (*pni)->program_number() << " bank " << (*pni)->bank_number() << endl;
493 ChannelNameSet::set_patch_banks (const ChannelNameSet::PatchBanks& pb)
498 _patch_list.clear ();
499 _patch_list_name = "";
500 _available_for_channels.clear ();
502 for (PatchBanks::const_iterator pbi = _patch_banks.begin(); pbi != _patch_banks.end(); ++pbi) {
503 for (PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
504 _patch_map[(*pni)->patch_primary_key()] = (*pni);
505 _patch_list.push_back ((*pni)->patch_primary_key());
509 for (uint8_t n = 0; n < 16; ++n) {
510 _available_for_channels.insert (n);
515 ChannelNameSet::use_patch_name_list (const PatchNameList& pnl)
517 for (PatchNameList::const_iterator p = pnl.begin(); p != pnl.end(); ++p) {
518 _patch_map[(*p)->patch_primary_key()] = (*p);
519 _patch_list.push_back ((*p)->patch_primary_key());
524 ChannelNameSet::get_state (void)
526 XMLNode* node = new XMLNode("ChannelNameSet");
527 node->add_property("Name", _name);
529 XMLNode* available_for_channels = node->add_child("AvailableForChannels");
530 assert(available_for_channels);
532 for (uint8_t channel = 0; channel < 16; ++channel) {
533 XMLNode* available_channel = available_for_channels->add_child("AvailableChannel");
534 assert(available_channel);
536 available_channel->add_property("Channel", (long) channel);
538 if (_available_for_channels.find(channel) != _available_for_channels.end()) {
539 available_channel->add_property("Available", "true");
541 available_channel->add_property("Available", "false");
545 for (PatchBanks::iterator patch_bank = _patch_banks.begin();
546 patch_bank != _patch_banks.end();
548 node->add_child_nocopy((*patch_bank)->get_state());
555 ChannelNameSet::set_state (const XMLTree& tree, const XMLNode& node)
557 assert(node.name() == "ChannelNameSet");
558 _name = node.property("Name")->value();
560 const XMLNodeList children = node.children();
561 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
564 if (node->name() == "AvailableForChannels") {
565 boost::shared_ptr<XMLSharedNodeList> channels =
566 tree.find("//AvailableChannel[@Available = 'true']/@Channel", node);
567 for (XMLSharedNodeList::const_iterator i = channels->begin();
568 i != channels->end();
570 _available_for_channels.insert(
571 string_to_int(tree, (*i)->attribute_value()));
573 } else if (node->name() == "PatchBank") {
574 boost::shared_ptr<PatchBank> bank (new PatchBank ());
575 bank->set_state(tree, *node);
576 _patch_banks.push_back(bank);
577 const PatchNameList& patches = bank->patch_name_list();
578 for (PatchNameList::const_iterator patch = patches.begin();
579 patch != patches.end();
581 _patch_map[(*patch)->patch_primary_key()] = *patch;
582 _patch_list.push_back((*patch)->patch_primary_key());
584 } else if (node->name() == "UsesNoteNameList") {
585 _note_list_name = node->property ("Name")->value();
586 } else if (node->name() == "UsesControlNameList") {
587 _control_list_name = node->property ("Name")->value();
595 CustomDeviceMode::set_state(const XMLTree& tree, const XMLNode& a_node)
597 assert(a_node.name() == "CustomDeviceMode");
599 _name = a_node.property("Name")->value();
601 boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
602 tree.find("//ChannelNameSetAssign", const_cast<XMLNode *>(&a_node));
603 for (XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
604 i != channel_name_set_assignments->end();
606 const int channel = string_to_int(tree, (*i)->property("Channel")->value());
607 const string& name_set = (*i)->property("NameSet")->value();
608 assert( 1 <= channel && channel <= 16 );
609 _channel_name_set_assignments[channel - 1] = name_set;
615 CustomDeviceMode::get_state(void)
617 XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
618 custom_device_mode->add_property("Name", _name);
619 XMLNode* channel_name_set_assignments =
620 custom_device_mode->add_child("ChannelNameSetAssignments");
621 for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
622 XMLNode* channel_name_set_assign =
623 channel_name_set_assignments->add_child("ChannelNameSetAssign");
624 channel_name_set_assign->add_property("Channel", i + 1);
625 channel_name_set_assign->add_property("NameSet", _channel_name_set_assignments[i]);
628 return *custom_device_mode;
631 boost::shared_ptr<const ValueNameList>
632 MasterDeviceNames::value_name_list_by_control(const std::string& mode, uint8_t channel, uint8_t number)
634 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(mode, channel);
636 return boost::shared_ptr<const ValueNameList>();
639 boost::shared_ptr<ControlNameList> control_names = control_name_list(chan_names->control_list_name());
640 if (!control_names) {
641 return boost::shared_ptr<const ValueNameList>();
644 boost::shared_ptr<const Control> control = control_names->control(number);
646 return boost::shared_ptr<const ValueNameList>();
649 if (!control->value_name_list_name().empty()) {
650 return value_name_list(control->value_name_list_name());
652 return control->value_name_list();
656 boost::shared_ptr<CustomDeviceMode>
657 MasterDeviceNames::custom_device_mode_by_name(const std::string& mode_name)
659 return _custom_device_modes[mode_name];
662 boost::shared_ptr<ChannelNameSet>
663 MasterDeviceNames::channel_name_set_by_channel(const std::string& mode, uint8_t channel)
665 boost::shared_ptr<CustomDeviceMode> cdm = custom_device_mode_by_name(mode);
666 boost::shared_ptr<ChannelNameSet> cns = _channel_name_sets[cdm->channel_name_set_name_by_channel(channel)];
670 boost::shared_ptr<Patch>
671 MasterDeviceNames::find_patch(const std::string& mode, uint8_t channel, const PatchPrimaryKey& key)
673 boost::shared_ptr<ChannelNameSet> cns = channel_name_set_by_channel(mode, channel);
674 if (!cns) return boost::shared_ptr<Patch>();
675 return cns->find_patch(key);
678 boost::shared_ptr<ChannelNameSet>
679 MasterDeviceNames::channel_name_set(const std::string& name)
681 ChannelNameSets::const_iterator i = _channel_name_sets.find(name);
682 if (i != _channel_name_sets.end()) {
685 return boost::shared_ptr<ChannelNameSet>();
688 boost::shared_ptr<ControlNameList>
689 MasterDeviceNames::control_name_list(const std::string& name)
691 ControlNameLists::const_iterator i = _control_name_lists.find(name);
692 if (i != _control_name_lists.end()) {
695 return boost::shared_ptr<ControlNameList>();
698 boost::shared_ptr<ValueNameList>
699 MasterDeviceNames::value_name_list(const std::string& name)
701 ValueNameLists::const_iterator i = _value_name_lists.find(name);
702 if (i != _value_name_lists.end()) {
705 return boost::shared_ptr<ValueNameList>();
708 boost::shared_ptr<NoteNameList>
709 MasterDeviceNames::note_name_list(const std::string& name)
711 NoteNameLists::const_iterator i = _note_name_lists.find(name);
712 if (i != _note_name_lists.end()) {
715 return boost::shared_ptr<NoteNameList>();
719 MasterDeviceNames::note_name(const std::string& mode_name,
729 boost::shared_ptr<const NoteNameList> note_names;
730 boost::shared_ptr<const Patch> patch(
731 find_patch(mode_name, channel, PatchPrimaryKey(program, bank)));
733 note_names = note_name_list(patch->note_list_name());
737 /* No note names specific to this patch, check the ChannelNameSet */
738 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(
741 note_names = note_name_list(chan_names->note_list_name());
748 boost::shared_ptr<const Note> note(note_names->notes()[number]);
749 return note ? note->name() : "";
753 MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode&)
756 boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer");
757 assert(manufacturer->size() == 1);
758 _manufacturer = manufacturer->front()->children().front()->content();
761 boost::shared_ptr<XMLSharedNodeList> models = tree.find("//Model");
762 assert(models->size() >= 1);
763 for (XMLSharedNodeList::iterator i = models->begin();
766 const XMLNodeList& contents = (*i)->children();
767 assert(contents.size() == 1);
768 XMLNode * content = *(contents.begin());
769 assert(content->is_content());
770 _models.insert(content->content());
774 boost::shared_ptr<XMLSharedNodeList> custom_device_modes = tree.find("//CustomDeviceMode");
775 for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
776 i != custom_device_modes->end();
778 boost::shared_ptr<CustomDeviceMode> custom_device_mode(new CustomDeviceMode());
779 custom_device_mode->set_state(tree, *(*i));
781 _custom_device_modes[custom_device_mode->name()] = custom_device_mode;
782 _custom_device_mode_names.push_back(custom_device_mode->name());
786 boost::shared_ptr<XMLSharedNodeList> channel_name_sets = tree.find("//ChannelNameSet");
787 for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
788 i != channel_name_sets->end();
790 boost::shared_ptr<ChannelNameSet> channel_name_set(new ChannelNameSet());
791 channel_name_set->set_state(tree, *(*i));
792 _channel_name_sets[channel_name_set->name()] = channel_name_set;
796 boost::shared_ptr<XMLSharedNodeList> note_name_lists = tree.find("//NoteNameList");
797 for (XMLSharedNodeList::iterator i = note_name_lists->begin();
798 i != note_name_lists->end();
800 boost::shared_ptr<NoteNameList> note_name_list(new NoteNameList());
801 note_name_list->set_state (tree, *(*i));
802 _note_name_lists[note_name_list->name()] = note_name_list;
806 boost::shared_ptr<XMLSharedNodeList> control_name_lists = tree.find("//ControlNameList");
807 for (XMLSharedNodeList::iterator i = control_name_lists->begin();
808 i != control_name_lists->end();
810 boost::shared_ptr<ControlNameList> control_name_list(new ControlNameList());
811 control_name_list->set_state (tree, *(*i));
812 _control_name_lists[control_name_list->name()] = control_name_list;
816 boost::shared_ptr<XMLSharedNodeList> value_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::ValueNameList");
817 for (XMLSharedNodeList::iterator i = value_name_lists->begin();
818 i != value_name_lists->end();
820 boost::shared_ptr<ValueNameList> value_name_list(new ValueNameList());
821 value_name_list->set_state (tree, *(*i));
822 _value_name_lists[value_name_list->name()] = value_name_list;
825 // global/post-facto PatchNameLists
826 boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList");
827 for (XMLSharedNodeList::iterator i = patch_name_lists->begin();
828 i != patch_name_lists->end();
831 PatchNameList patch_name_list;
832 const XMLNodeList patches = (*i)->children();
834 for (XMLNodeList::const_iterator p = patches.begin(); p != patches.end(); ++p) {
835 boost::shared_ptr<Patch> patch (new Patch ());
836 patch->set_state(tree, *(*p));
837 patch_name_list.push_back(patch);
840 if (!patch_name_list.empty()) {
841 _patch_name_lists[(*i)->property ("Name")->value()] = patch_name_list;
845 /* now traverse patches and hook up anything that used UsePatchNameList
846 * to the right patch list
849 for (ChannelNameSets::iterator cns = _channel_name_sets.begin(); cns != _channel_name_sets.end(); ++cns) {
850 ChannelNameSet::PatchBanks pbs = cns->second->patch_banks();
851 PatchNameLists::iterator p;
853 for (ChannelNameSet::PatchBanks::iterator pb = pbs.begin(); pb != pbs.end(); ++pb) {
854 const std::string& pln = (*pb)->patch_list_name();
856 if ((p = _patch_name_lists.find (pln)) != _patch_name_lists.end()) {
857 if ((*pb)->set_patch_name_list (p->second)) {
860 cns->second->use_patch_name_list (p->second);
862 error << string_compose ("Patch list name %1 was not found - patch file ignored", pln) << endmsg;
874 MasterDeviceNames::get_state(void)
876 static XMLNode nothing("<nothing>");
880 MIDINameDocument::MIDINameDocument (const string& file_path)
881 : _file_path(file_path)
884 if (!document.read (file_path)) {
885 throw failed_constructor ();
888 document.set_filename (file_path);
889 set_state (document, *document.root());
893 MIDINameDocument::set_state (const XMLTree& tree, const XMLNode&)
897 boost::shared_ptr<XMLSharedNodeList> author = tree.find("//Author");
898 if (author->size() < 1) {
899 error << "No author information in MIDNAM file" << endmsg;
903 if (author->front()->children().size() > 0) {
904 _author = author->front()->children().front()->content();
909 boost::shared_ptr<XMLSharedNodeList> master_device_names_list = tree.find ("//MasterDeviceNames");
911 for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
912 i != master_device_names_list->end();
914 boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
916 if (master_device_names->set_state(tree, *(*i))) {
920 for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
921 model != master_device_names->models().end();
923 _master_device_names_list.insert(
924 std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
925 (*model, master_device_names));
927 _all_models.insert(*model);
935 MIDINameDocument::get_state(void)
937 static XMLNode nothing("<nothing>");
941 boost::shared_ptr<MasterDeviceNames>
942 MIDINameDocument::master_device_names(const std::string& model)
944 MasterDeviceNamesList::const_iterator m = _master_device_names_list.find(model);
945 if (m != _master_device_names_list.end()) {
946 return boost::shared_ptr<MasterDeviceNames>(m->second);
948 return boost::shared_ptr<MasterDeviceNames>();
951 const char* general_midi_program_names[128] = {
952 "Acoustic Grand Piano",
953 "Bright Acoustic Piano",
954 "Electric Grand Piano",
976 "Acoustic Guitar (nylon)",
977 "Acoustic Guitar (steel)",
978 "Electric Guitar (jazz)",
979 "Electric Guitar (clean)",
980 "Electric Guitar (muted)",
985 "Electric Bass (finger)",
986 "Electric Bass (pick)",
1000 "String Ensemble 1",
1001 "String Ensemble 2",
1033 "Lead 2 (sawtooth)",
1034 "Lead 3 (calliope lead)",
1035 "Lead 4 (chiff lead)",
1039 "Lead 8 (bass + lead)",
1042 "Pad 3 (polysynth)",
1049 "FX 2 (soundtrack)",
1051 "FX 4 (atmosphere)",
1052 "FX 5 (brightness)",
1072 "Guitar Fret Noise",