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<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::MIDIXML::midi_to_xml(*event));
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->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 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->set_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->set_property("Channel", channel);
538 if (_available_for_channels.find(channel) != _available_for_channels.end()) {
539 available_channel->set_property("Available", "true");
541 available_channel->set_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();
571 _available_for_channels.insert(
572 string_to_int(tree, (*i)->attribute_value()));
573 } catch (XMLException &e) {
574 cerr << "ChannelNameSet::set_state: " << e.what () << endl;
577 } else if (node->name() == "PatchBank") {
578 boost::shared_ptr<PatchBank> bank (new PatchBank ());
579 bank->set_state(tree, *node);
580 _patch_banks.push_back(bank);
581 const PatchNameList& patches = bank->patch_name_list();
582 for (PatchNameList::const_iterator patch = patches.begin();
583 patch != patches.end();
585 _patch_map[(*patch)->patch_primary_key()] = *patch;
586 _patch_list.push_back((*patch)->patch_primary_key());
588 } else if (node->name() == "UsesNoteNameList") {
589 _note_list_name = node->property ("Name")->value();
590 } else if (node->name() == "UsesControlNameList") {
591 _control_list_name = node->property ("Name")->value();
599 CustomDeviceMode::set_state(const XMLTree& tree, const XMLNode& a_node)
601 assert(a_node.name() == "CustomDeviceMode");
603 _name = a_node.property("Name")->value();
605 boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
606 tree.find("//ChannelNameSetAssign", const_cast<XMLNode *>(&a_node));
607 for (XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
608 i != channel_name_set_assignments->end();
610 const int channel = string_to_int(tree, (*i)->property("Channel")->value());
611 const string& name_set = (*i)->property("NameSet")->value();
612 assert( 1 <= channel && channel <= 16 );
613 _channel_name_set_assignments[channel - 1] = name_set;
619 CustomDeviceMode::get_state(void)
621 XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
622 custom_device_mode->set_property("Name", _name);
623 XMLNode* channel_name_set_assignments =
624 custom_device_mode->add_child("ChannelNameSetAssignments");
625 for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
626 XMLNode* channel_name_set_assign =
627 channel_name_set_assignments->add_child("ChannelNameSetAssign");
628 channel_name_set_assign->set_property("Channel", i + 1);
629 channel_name_set_assign->set_property("NameSet", _channel_name_set_assignments[i]);
632 return *custom_device_mode;
635 boost::shared_ptr<const ValueNameList>
636 MasterDeviceNames::value_name_list_by_control(const std::string& mode, uint8_t channel, uint8_t number)
638 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(mode, channel);
640 return boost::shared_ptr<const ValueNameList>();
643 boost::shared_ptr<ControlNameList> control_names = control_name_list(chan_names->control_list_name());
644 if (!control_names) {
645 return boost::shared_ptr<const ValueNameList>();
648 boost::shared_ptr<const Control> control = control_names->control(number);
650 return boost::shared_ptr<const ValueNameList>();
653 if (!control->value_name_list_name().empty()) {
654 return value_name_list(control->value_name_list_name());
656 return control->value_name_list();
660 boost::shared_ptr<CustomDeviceMode>
661 MasterDeviceNames::custom_device_mode_by_name(const std::string& mode_name)
663 return _custom_device_modes[mode_name];
666 boost::shared_ptr<ChannelNameSet>
667 MasterDeviceNames::channel_name_set_by_channel(const std::string& mode, uint8_t channel)
669 boost::shared_ptr<CustomDeviceMode> cdm = custom_device_mode_by_name(mode);
670 boost::shared_ptr<ChannelNameSet> cns = _channel_name_sets[cdm->channel_name_set_name_by_channel(channel)];
674 boost::shared_ptr<Patch>
675 MasterDeviceNames::find_patch(const std::string& mode, uint8_t channel, const PatchPrimaryKey& key)
677 boost::shared_ptr<ChannelNameSet> cns = channel_name_set_by_channel(mode, channel);
678 if (!cns) return boost::shared_ptr<Patch>();
679 return cns->find_patch(key);
682 boost::shared_ptr<ChannelNameSet>
683 MasterDeviceNames::channel_name_set(const std::string& name)
685 ChannelNameSets::const_iterator i = _channel_name_sets.find(name);
686 if (i != _channel_name_sets.end()) {
689 return boost::shared_ptr<ChannelNameSet>();
692 boost::shared_ptr<ControlNameList>
693 MasterDeviceNames::control_name_list(const std::string& name)
695 ControlNameLists::const_iterator i = _control_name_lists.find(name);
696 if (i != _control_name_lists.end()) {
699 return boost::shared_ptr<ControlNameList>();
702 boost::shared_ptr<ValueNameList>
703 MasterDeviceNames::value_name_list(const std::string& name)
705 ValueNameLists::const_iterator i = _value_name_lists.find(name);
706 if (i != _value_name_lists.end()) {
709 return boost::shared_ptr<ValueNameList>();
712 boost::shared_ptr<NoteNameList>
713 MasterDeviceNames::note_name_list(const std::string& name)
715 NoteNameLists::const_iterator i = _note_name_lists.find(name);
716 if (i != _note_name_lists.end()) {
719 return boost::shared_ptr<NoteNameList>();
723 MasterDeviceNames::note_name(const std::string& mode_name,
733 boost::shared_ptr<const NoteNameList> note_names;
734 boost::shared_ptr<const Patch> patch(
735 find_patch(mode_name, channel, PatchPrimaryKey(program, bank)));
737 note_names = note_name_list(patch->note_list_name());
741 /* No note names specific to this patch, check the ChannelNameSet */
742 boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(
745 note_names = note_name_list(chan_names->note_list_name());
752 boost::shared_ptr<const Note> note(note_names->notes()[number]);
753 return note ? note->name() : "";
757 MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode&)
760 boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer");
761 assert(manufacturer->size() == 1);
762 _manufacturer = manufacturer->front()->children().front()->content();
765 boost::shared_ptr<XMLSharedNodeList> models = tree.find("//Model");
766 assert(models->size() >= 1);
767 for (XMLSharedNodeList::iterator i = models->begin();
770 const XMLNodeList& contents = (*i)->children();
771 assert(contents.size() == 1);
772 XMLNode * content = *(contents.begin());
773 assert(content->is_content());
774 _models.insert(content->content());
778 boost::shared_ptr<XMLSharedNodeList> custom_device_modes = tree.find("//CustomDeviceMode");
779 for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
780 i != custom_device_modes->end();
782 boost::shared_ptr<CustomDeviceMode> custom_device_mode(new CustomDeviceMode());
783 custom_device_mode->set_state(tree, *(*i));
785 _custom_device_modes[custom_device_mode->name()] = custom_device_mode;
786 _custom_device_mode_names.push_back(custom_device_mode->name());
790 boost::shared_ptr<XMLSharedNodeList> channel_name_sets = tree.find("//ChannelNameSet");
791 for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
792 i != channel_name_sets->end();
794 boost::shared_ptr<ChannelNameSet> channel_name_set(new ChannelNameSet());
795 channel_name_set->set_state(tree, *(*i));
796 _channel_name_sets[channel_name_set->name()] = channel_name_set;
800 boost::shared_ptr<XMLSharedNodeList> note_name_lists = tree.find("//NoteNameList");
801 for (XMLSharedNodeList::iterator i = note_name_lists->begin();
802 i != note_name_lists->end();
804 boost::shared_ptr<NoteNameList> note_name_list(new NoteNameList());
805 note_name_list->set_state (tree, *(*i));
806 _note_name_lists[note_name_list->name()] = note_name_list;
810 boost::shared_ptr<XMLSharedNodeList> control_name_lists = tree.find("//ControlNameList");
811 for (XMLSharedNodeList::iterator i = control_name_lists->begin();
812 i != control_name_lists->end();
814 boost::shared_ptr<ControlNameList> control_name_list(new ControlNameList());
815 control_name_list->set_state (tree, *(*i));
816 _control_name_lists[control_name_list->name()] = control_name_list;
820 boost::shared_ptr<XMLSharedNodeList> value_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::ValueNameList");
821 for (XMLSharedNodeList::iterator i = value_name_lists->begin();
822 i != value_name_lists->end();
824 boost::shared_ptr<ValueNameList> value_name_list(new ValueNameList());
825 value_name_list->set_state (tree, *(*i));
826 _value_name_lists[value_name_list->name()] = value_name_list;
829 // global/post-facto PatchNameLists
830 boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList");
831 for (XMLSharedNodeList::iterator i = patch_name_lists->begin();
832 i != patch_name_lists->end();
835 PatchNameList patch_name_list;
836 const XMLNodeList patches = (*i)->children();
838 for (XMLNodeList::const_iterator p = patches.begin(); p != patches.end(); ++p) {
839 boost::shared_ptr<Patch> patch (new Patch ());
840 patch->set_state(tree, *(*p));
841 patch_name_list.push_back(patch);
844 if (!patch_name_list.empty()) {
845 _patch_name_lists[(*i)->property ("Name")->value()] = patch_name_list;
849 /* now traverse patches and hook up anything that used UsePatchNameList
850 * to the right patch list
853 for (ChannelNameSets::iterator cns = _channel_name_sets.begin(); cns != _channel_name_sets.end(); ++cns) {
854 ChannelNameSet::PatchBanks pbs = cns->second->patch_banks();
855 PatchNameLists::iterator p;
857 for (ChannelNameSet::PatchBanks::iterator pb = pbs.begin(); pb != pbs.end(); ++pb) {
858 const std::string& pln = (*pb)->patch_list_name();
860 if ((p = _patch_name_lists.find (pln)) != _patch_name_lists.end()) {
861 if ((*pb)->set_patch_name_list (p->second)) {
864 cns->second->use_patch_name_list (p->second);
866 error << string_compose ("Patch list name %1 was not found - patch file ignored", pln) << endmsg;
878 MasterDeviceNames::get_state(void)
880 static XMLNode nothing("<nothing>");
884 MIDINameDocument::MIDINameDocument (const string& file_path)
885 : _file_path(file_path)
888 if (!document.read (file_path)) {
889 throw failed_constructor ();
892 document.set_filename (file_path);
893 set_state (document, *document.root());
897 MIDINameDocument::set_state (const XMLTree& tree, const XMLNode&)
901 boost::shared_ptr<XMLSharedNodeList> author = tree.find("//Author");
902 if (author->size() < 1) {
903 error << "No author information in MIDNAM file" << endmsg;
907 if (author->front()->children().size() > 0) {
908 _author = author->front()->children().front()->content();
913 boost::shared_ptr<XMLSharedNodeList> master_device_names_list = tree.find ("//MasterDeviceNames");
915 for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
916 i != master_device_names_list->end();
918 boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
920 if (master_device_names->set_state(tree, *(*i))) {
924 for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
925 model != master_device_names->models().end();
927 _master_device_names_list.insert(
928 std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
929 (*model, master_device_names));
931 _all_models.insert(*model);
939 MIDINameDocument::get_state(void)
941 static XMLNode nothing("<nothing>");
945 boost::shared_ptr<MasterDeviceNames>
946 MIDINameDocument::master_device_names(const std::string& model)
948 MasterDeviceNamesList::const_iterator m = _master_device_names_list.find(model);
949 if (m != _master_device_names_list.end()) {
950 return boost::shared_ptr<MasterDeviceNames>(m->second);
952 return boost::shared_ptr<MasterDeviceNames>();
955 const char* general_midi_program_names[128] = {
956 "Acoustic Grand Piano",
957 "Bright Acoustic Piano",
958 "Electric Grand Piano",
980 "Acoustic Guitar (nylon)",
981 "Acoustic Guitar (steel)",
982 "Electric Guitar (jazz)",
983 "Electric Guitar (clean)",
984 "Electric Guitar (muted)",
989 "Electric Bass (finger)",
990 "Electric Bass (pick)",
1001 "Pizzicato Strings",
1004 "String Ensemble 1",
1005 "String Ensemble 2",
1037 "Lead 2 (sawtooth)",
1038 "Lead 3 (calliope lead)",
1039 "Lead 4 (chiff lead)",
1043 "Lead 8 (bass + lead)",
1046 "Pad 3 (polysynth)",
1053 "FX 2 (soundtrack)",
1055 "FX 4 (atmosphere)",
1056 "FX 5 (brightness)",
1076 "Guitar Fret Noise",