1 /*
2 * liquidsfz - sfz sampler
3 *
4 * Copyright (C) 2020 Stefan Westerfeld
5 *
6 * This library is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by the
8 * Free Software Foundation; either version 2.1 of the License, or (at your
9 * option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this library; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "pugixml.hh"
22 #include "liquidsfz.hh"
23
24 using pugi::xml_node;
25 using pugi::xml_document;
26 using std::string;
27
28 namespace LiquidSFZInternal
29 {
30
31 string
gen_midnam(const LiquidSFZ::Synth & synth,const string & model)32 gen_midnam (const LiquidSFZ::Synth& synth, const string& model)
33 {
34 xml_document doc;
35
36 doc.append_child (pugi::node_doctype).set_value ("MIDINameDocument PUBLIC"
37 " \"-//MIDI Manufacturers Association//DTD MIDINameDocument 1.0//EN\""
38 " \"http://www.midi.org/dtds/MIDINameDocument10.dtd\"");
39
40 xml_node midi_name_document = doc.append_child ("MIDINameDocument");
41
42 midi_name_document.append_child ("Author");
43 xml_node master_device_names = midi_name_document.append_child ("MasterDeviceNames");
44 master_device_names.append_child ("Manufacturer").append_child (pugi::node_pcdata).set_value ("LiquidSFZ");
45 master_device_names.append_child ("Model").append_child (pugi::node_pcdata).set_value (model.c_str());
46
47 // ------------ <CustomDeviceMode>
48 xml_node custom_device_mode = master_device_names.append_child ("CustomDeviceMode");
49 custom_device_mode.append_attribute ("Name").set_value ("Default");
50
51 xml_node channel_name_set_assignments = custom_device_mode.append_child ("ChannelNameSetAssignments");
52 for (int channel = 1; channel <= 16; channel++)
53 {
54 pugi::xml_node channel_name_set_assign = channel_name_set_assignments.append_child ("ChannelNameSetAssign");
55 channel_name_set_assign.append_attribute ("Channel").set_value (channel);
56 channel_name_set_assign.append_attribute ("NameSet").set_value ("Names");
57 }
58 // ------------ </CustomDeviceMode>
59
60 // ------------ <ChannelNameSet>
61 xml_node channel_name_set = master_device_names.append_child ("ChannelNameSet");
62 channel_name_set.append_attribute ("Name").set_value("Names");
63
64 xml_node available_for_channels = channel_name_set.append_child ("AvailableForChannels");
65 for (int channel = 1; channel <= 16; channel++)
66 {
67 xml_node available_channel = available_for_channels.append_child ("AvailableChannel");
68 available_channel.append_attribute ("Channel").set_value (channel);
69 available_channel.append_attribute ("Available").set_value ("true");
70 }
71 channel_name_set.append_child ("UsesControlNameList").append_attribute ("Name").set_value ("Controls");
72 channel_name_set.append_child ("UsesNoteNameList").append_attribute ("Name").set_value ("Notes");
73 // ------------ </ChannelNameSet>
74
75 // ------------ <NoteNameList>
76 xml_node note_name_list = master_device_names.append_child ("NoteNameList");
77 note_name_list.append_attribute ("Name").set_value ("Notes");
78 for (const auto& key_info : synth.list_keys())
79 {
80 if (key_info.label() != "")
81 {
82 xml_node note = note_name_list.append_child ("Note");
83 note.append_attribute("Number").set_value (key_info.key());
84 note.append_attribute("Name").set_value (key_info.label().c_str());
85 }
86 }
87 // </NoteNameList>
88
89 // ------------- <ControlNameList>
90 pugi::xml_node control_name_list = master_device_names.append_child ("ControlNameList");
91 control_name_list.append_attribute ("Name").set_value ("Controls");
92 for (const auto& cc_info : synth.list_ccs())
93 {
94 xml_node control = control_name_list.append_child ("Control");
95 control.append_attribute ("Type").set_value ("7bit");
96 control.append_attribute ("Number").set_value (cc_info.cc());
97 control.append_attribute ("Name").set_value (cc_info.label().c_str());
98 }
99 // ------------- </ControlNameList>
100
101 struct xml_string_writer : pugi::xml_writer
102 {
103 string result;
104
105 virtual void
106 write (const void* data, size_t size)
107 {
108 result.append (static_cast<const char*>(data), size);
109 }
110 } writer;
111
112 doc.save (writer);
113 return writer.result;
114 }
115
116 }
117