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/convert.h"
36 Patch::get_state (void)
38 XMLNode
* node
= new XMLNode("Patch");
39 node
->add_property("Number", _number
);
40 node
->add_property("Name", _name
);
42 typedef std::list< boost::shared_ptr< Evoral::MIDIEvent<double> > > PatchMidiCommands;
43 XMLNode* commands = node->add_child("PatchMIDICommands");
44 for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
45 event != _patch_midi_commands.end();
47 commands->add_child_copy(*((((Evoral::MIDIEvent&)*event)).to_xml()));
54 void initialize_primary_key_from_commands (PatchPrimaryKey
& id
, const XMLNode
* node
)
56 const XMLNodeList events
= node
->children();
57 for (XMLNodeList::const_iterator i
= events
.begin(); i
!= events
.end(); ++i
) {
59 if (node
->name() == "ControlChange") {
60 string control
= node
->property("Control")->value();
61 assert(control
!= "");
62 string value
= node
->property("Value")->value();
66 id
.msb
= PBD::atoi(value
);
67 } else if (control
== "32") {
68 id
.lsb
= PBD::atoi(value
);
70 } else if (node
->name() == "ProgramChange") {
71 string number
= node
->property("Number")->value();
73 id
.program_number
= PBD::atoi(number
);
80 Patch::set_state (const XMLNode
& node
, int /*version*/)
82 assert(node
.name() == "Patch");
83 _number
= node
.property("Number")->value();
84 _name
= node
.property("Name")->value();
85 XMLNode
* commands
= node
.child("PatchMIDICommands");
88 initialize_primary_key_from_commands(_id
, commands
);
90 string program_change
= node
.property("ProgramChange")->value();
91 assert(program_change
.length());
93 assert(_bank
->patch_primary_key());
94 if ( _bank
&& _bank
->patch_primary_key() ) {
95 _id
.msb
= _bank
->patch_primary_key()->msb
;
96 _id
.lsb
= _bank
->patch_primary_key()->lsb
;
97 _id
.program_number
= PBD::atoi(program_change
);
101 cerr
<< "deserialized Patch: name: " << _name
<< " msb: " << _id
.msb
<< " lsb: " << _id
.lsb
<< " program " << _id
.program_number
<< endl
;
102 // TODO: handle that more gracefully
103 assert(_id
.is_sane());
109 Note::get_state (void)
111 XMLNode
* node
= new XMLNode("Note");
112 node
->add_property("Number", _number
);
113 node
->add_property("Name", _name
);
119 Note::set_state (const XMLNode
& node
, int /*version*/)
121 assert(node
.name() == "Note");
122 _number
= node
.property("Number")->value();
123 _name
= node
.property("Name")->value();
129 NoteNameList::get_state (void)
131 XMLNode
* node
= new XMLNode("NoteNameList");
132 node
->add_property("Name", _name
);
138 NoteNameList::set_state (const XMLNode
& node
, int version
)
140 assert(node
.name() == "NoteNameList");
141 _name
= node
.property("Name")->value();
143 boost::shared_ptr
<XMLSharedNodeList
> notes
=
145 for (XMLSharedNodeList::const_iterator i
= notes
->begin(); i
!= notes
->end(); ++i
) {
146 boost::shared_ptr
<Note
> note(new Note());
147 note
->set_state(*(*i
), version
);
148 _notes
.push_back(note
);
156 PatchBank::get_state (void)
158 XMLNode
* node
= new XMLNode("PatchBank");
159 node
->add_property("Name", _name
);
160 XMLNode
* patch_name_list
= node
->add_child("PatchNameList");
161 for (PatchNameList::iterator patch
= _patch_name_list
.begin();
162 patch
!= _patch_name_list
.end();
164 patch_name_list
->add_child_nocopy((*patch
)->get_state());
171 PatchBank::set_state (const XMLNode
& node
, int version
)
173 assert(node
.name() == "PatchBank");
174 _name
= node
.property("Name")->value();
176 XMLNode
* commands
= node
.child("MIDICommands");
178 _id
= new PatchPrimaryKey();
179 initialize_primary_key_from_commands(*_id
, commands
);
182 XMLNode
* patch_name_list
= node
.child("PatchNameList");
183 assert(patch_name_list
);
184 const XMLNodeList patches
= patch_name_list
->children();
185 for (XMLNodeList::const_iterator i
= patches
.begin(); i
!= patches
.end(); ++i
) {
186 boost::shared_ptr
<Patch
> patch(new Patch(this));
187 patch
->set_state(*(*i
), version
);
188 _patch_name_list
.push_back(patch
);
195 ChannelNameSet::get_state (void)
197 XMLNode
* node
= new XMLNode("ChannelNameSet");
198 node
->add_property("Name", _name
);
200 XMLNode
* available_for_channels
= node
->add_child("AvailableForChannels");
201 assert(available_for_channels
);
203 for (uint8_t channel
= 0; channel
< 16; ++channel
) {
204 XMLNode
* available_channel
= available_for_channels
->add_child("AvailableChannel");
205 assert(available_channel
);
207 available_channel
->add_property("Channel", (long) channel
);
209 if (_available_for_channels
.find(channel
) != _available_for_channels
.end()) {
210 available_channel
->add_property("Available", "true");
212 available_channel
->add_property("Available", "false");
216 for (PatchBanks::iterator patch_bank
= _patch_banks
.begin();
217 patch_bank
!= _patch_banks
.end();
219 node
->add_child_nocopy((*patch_bank
)->get_state());
226 ChannelNameSet::set_state (const XMLNode
& node
, int version
)
228 assert(node
.name() == "ChannelNameSet");
229 _name
= node
.property("Name")->value();
230 // cerr << "ChannelNameSet _name: " << _name << endl;
231 const XMLNodeList children
= node
.children();
232 for (XMLNodeList::const_iterator i
= children
.begin(); i
!= children
.end(); ++i
) {
235 if (node
->name() == "AvailableForChannels") {
236 // cerr << "AvailableForChannels" << endl;
237 boost::shared_ptr
<XMLSharedNodeList
> channels
=
238 node
->find("//AvailableChannel[@Available = 'true']/@Channel");
239 // cerr << "AvailableForChannels after find" << endl;
240 for(XMLSharedNodeList::const_iterator i
= channels
->begin();
241 i
!= channels
->end();
243 // cerr << "AvailableForChannels before insert" << endl;
244 _available_for_channels
.insert(atoi((*i
)->attribute_value().c_str()));
245 // cerr << "AvailableForChannels after insert" << endl;
249 // cerr << "before PatchBank" << endl;
251 if (node
->name() == "PatchBank") {
252 // cerr << "got PatchBank" << endl;
253 boost::shared_ptr
<PatchBank
> bank(new PatchBank());
254 bank
->set_state(*node
, version
);
255 _patch_banks
.push_back(bank
);
256 const PatchBank::PatchNameList
& patches
= bank
->patch_name_list();
257 for (PatchBank::PatchNameList::const_iterator patch
= patches
.begin();
258 patch
!= patches
.end();
260 _patch_map
[(*patch
)->patch_primary_key()] = *patch
;
261 _patch_list
.push_back((*patch
)->patch_primary_key());
263 // cerr << "after PatchBank pushback" << endl;
267 // cerr << "ChannelnameSet done" << endl;
273 CustomDeviceMode::set_state(const XMLNode
& a_node
, int /*version*/)
275 assert(a_node
.name() == "CustomDeviceMode");
277 _name
= a_node
.property("Name")->value();
279 boost::shared_ptr
<XMLSharedNodeList
> channel_name_set_assignments
=
280 a_node
.find("//ChannelNameSetAssign");
281 for(XMLSharedNodeList::const_iterator i
= channel_name_set_assignments
->begin();
282 i
!= channel_name_set_assignments
->end();
284 int channel
= atoi((*i
)->property("Channel")->value().c_str());
285 string name_set
= (*i
)->property("NameSet")->value();
286 assert( 1 <= channel
&& channel
<= 16 );
287 _channel_name_set_assignments
[channel
- 1] = name_set
;
293 CustomDeviceMode::get_state(void)
295 XMLNode
* custom_device_mode
= new XMLNode("CustomDeviceMode");
296 custom_device_mode
->add_property("Name", _name
);
297 XMLNode
* channel_name_set_assignments
=
298 custom_device_mode
->add_child("ChannelNameSetAssignments");
299 for (int i
= 0; i
< 15 && !_channel_name_set_assignments
[i
].empty(); i
++) {
300 XMLNode
* channel_name_set_assign
=
301 channel_name_set_assignments
->add_child("ChannelNameSetAssign");
302 channel_name_set_assign
->add_property("Channel", i
+ 1);
303 channel_name_set_assign
->add_property("NameSet", _channel_name_set_assignments
[i
]);
306 return *custom_device_mode
;
310 MasterDeviceNames::set_state(const XMLNode
& a_node
, int version
)
312 // cerr << "MasterDeviceNames::set_state Manufacturer" << endl;
314 boost::shared_ptr
<XMLSharedNodeList
> manufacturer
= a_node
.find("//Manufacturer");
315 assert(manufacturer
->size() == 1);
316 _manufacturer
= manufacturer
->front()->content();
318 // cerr << "MasterDeviceNames::set_state models" << endl;
320 boost::shared_ptr
<XMLSharedNodeList
> models
= a_node
.find("//Model");
321 assert(models
->size() >= 1);
322 for (XMLSharedNodeList::iterator i
= models
->begin();
325 const XMLNodeList
& contents
= (*i
)->children();
326 assert(contents
.size() == 1);
327 XMLNode
* content
= *(contents
.begin());
328 assert(content
->is_content());
329 _models
.push_back(content
->content());
332 // cerr << "MasterDeviceNames::set_state CustomDeviceModes" << endl;
334 boost::shared_ptr
<XMLSharedNodeList
> custom_device_modes
= a_node
.find("//CustomDeviceMode");
335 for (XMLSharedNodeList::iterator i
= custom_device_modes
->begin();
336 i
!= custom_device_modes
->end();
338 boost::shared_ptr
<CustomDeviceMode
> custom_device_mode(new CustomDeviceMode());
339 custom_device_mode
->set_state(*(*i
), version
);
341 _custom_device_modes
[custom_device_mode
->name()] = custom_device_mode
;
342 _custom_device_mode_names
.push_back(custom_device_mode
->name());
345 // cerr << "MasterDeviceNames::set_state ChannelNameSets" << endl;
347 boost::shared_ptr
<XMLSharedNodeList
> channel_name_sets
= a_node
.find("//ChannelNameSet");
348 for (XMLSharedNodeList::iterator i
= channel_name_sets
->begin();
349 i
!= channel_name_sets
->end();
351 boost::shared_ptr
<ChannelNameSet
> channel_name_set(new ChannelNameSet());
352 // cerr << "MasterDeviceNames::set_state ChannelNameSet before set_state" << endl;
353 channel_name_set
->set_state(*(*i
), version
);
354 _channel_name_sets
[channel_name_set
->name()] = channel_name_set
;
357 // cerr << "MasterDeviceNames::set_state NoteNameLists" << endl;
359 boost::shared_ptr
<XMLSharedNodeList
> note_name_lists
= a_node
.find("//NoteNameList");
360 for (XMLSharedNodeList::iterator i
= note_name_lists
->begin();
361 i
!= note_name_lists
->end();
363 boost::shared_ptr
<NoteNameList
> note_name_list(new NoteNameList());
364 note_name_list
->set_state(*(*i
), version
);
365 _note_name_lists
.push_back(note_name_list
);
372 MasterDeviceNames::get_state(void)
374 static XMLNode
nothing("<nothing>");
378 MIDINameDocument::MIDINameDocument (const string
& filename
)
379 : _document(XMLTree(filename
))
381 set_state(*_document
.root(), 0);
385 MIDINameDocument::set_state(const XMLNode
& a_node
, int version
)
388 boost::shared_ptr
<XMLSharedNodeList
> author
= a_node
.find("//Author");
389 assert(author
->size() == 1);
390 _author
= author
->front()->content();
392 // cerr << "MIDINameDocument::set_state befor masterdevicenames" << endl;
394 boost::shared_ptr
<XMLSharedNodeList
> master_device_names_list
= a_node
.find("//MasterDeviceNames");
395 for (XMLSharedNodeList::iterator i
= master_device_names_list
->begin();
396 i
!= master_device_names_list
->end();
398 boost::shared_ptr
<MasterDeviceNames
> master_device_names(new MasterDeviceNames());
399 // cerr << "MIDINameDocument::set_state before masterdevicenames->set_state" << endl;
400 master_device_names
->set_state(*(*i
), version
);
401 // cerr << "MIDINameDocument::set_state after masterdevicenames->set_state" << endl;
403 for (MasterDeviceNames::Models::const_iterator model
= master_device_names
->models().begin();
404 model
!= master_device_names
->models().end();
406 // cerr << "MIDINameDocument::set_state inserting model " << *model << endl;
407 _master_device_names_list
.insert(
408 std::pair
<std::string
, boost::shared_ptr
<MasterDeviceNames
> >
409 (*model
, master_device_names
));
411 _all_models
.push_back(*model
);
419 MIDINameDocument::get_state(void)
421 static XMLNode
nothing("<nothing>");