* first working prototype of selecting instruments in the MIDI track header
[ardour.git] / libs / midi++2 / midnam_patch.cc
1 /*
2     Copyright (C) 2008 Hans Baier 
3
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.
8
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.
13
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.
17
18     $Id$
19 */
20
21 #include "midi++/midnam_patch.h"
22 #include <algorithm>
23
24 #include <iostream>
25
26 using namespace std;
27
28 namespace MIDI
29 {
30
31 namespace Name
32 {
33
34 XMLNode&
35 Patch::get_state (void)
36 {
37         XMLNode* node = new XMLNode("Patch");
38         node->add_property("Number", _number);
39         node->add_property("Name",   _name);
40         XMLNode* commands = node->add_child("PatchMIDICommands");
41         for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
42             event != _patch_midi_commands.end();
43             ++event) {
44                 commands->add_child_copy(*((((Evoral::MIDIEvent&)*event)).to_xml()));
45         }
46
47         return *node;
48 }
49
50 int
51 Patch::set_state (const XMLNode& node)
52 {
53         assert(node.name() == "Patch");
54         _number = node.property("Number")->value();
55         _name   = node.property("Name")->value();
56         XMLNode* commands = node.child("PatchMIDICommands");
57         assert(commands);
58         const XMLNodeList events = commands->children();
59         for (XMLNodeList::const_iterator i = events.begin(); i != events.end(); ++i) {
60                 _patch_midi_commands.push_back(*(new Evoral::MIDIEvent(*(*i))));
61         }
62
63         return 0;
64 }
65
66 XMLNode&
67 Note::get_state (void)
68 {
69         XMLNode* node = new XMLNode("Note");
70         node->add_property("Number", _number);
71         node->add_property("Name",   _name);
72
73         return *node;
74 }
75
76 int
77 Note::set_state (const XMLNode& node)
78 {
79         assert(node.name() == "Note");
80         _number = node.property("Number")->value();
81         _name   = node.property("Name")->value();
82
83         return 0;
84 }
85
86 XMLNode&
87 NoteNameList::get_state (void)
88 {
89         XMLNode* node = new XMLNode("NoteNameList");
90         node->add_property("Name",   _name);
91
92         return *node;
93 }
94
95 int
96 NoteNameList::set_state (const XMLNode& node)
97 {
98         assert(node.name() == "NoteNameList");
99         _name   = node.property("Name")->value();
100
101         boost::shared_ptr<XMLSharedNodeList> notes =
102                                         node.find("//Note");
103         for (XMLSharedNodeList::const_iterator i = notes->begin(); i != notes->end(); ++i) {
104                 Note* note = new Note();
105                 note->set_state(*(*i));
106                 _notes.push_back(*note);
107         }
108         
109         return 0;
110 }
111
112
113 XMLNode&
114 PatchBank::get_state (void)
115 {
116         XMLNode* node = new XMLNode("PatchBank");
117         node->add_property("Name",   _name);
118         XMLNode* patch_name_list = node->add_child("PatchNameList");
119         for (PatchNameList::iterator patch = _patch_name_list.begin();
120             patch != _patch_name_list.end();
121             ++patch) {
122                 patch_name_list->add_child_nocopy(patch->get_state());
123         }
124
125         return *node;
126 }
127
128 int
129 PatchBank::set_state (const XMLNode& node)
130 {
131         assert(node.name() == "PatchBank");
132         _name   = node.property("Name")->value();
133         XMLNode* patch_name_list = node.child("PatchNameList");
134         assert(patch_name_list);
135         const XMLNodeList patches = patch_name_list->children();
136         for (XMLNodeList::const_iterator i = patches.begin(); i != patches.end(); ++i) {
137                 Patch* patch = new Patch();
138                 patch->set_state(*(*i));
139                 _patch_name_list.push_back(*patch);
140         }
141
142         return 0;
143 }
144
145 XMLNode&
146 ChannelNameSet::get_state (void)
147 {
148         XMLNode* node = new XMLNode("ChannelNameSet");
149         node->add_property("Name",   _name);
150
151         XMLNode* available_for_channels = node->add_child("AvailableForChannels");
152         assert(available_for_channels);
153
154         for (uint8_t channel = 0; channel < 16; ++channel) {
155                 XMLNode* available_channel = available_for_channels->add_child("AvailableChannel");
156                 assert(available_channel);
157
158                 available_channel->add_property("Channel", (long) channel);
159
160                 if (_available_for_channels.find(channel) != _available_for_channels.end()) {
161                         available_channel->add_property("Available", "true");
162                 } else {
163                         available_channel->add_property("Available", "false");
164                 }
165         }
166
167         for (PatchBanks::iterator patch_bank = _patch_banks.begin();
168             patch_bank != _patch_banks.end();
169             ++patch_bank) {
170                 node->add_child_nocopy(patch_bank->get_state());
171         }
172
173         return *node;
174 }
175
176 int
177 ChannelNameSet::set_state (const XMLNode& node)
178 {
179         assert(node.name() == "ChannelNameSet");
180         _name   = node.property("Name")->value();
181         // cerr << "ChannelNameSet _name: " << _name << endl;
182         const XMLNodeList children = node.children();
183         for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
184                 XMLNode* node = *i;
185                 assert(node);
186                 if (node->name() == "AvailableForChannels") {
187                         // cerr << "AvailableForChannels" << endl;
188                         boost::shared_ptr<XMLSharedNodeList> channels =
189                                 node->find("//AvailableChannel[@Available = 'true']/@Channel");
190                         // cerr << "AvailableForChannels after find" << endl;
191                         for(XMLSharedNodeList::const_iterator i = channels->begin();
192                             i != channels->end();
193                             ++i) {
194                                 // cerr << "AvailableForChannels before insert" << endl;
195                                 _available_for_channels.insert(atoi((*i)->attribute_value().c_str()));
196                                 // cerr << "AvailableForChannels after insert" << endl;
197                         }
198                 }
199                 
200                 // cerr << "before PatchBank" << endl;
201
202                 if (node->name() == "PatchBank") {
203                         // cerr << "got PatchBank" << endl;
204                         PatchBank* bank = new PatchBank();
205                         bank->set_state(*node);
206                         _patch_banks.push_back(*bank);
207                         // cerr << "after PatchBank pushback" << endl;
208                 }
209         }
210         
211         // cerr << "ChannelnameSet done" << endl;
212
213         return 0;
214 }
215
216 int
217 CustomDeviceMode::set_state(const XMLNode& a_node)
218 {
219         assert(a_node.name() == "CustomDeviceMode");
220         boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
221                 a_node.find("//ChannelNameSetAssign");
222         for(XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
223             i != channel_name_set_assignments->end();
224             ++i) {
225                 int channel = atoi((*i)->property("Channel")->value().c_str());
226                 string name_set = (*i)->property("NameSet")->value();
227                 assert( 1 <= channel && channel <= 16 );
228                 _channel_name_set_assignments[channel -1] = name_set;
229         }
230         return 0;
231 }
232
233 XMLNode&
234 CustomDeviceMode::get_state(void)
235 {
236         XMLNode* custom_device_mode = new XMLNode("CustomDeviceMode");
237         custom_device_mode->add_property("Name",   _name);
238         XMLNode* channel_name_set_assignments = 
239                 custom_device_mode->add_child("ChannelNameSetAssignments");
240         for (int i = 0; i < 15 && !_channel_name_set_assignments[i].empty(); i++) {
241                 XMLNode* channel_name_set_assign = 
242                         channel_name_set_assignments->add_child("ChannelNameSetAssign");
243                 channel_name_set_assign->add_property("Channel", i + 1);
244                 channel_name_set_assign->add_property("NameSet", _channel_name_set_assignments[i]);
245         }
246         
247         return *custom_device_mode;
248 }
249
250 int
251 MasterDeviceNames::set_state(const XMLNode& a_node)
252 {
253         // cerr << "MasterDeviceNames::set_state Manufacturer" << endl;
254         // Manufacturer
255         boost::shared_ptr<XMLSharedNodeList> manufacturer = a_node.find("//Manufacturer");
256         assert(manufacturer->size() == 1);
257         _manufacturer = manufacturer->front()->content();
258
259         // cerr << "MasterDeviceNames::set_state models" << endl;
260         // Models
261         boost::shared_ptr<XMLSharedNodeList> models = a_node.find("//Model");
262         assert(models->size() >= 1);
263         for (XMLSharedNodeList::iterator i = models->begin();
264              i != models->end();
265              ++i) {
266                 const XMLNodeList& contents = (*i)->children();
267                 assert(contents.size() == 1);
268                 XMLNode * content = *(contents.begin());
269                 assert(content->is_content());
270                 _models.push_back(content->content());
271         }
272
273         // cerr << "MasterDeviceNames::set_state CustomDeviceModes" << endl;
274         // CustomDeviceModes
275         boost::shared_ptr<XMLSharedNodeList> custom_device_modes = a_node.find("//CustomDeviceMode");
276         for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
277              i != custom_device_modes->end();
278              ++i) {
279                 CustomDeviceMode* custom_device_mode = new CustomDeviceMode();
280                 custom_device_mode->set_state(*(*i));
281                 _custom_device_modes.push_back(*custom_device_mode);
282         }
283
284         // cerr << "MasterDeviceNames::set_state ChannelNameSets" << endl;
285         // ChannelNameSets
286         boost::shared_ptr<XMLSharedNodeList> channel_name_sets = a_node.find("//ChannelNameSet");
287         for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
288              i != channel_name_sets->end();
289              ++i) {
290                 ChannelNameSet* channel_name_set = new ChannelNameSet();
291                 // cerr << "MasterDeviceNames::set_state ChannelNameSet before set_state" << endl;
292                 channel_name_set->set_state(*(*i));
293                 _channel_name_sets.push_back(*channel_name_set);
294         }
295
296         // cerr << "MasterDeviceNames::set_state NoteNameLists" << endl;
297         // NoteNameLists
298         boost::shared_ptr<XMLSharedNodeList> note_name_lists = a_node.find("//NoteNameList");
299         for (XMLSharedNodeList::iterator i = note_name_lists->begin();
300              i != note_name_lists->end();
301              ++i) {
302                 NoteNameList* note_name_list = new NoteNameList();
303                 note_name_list->set_state(*(*i));
304                 _note_name_lists.push_back(*note_name_list);
305         }
306
307         return 0;
308 }
309
310 XMLNode&
311 MasterDeviceNames::get_state(void)
312 {
313         static XMLNode nothing("<nothing>");
314         return nothing;
315 }
316
317 int
318 MIDINameDocument::set_state(const XMLNode& a_node)
319 {
320         // Author
321         boost::shared_ptr<XMLSharedNodeList> author = a_node.find("//Author");
322         assert(author->size() == 1);
323         _author = author->front()->content();
324         
325         // cerr << "MIDINameDocument::set_state befor masterdevicenames" << endl;
326         // MasterDeviceNames
327         boost::shared_ptr<XMLSharedNodeList> master_device_names_list = a_node.find("//MasterDeviceNames");
328         for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
329              i != master_device_names_list->end();
330              ++i) {
331                 boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
332                 // cerr << "MIDINameDocument::set_state before masterdevicenames->set_state" << endl;
333                 master_device_names->set_state(*(*i));
334                 // cerr << "MIDINameDocument::set_state after masterdevicenames->set_state" << endl;
335                 
336                 for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
337                      model != master_device_names->models().end();
338                      ++model) {
339                         // cerr << "MIDINameDocument::set_state inserting model " << *model << endl;
340                                 _master_device_names_list.insert(
341                                                 std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
342                                                          (*model,      master_device_names));
343                                 
344                                 _all_models.push_back(*model);
345                 }
346         }
347         
348         return 0;
349 }
350
351 /*
352 const MasterDeviceNames::Models&
353 MIDINameDocument::models(void)
354 {
355         ;
356 }
357 */
358
359 XMLNode&
360 MIDINameDocument::get_state(void)
361 {
362         static XMLNode nothing("<nothing>");
363         return nothing;
364 }
365
366
367 } //namespace Name
368
369 } //namespace MIDI
370