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)
45 int initialize_primary_key_from_commands (PatchPrimaryKey& id, const XMLNode* node)
47 const XMLNodeList events = node->children();
48 for (XMLNodeList::const_iterator i = events.begin(); i != events.end(); ++i) {
50 if (node->name() == "ControlChange") {
51 string control = node->property("Control")->value();
52 assert(control != "");
53 string value = node->property("Value")->value();
59 id.bank_number |= (PBD::atoi (value)<<7);
60 } else if (control == "32") {
61 id.bank_number |= PBD::atoi (value);
63 } else if (node->name() == "ProgramChange") {
64 string number = node->property("Number")->value();
66 id.program_number = PBD::atoi(number);
74 Patch::get_state (void)
76 XMLNode* node = new XMLNode("Patch");
78 /* XXX this is totally wrong */
80 node->add_property("Number", string_compose ("%1", _id.program_number));
81 node->add_property("Name", _name);
84 typedef std::list< boost::shared_ptr< Evoral::MIDIEvent<double> > > PatchMidiCommands;
85 XMLNode* commands = node->add_child("PatchMIDICommands");
86 for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
87 event != _patch_midi_commands.end();
89 commands->add_child_copy(*((((Evoral::MIDIEvent&)*event)).to_xml()));
97 Patch::set_state (const XMLTree&, const XMLNode& node)
99 if (node.name() != "Patch") {
100 cerr << "Incorrect node " << node.name() << " handed to Patch" << endl;
104 const XMLProperty* prop = node.property ("Number");
109 _id.program_number = PBD::atoi (prop->value());
111 prop = node.property ("Name");
116 _name = prop->value();
118 XMLNode* commands = node.child("PatchMIDICommands");
121 if (initialize_primary_key_from_commands(_id, commands)) {
125 string program_change = node.property("ProgramChange")->value();
126 assert(program_change.length());
127 _id.program_number = PBD::atoi(program_change);
135 Note::get_state (void)
137 XMLNode* node = new XMLNode("Note");
138 node->add_property("Number", _number);
139 node->add_property("Name", _name);
146 Note::set_state (const XMLTree&, const XMLNode& node)
148 assert(node.name() == "Note");
149 _number = node.property("Number")->value();
150 _name = node.property("Name")->value();
156 NoteNameList::get_state (void)
158 XMLNode* node = new XMLNode("NoteNameList");
159 node->add_property("Name", _name);
165 NoteNameList::set_state (const XMLTree& tree, const XMLNode& node)
167 assert(node.name() == "NoteNameList");
168 _name = node.property("Name")->value();
170 boost::shared_ptr<XMLSharedNodeList> notes = tree.find("//Note");
171 for (XMLSharedNodeList::const_iterator i = notes->begin(); i != notes->end(); ++i) {
172 boost::shared_ptr<Note> note(new Note());
173 note->set_state (tree, *(*i));
174 _notes.push_back(note);
182 PatchBank::get_state (void)
184 XMLNode* node = new XMLNode("PatchBank");
185 node->add_property("Name", _name);
186 XMLNode* patch_name_list = node->add_child("PatchNameList");
187 for (PatchNameList::iterator patch = _patch_name_list.begin();
188 patch != _patch_name_list.end();
190 patch_name_list->add_child_nocopy((*patch)->get_state());
197 PatchBank::set_state (const XMLTree& tree, const XMLNode& node)
199 assert(node.name() == "PatchBank");
200 _name = node.property("Name")->value();
202 XMLNode* commands = node.child("MIDICommands");
204 PatchPrimaryKey id (0, 0);
205 if (initialize_primary_key_from_commands (id, commands)) {
208 _number = id.bank_number;
211 XMLNode* patch_name_list = node.child("PatchNameList");
213 if (patch_name_list) {
214 const XMLNodeList patches = patch_name_list->children();
215 for (XMLNodeList::const_iterator i = patches.begin(); i != patches.end(); ++i) {
216 boost::shared_ptr<Patch> patch (new Patch (string(), 0, _number));
217 patch->set_state(tree, *(*i));
218 _patch_name_list.push_back(patch);
221 XMLNode* use_patch_name_list = node.child ("UsesPatchNameList");
222 if (use_patch_name_list) {
223 _patch_list_name = use_patch_name_list->property ("Name")->value();
225 error << "Patch without patch name list - patchfile will be ignored" << endmsg;
234 PatchBank::set_patch_name_list (const PatchNameList& pnl)
236 _patch_name_list = pnl;
237 _patch_list_name = "";
239 for (PatchNameList::iterator p = _patch_name_list.begin(); p != _patch_name_list.end(); p++) {
240 (*p)->set_bank_number (_number);
247 ChannelNameSet::set_patch_banks (const ChannelNameSet::PatchBanks& pb)
252 _patch_list.clear ();
253 _patch_list_name = "";
254 _available_for_channels.clear ();
256 for (PatchBanks::const_iterator pbi = _patch_banks.begin(); pbi != _patch_banks.end(); ++pbi) {
257 for (PatchBank::PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
258 _patch_map[(*pni)->patch_primary_key()] = (*pni);
259 _patch_list.push_back ((*pni)->patch_primary_key());
263 for (uint8_t n = 0; n < 16; ++n) {
264 _available_for_channels.insert (n);
269 ChannelNameSet::get_state (void)
271 XMLNode* node = new XMLNode("ChannelNameSet");
272 node->add_property("Name", _name);
274 XMLNode* available_for_channels = node->add_child("AvailableForChannels");
275 assert(available_for_channels);
277 for (uint8_t channel = 0; channel < 16; ++channel) {
278 XMLNode* available_channel = available_for_channels->add_child("AvailableChannel");
279 assert(available_channel);
281 available_channel->add_property("Channel", (long) channel);
283 if (_available_for_channels.find(channel) != _available_for_channels.end()) {
284 available_channel->add_property("Available", "true");
286 available_channel->add_property("Available", "false");
290 for (PatchBanks::iterator patch_bank = _patch_banks.begin();
291 patch_bank != _patch_banks.end();
293 node->add_child_nocopy((*patch_bank)->get_state());
300 ChannelNameSet::set_state (const XMLTree& tree, const XMLNode& node)
302 assert(node.name() == "ChannelNameSet");
303 _name = node.property("Name")->value();
304 const XMLNodeList children = node.children();
305 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
308 if (node->name() == "AvailableForChannels") {
309 boost::shared_ptr<XMLSharedNodeList> channels =
310 tree.find("//AvailableChannel[@Available = 'true']/@Channel");
311 for(XMLSharedNodeList::const_iterator i = channels->begin();
312 i != channels->end();
314 _available_for_channels.insert(atoi((*i)->attribute_value().c_str()));
318 if (node->name() == "PatchBank") {
319 boost::shared_ptr<PatchBank> bank (new PatchBank ());
320 bank->set_state(tree, *node);
321 _patch_banks.push_back(bank);
322 const PatchBank::PatchNameList& patches = bank->patch_name_list();
323 for (PatchBank::PatchNameList::const_iterator patch = patches.begin();
324 patch != patches.end();
326 _patch_map[(*patch)->patch_primary_key()] = *patch;
327 _patch_list.push_back((*patch)->patch_primary_key());
336 CustomDeviceMode::set_state(const XMLTree& tree, const XMLNode& a_node)
338 assert(a_node.name() == "CustomDeviceMode");
340 _name = a_node.property("Name")->value();
342 boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
343 tree.find("//ChannelNameSetAssign");
344 for(XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
345 i != channel_name_set_assignments->end();
347 int channel = atoi((*i)->property("Channel")->value().c_str());
348 string name_set = (*i)->property("NameSet")->value();
349 assert( 1 <= channel && channel <= 16 );
350 _channel_name_set_assignments[channel - 1] = name_set;
356 CustomDeviceMode::get_state(void)
358 XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
359 custom_device_mode->add_property("Name", _name);
360 XMLNode* channel_name_set_assignments =
361 custom_device_mode->add_child("ChannelNameSetAssignments");
362 for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
363 XMLNode* channel_name_set_assign =
364 channel_name_set_assignments->add_child("ChannelNameSetAssign");
365 channel_name_set_assign->add_property("Channel", i + 1);
366 channel_name_set_assign->add_property("NameSet", _channel_name_set_assignments[i]);
369 return *custom_device_mode;
373 MasterDeviceNames::set_state(const XMLTree& tree, const XMLNode& a_node)
376 boost::shared_ptr<XMLSharedNodeList> manufacturer = tree.find("//Manufacturer");
377 assert(manufacturer->size() == 1);
378 _manufacturer = manufacturer->front()->content();
381 boost::shared_ptr<XMLSharedNodeList> models = tree.find("//Model");
382 assert(models->size() >= 1);
383 for (XMLSharedNodeList::iterator i = models->begin();
386 const XMLNodeList& contents = (*i)->children();
387 assert(contents.size() == 1);
388 XMLNode * content = *(contents.begin());
389 assert(content->is_content());
390 _models.push_back(content->content());
394 boost::shared_ptr<XMLSharedNodeList> custom_device_modes = tree.find("//CustomDeviceMode");
395 for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
396 i != custom_device_modes->end();
398 boost::shared_ptr<CustomDeviceMode> custom_device_mode(new CustomDeviceMode());
399 custom_device_mode->set_state(tree, *(*i));
401 _custom_device_modes[custom_device_mode->name()] = custom_device_mode;
402 _custom_device_mode_names.push_back(custom_device_mode->name());
406 boost::shared_ptr<XMLSharedNodeList> channel_name_sets = tree.find("//ChannelNameSet");
407 for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
408 i != channel_name_sets->end();
410 boost::shared_ptr<ChannelNameSet> channel_name_set(new ChannelNameSet());
411 channel_name_set->set_state(tree, *(*i));
412 _channel_name_sets[channel_name_set->name()] = channel_name_set;
416 boost::shared_ptr<XMLSharedNodeList> note_name_lists = tree.find("//NoteNameList");
417 for (XMLSharedNodeList::iterator i = note_name_lists->begin();
418 i != note_name_lists->end();
420 boost::shared_ptr<NoteNameList> note_name_list(new NoteNameList());
421 note_name_list->set_state (tree, *(*i));
422 _note_name_lists.push_back(note_name_list);
425 // global/post-facto PatchNameLists
426 boost::shared_ptr<XMLSharedNodeList> patch_name_lists = tree.find("/child::MIDINameDocument/child::MasterDeviceNames/child::PatchNameList");
427 for (XMLSharedNodeList::iterator i = patch_name_lists->begin();
428 i != patch_name_lists->end();
431 PatchBank::PatchNameList patch_name_list;
432 const XMLNodeList patches = (*i)->children();
434 for (XMLNodeList::const_iterator p = patches.begin(); p != patches.end(); ++p) {
435 boost::shared_ptr<Patch> patch (new Patch ());
436 patch->set_state(tree, *(*p));
437 patch_name_list.push_back(patch);
440 if (!patch_name_list.empty()) {
441 _patch_name_lists[(*i)->property ("Name")->value()] = patch_name_list;
445 /* now traverse patches and hook up anything that used UsePatchNameList
446 * to the right patch list
449 for (ChannelNameSets::iterator cns = _channel_name_sets.begin(); cns != _channel_name_sets.end(); ++cns) {
450 ChannelNameSet::PatchBanks pbs = cns->second->patch_banks();
451 for (ChannelNameSet::PatchBanks::iterator pb = pbs.begin(); pb != pbs.end(); ++pb) {
452 std::string pln = (*pb)->patch_list_name();
454 PatchNameLists::iterator p = _patch_name_lists.find (pln);
455 if (p != _patch_name_lists.end()) {
456 if ((*pb)->set_patch_name_list (p->second)) {
460 error << string_compose ("Patch list name %1 was not found - patch file ignored", pln) << endmsg;
471 MasterDeviceNames::get_state(void)
473 static XMLNode nothing("<nothing>");
477 MIDINameDocument::MIDINameDocument (const string& filename)
479 if (!_document.read (filename)) {
480 throw failed_constructor ();
483 set_state (_document, *_document.root());
487 MIDINameDocument::set_state (const XMLTree& tree, const XMLNode& a_node)
491 boost::shared_ptr<XMLSharedNodeList> author = tree.find("//Author");
492 if (author->size() < 1) {
493 error << "No author information in MIDNAM file" << endmsg;
496 _author = author->front()->content();
500 boost::shared_ptr<XMLSharedNodeList> master_device_names_list = tree.find ("//MasterDeviceNames");
502 for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
503 i != master_device_names_list->end();
505 boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
507 if (master_device_names->set_state(tree, *(*i))) {
511 for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
512 model != master_device_names->models().end();
514 _master_device_names_list.insert(
515 std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
516 (*model, master_device_names));
518 _all_models.push_back(*model);
526 MIDINameDocument::get_state(void)
528 static XMLNode nothing("<nothing>");
532 const char* general_midi_program_names[128] = {
533 "Acoustic Grand Piano",
534 "Bright Acoustic Piano",
535 "Electric Grand Piano",
557 "Acoustic Guitar (nylon)",
558 "Acoustic Guitar (steel)",
559 "Electric Guitar (jazz)",
560 "Electric Guitar (clean)",
561 "Electric Guitar (muted)",
566 "Electric Bass (finger)",
567 "Electric Bass (pick)",
615 "Lead 3 (calliope lead)",
616 "Lead 4 (chiff lead)",
620 "Lead 8 (bass + lead)",