1 /* Demo Recorder for MAEMO 5
2 * Copyright (C) 2010 Dru Moore <usr@dru-id.co.uk>
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2,
5 * or (at your option) any later version, as published by the Free
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 namespace SettingsStructures {
22 public struct VolumeSettings {
26 public VolumeSettings() {
30 public VolumeSettings.with_values(double volume, bool mute) {
34 public string to_xml_string() {
35 return ("<VolumeSettings>\n" +
36 "<volume type=\"double\">%02f</volume>\n" +
37 "<mute type=\"bool\">%s</mute>\n" +
38 "</VolumeSettings>\n").printf(
43 public void from_xml_node_helper(Xml.Node* node) {
44 // VolumeSettings is below root
45 // Loop over the passed node's children
46 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
47 // Spaces between tags are also nodes, discard them
48 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
51 // Get the node's name
52 if ("VolumeSettings" == iter->name) {
58 public void from_xml_node(Xml.Node* node) {
59 // VolumeSettings is root
60 // Loop over the passed node's children
61 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
62 // Spaces between tags are also nodes, discard them
63 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
66 // Get the node's name
67 string node_name = iter->name;
69 string? type = XmlHelpers.get_node_attribute(iter, "type");
70 // Get the node's content with <tags> stripped
77 this.mute = iter->get_content().to_bool();
86 this.volume = iter->get_content().to_double();
101 public struct PanoramaSettings {
102 public double panorama;
104 public PanoramaSettings() {
107 public PanoramaSettings.with_values(double panorama) {
108 this.panorama = panorama;
110 public string to_xml_string() {
111 return ("<PanoramaSettings>\n" +
112 "<panorama type=\"double\">%02f</panorama>\n" +
113 "</PanoramaSettings>\n").printf(
117 public void from_xml_node_helper(Xml.Node* node) {
118 // PanoramaSettings is below root
119 // Loop over the passed node's children
120 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
121 // Spaces between tags are also nodes, discard them
122 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
125 // Get the node's name
126 if ("PanoramaSettings" == iter->name) {
132 public void from_xml_node(Xml.Node* node) {
133 // PanoramaSettings is root
134 // Loop over the passed node's children
135 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
136 // Spaces between tags are also nodes, discard them
137 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
140 // Get the node's name
141 string node_name = iter->name;
142 // Get the nodes type
143 string? type = XmlHelpers.get_node_attribute(iter, "type");
144 // Get the node's content with <tags> stripped
151 this.panorama = iter->get_content().to_double();
166 public struct DynamicsSettings {
169 public string characteristics;
171 public double threshold;
173 public DynamicsSettings() {
175 this.mode = "compressor";
176 this.characteristics = "soft-knee";
178 this.threshold = 1.0;
180 public DynamicsSettings.with_values(bool active, string mode, string characteristics, double ratio, double threshold) {
183 this.characteristics = characteristics;
185 this.threshold = threshold;
187 public string to_xml_string() {
188 return ("<DynamicsSettings>\n" +
189 "<active type=\"bool\">%s</active>\n" +
190 "<mode type=\"string\"><![CDATA[%s]]></mode>\n" +
191 "<characteristics type=\"string\"><![CDATA[%s]]></characteristics>\n" +
192 "<ratio type=\"double\">%02f</ratio>\n" +
193 "<threshold type=\"double\">%02f</threshold>\n" +
194 "</DynamicsSettings>\n").printf(
202 public void from_xml_node_helper(Xml.Node* node) {
203 // DynamicsSettings is below root
204 // Loop over the passed node's children
205 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
206 // Spaces between tags are also nodes, discard them
207 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
210 // Get the node's name
211 if ("DynamicsSettings" == iter->name) {
217 public void from_xml_node(Xml.Node* node) {
218 // Loop over the passed node's children
219 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
220 // Spaces between tags are also nodes, discard them
221 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
224 // Get the node's name
225 string node_name = iter->name;
226 // Get the nodes type
227 string? type = XmlHelpers.get_node_attribute(iter, "type");
228 // Get the node's content with <tags> stripped
235 this.active = iter->get_content().to_bool();
244 this.ratio = iter->get_content().to_double();
247 this.threshold = iter->get_content().to_double();
256 this.mode = iter->get_content();
258 case "characteristics":
259 this.characteristics = iter->get_content();
274 public struct EchoSettings {
276 public uint64 max_delay;
278 public double feedback;
279 public double intensity;
281 public EchoSettings() {
283 this.max_delay = Time.Milliseconds.SECOND / 2;
288 public EchoSettings.with_values(bool active, uint64 max_delay, uint64 delay, double feedback, double intensity) {
289 this.active = active;
290 this.max_delay = max_delay;
292 this.feedback = feedback;
293 this.intensity = intensity;
295 public string to_xml_string() {
296 return ("<EchoSettings>\n" +
297 "<active type=\"bool\">%s</active>\n" +
298 "<max_delay type=\"uint64\">%llu</max_delay>\n" +
299 "<delay type=\"uint64\">%llu</delay>\n" +
300 "<feedback type=\"double\">%02f</feedback>\n" +
301 "<intensity type=\"double\">%02f</intensity>\n" +
302 "</EchoSettings>\n").printf(
310 public void from_xml_node_helper(Xml.Node* node) {
311 // EchoSettings is below root
312 // Loop over the passed node's children
313 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
314 // Spaces between tags are also nodes, discard them
315 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
318 // Get the node's name
319 if ("EchoSettings" == iter->name) {
325 public void from_xml_node(Xml.Node* node) {
326 // EchoSettings is root
327 // Loop over the passed node's children
328 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
329 // Spaces between tags are also nodes, discard them
330 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
333 // Get the node's name
334 string node_name = iter->name;
335 // Get the nodes type
336 string? type = XmlHelpers.get_node_attribute(iter, "type");
337 // Get the node's content with <tags> stripped
344 this.active = iter->get_content().to_bool();
353 this.feedback = iter->get_content().to_double();
356 this.intensity = iter->get_content().to_double();
365 this.max_delay = iter->get_content().to_uint64();
368 this.delay = iter->get_content().to_uint64();
383 public struct EqualizerSettings {
385 public double[] bands;
388 public EqualizerSettings() {
391 this.bands = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
393 public EqualizerSettings.with_name(string val) {
396 this.bands = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
398 public EqualizerSettings.with_values(string name, double[] bands) {
403 public string to_xml_string() {
404 return ("<EqualizerSettings>\n" +
405 "<active type=\"bool\">%s></active>\n" +
406 "<name type=\"string\"><![CDATA[%s]]></name>\n" +
407 "<band_0 type=\"double\">>%02f</band_0>\n" +
408 "<band_1 type=\"double\">>%02f</band_1>\n" +
409 "<band_2 type=\"double\">>%02f</band_2>\n" +
410 "<band_3 type=\"double\">>%02f</band_3>\n" +
411 "<band_4 type=\"double\">>%02f</band_4>\n" +
412 "<band_5 type=\"double\">>%02f</band_5>\n" +
413 "<band_6 type=\"double\">>%02f</band_6>\n" +
414 "<band_7 type=\"double\">>%02f</band_7>\n" +
415 "<band_8 type=\"double\">>%02f</band_8>\n" +
416 "<band_9 type=\"double\">>%02f</band_9>\n" +
417 "</EqualizerSettings>\n").printf(
432 public void from_xml_node_helper(Xml.Node* node) {
433 // Loop over the passed node's children
434 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
435 // Spaces between tags are also nodes, discard them
436 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
439 // Get the node's name
440 if ("EqualizerSettings" == iter->name) {
446 public void from_xml_node(Xml.Node* node) {
447 // Loop over the passed node's children
448 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
449 // Spaces between tags are also nodes, discard them
450 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
453 // Get the node's name
454 string node_name = iter->name;
455 // Get the nodes type
456 string? type = XmlHelpers.get_node_attribute(iter, "type");
457 // Get the node's content with <tags> stripped
464 this.active = iter->get_content().to_bool();
473 this.bands[0] = iter->get_content().to_double();
476 this.bands[1]= iter->get_content().to_double();
479 this.bands[2] = iter->get_content().to_double();
482 this.bands[3] = iter->get_content().to_double();
485 this.bands[4] = iter->get_content().to_double();
488 this.bands[5] = iter->get_content().to_double();
491 this.bands[6] = iter->get_content().to_double();
494 this.bands[7] = iter->get_content().to_double();
497 this.bands[8] = iter->get_content().to_double();
500 this.bands[9] = iter->get_content().to_double();
509 this.name = iter->get_content();
523 public string to_string() {
524 return "%s: bands:{%02f %02f %02f %02f %02f %02f %02f %02f %02f %02f}\n".printf(
538 public string serialize_to_string() {
539 return "EqualizerPreset:%s,%02f,%02f,%02f,%02f,%02f,%02f,%02f,%02f,%02f,%02f\n".printf(
540 name.replace(",", "\\,")
553 public bool deserialize_from_string(string data) {
555 // call parser to build an array of string of parts
556 string[] values = CdlParser.ParseLine(data);
557 // check length of array
558 if (13 == values.length) {
559 // parse parts into this
561 for (int i = 0; i < 10; ++i) {
562 bands[i] = values[i + 1].to_double();
570 public struct RecordingSettings {
571 public string source;
572 public double pregain;
573 public double volume;
574 public DynamicsSettings dynamics;
576 public RecordingSettings() {
577 this.source = "microphone";
580 this.dynamics = DynamicsSettings();
582 public RecordingSettings.with_values(string source, double pregain, double volume, DynamicsSettings dynamics) {
583 this.source = source;
584 this.pregain = pregain;
585 this.volume = volume;
586 this.dynamics = dynamics;
588 public string to_xml_string() {
589 return ("<RecordingSettings>\n" +
590 "<source type=\"string\"><![CDATA[%s]]></source>\n" +
591 "<pregain type=\"double\">%02f</pregain>\n" +
592 "<volume type=\"double\">%02f</volume>\n" +
593 "<dynamics type=\"DynamicsSettings\">\n%s</dynamics>\n" +
594 "</RecordingSettings>\n").printf(
598 dynamics.to_xml_string()
601 public void from_xml_node_helper(Xml.Node* node) {
602 // RecordingSettings is below root
603 // Loop over the passed node's children
604 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
605 // Spaces between tags are also nodes, discard them
606 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
609 // Get the node's name
610 if ("RecordingSettings" == iter->name) {
616 public void from_xml_node(Xml.Node* node) {
617 // RecordingSettings is root
618 // Loop over the passed node's children
619 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
620 // Spaces between tags are also nodes, discard them
621 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
624 // Get the node's name
625 string node_name = iter->name;
626 // Get the nodes type
627 string? type = XmlHelpers.get_node_attribute(iter, "type");
628 // Get the node's content with <tags> stripped
635 this.source = iter->get_content();
644 this.pregain = iter->get_content().to_double();
647 this.volume = iter->get_content().to_double();
653 case "DynamicsSettings":
656 this.dynamics.from_xml_node_helper(iter);
671 public struct MonitorSettings {
672 public bool output_audio;
673 public RecordingSettings input;
675 public MonitorSettings() {
676 this.output_audio = false;
677 this.input = RecordingSettings();
679 public MonitorSettings.with_values(bool output_audio, RecordingSettings input) {
680 this.output_audio = output_audio;
683 public string to_xml_string() {
684 return ("<MonitorSettings>\n" +
685 "<output_audio type=\"bool\">%s</output_audio>\n" +
686 "<input type=\"RecordingSettings\">\n%s</input>\n" +
687 "</MonitorSettings>\n").printf(
688 output_audio.to_string(),
689 input.to_xml_string()
692 public void from_xml_node_helper(Xml.Node* node) {
693 // MonitorSettings is below root
694 // Loop over the passed node's children
695 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
696 // Spaces between tags are also nodes, discard them
697 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
700 // Get the node's name
701 if ("MonitorSettings" == iter->name) {
707 public void from_xml_node(Xml.Node* node) {
708 // MonitorSettings is root
709 // Loop over the passed node's children
710 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
711 // Spaces between tags are also nodes, discard them
712 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
715 // Get the node's name
716 string node_name = iter->name;
717 // Get the nodes type
718 string? type = XmlHelpers.get_node_attribute(iter, "type");
719 // Get the node's content with <tags> stripped
726 this.output_audio = iter->get_content().to_bool();
732 case "RecordingSettings":
735 this.input.from_xml_node_helper(iter);
750 public struct TrackSettings {
755 public VolumeSettings volume;
756 public PanoramaSettings panorama;
757 public DynamicsSettings dynamics;
758 public EchoSettings echo;
759 public EqualizerSettings equalizer;
761 public TrackSettings() {
764 this.name = "Unnamed";
766 this.volume = VolumeSettings();
767 this.panorama = PanoramaSettings();
768 this.dynamics = DynamicsSettings();
769 this.echo = EchoSettings();
770 this.equalizer = EqualizerSettings();
772 public TrackSettings.with_values(string uri, string name, string notes, bool active, VolumeSettings volume, PanoramaSettings panorama, DynamicsSettings dynamics, EchoSettings echo, EqualizerSettings equalizer) {
773 this.active = active;
777 this.volume = volume;
778 this.panorama = panorama;
779 this.dynamics = dynamics;
781 this.equalizer = equalizer;
783 public string to_xml_string() {
784 return ("<TrackSettings>\n" +
785 "<active type=\"bool\">%s</active>\n" +
786 "<uri type=\"string\"><![CDATA[%s]]></uri>\n" +
787 "<name type=\"string\"><![CDATA[%s]]></name>\n" +
788 "<notes type=\"string\"><![CDATA[%s]]></notes>\n" +
789 "<volume type=\"VolumeSettings\">\n%s</volume>\n" +
790 "<panorama type=\"PanoramaSettings\">\n%s</panorama>\n" +
791 "<dynamics type=\"DynamicsSettings\">\n%s</dynamics>\n" +
792 "<echo type=\"EchoSettings\">\n%s</echo>\n" +
793 "<equalizer type=\"EqualizerSettings\">\n%s</equalizer>\n" +
794 "</TrackSettings>\n").printf(
799 volume.to_xml_string(),
800 panorama.to_xml_string(),
801 dynamics.to_xml_string(),
802 echo.to_xml_string(),
803 equalizer.to_xml_string()
806 public void from_xml_node_helper(Xml.Node* node) {
807 // TrackSettings is below root
808 // Loop over the passed node's children
809 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
810 // Spaces between tags are also nodes, discard them
811 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
814 // Get the node's name
815 if ("TrackSettings" == iter->name) {
821 public void from_xml_node(Xml.Node* node) {
822 // TrackSettings is root
823 // Loop over the passed node's children
824 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
825 // Spaces between tags are also nodes, discard them
826 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
829 // Get the node's name
830 string node_name = iter->name;
831 // Get the nodes type
832 string? type = XmlHelpers.get_node_attribute(iter, "type");
833 // Get the node's content with <tags> stripped
840 this.name = iter->get_content();
843 this.uri = iter->get_content();
846 this.notes = iter->get_content();
855 this.active = iter->get_content().to_bool();
861 case "VolumeSettings":
864 this.volume.from_xml_node_helper(iter);
870 case "PanoramaSettings":
873 this.panorama.from_xml_node_helper(iter);
879 case "DynamicsSettings":
882 this.dynamics.from_xml_node_helper(iter);
891 this.echo.from_xml_node_helper(iter);
897 case "EqualizerSettings":
900 this.equalizer.from_xml_node_helper(iter);
915 public struct MixerSettings {
916 public VolumeSettings volume;
917 public PanoramaSettings panorama;
918 public EqualizerSettings equalizer;
920 public MixerSettings() {
921 this.volume = VolumeSettings();
922 this.panorama = PanoramaSettings();
923 this.equalizer = EqualizerSettings();
925 public MixerSettings.with_values(VolumeSettings volume, PanoramaSettings panorama, EqualizerSettings equalizer) {
926 this.volume = volume;
927 this.panorama = panorama;
928 this.equalizer = equalizer;
930 public string to_xml_string() {
931 return ("<MixerSettings>\n" +
932 "<volume type=\"VolumeSettings\">\n%s</volume>\n" +
933 "<panorama type=\"PanoramaSettings\">\n%s</panorama>\n" +
934 "<equalizer type=\"EqualizerSettings\">\n%s</equalizer>\n" +
935 "</MixerSettings>\n").printf(
936 volume.to_xml_string(),
937 panorama.to_xml_string(),
938 equalizer.to_xml_string()
941 public void from_xml_node_helper(Xml.Node* node) {
942 // MixerSettings is below root
943 // Loop over the passed node's children
944 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
945 // Spaces between tags are also nodes, discard them
946 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
949 // Get the node's name
950 if ("MixerSettings" == iter->name) {
956 public void from_xml_node(Xml.Node* node) {
957 // MixerSettings is root
958 // Loop over the passed node's children
959 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
960 // Spaces between tags are also nodes, discard them
961 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
964 // Get the node's name
965 string node_name = iter->name;
966 // Get the nodes type
967 string? type = XmlHelpers.get_node_attribute(iter, "type");
968 // Get the node's content with <tags> stripped
972 case "VolumeSettings":
975 this.volume.from_xml_node_helper(iter);
981 case "PanoramaSettings":
984 this.panorama.from_xml_node_helper(iter);
990 case "EqualizerSettings":
993 this.equalizer.from_xml_node_helper(iter);
1008 public struct MixdownSettings {
1009 public string encoder;
1010 public string quality;
1011 public string location;
1012 public string artist;
1013 public string title;
1014 public string album;
1015 public unowned List<Tagging.Tag?> tags;
1017 public MixdownSettings() {
1018 this.encoder = "vorbisenc";
1019 this.quality = "high";
1021 this.artist = "Unknown Artist";
1022 this.title = "Untitled";
1023 this.album = "Untitled";
1026 public MixdownSettings.with_values(string encoder, string quality, string location, string artist, string title, string album, List<Tagging.Tag?> tags) {
1027 this.encoder = encoder;
1028 this.quality = quality;
1029 this.location = location;
1030 this.artist = artist;
1035 public string to_xml_string() {
1036 return ("<MixdownSettings>\n" +
1037 "<encoder type=\"string\"><![CDATA[%s]]></encoder>\n" +
1038 "<quality type=\"string\"><![CDATA[%s]]></quality>\n" +
1039 "<location type=\"string\"><![CDATA[%s]]></location>\n" +
1040 "<artist type=\"string\"><![CDATA[%s]]></artist>\n" +
1041 "<title type=\"string\"><![CDATA[%s]]></title>\n" +
1042 "<album type=\"string\"><![CDATA[%s]]></album>\n" +
1043 "<tags type=\"TagList\">\n%s</tags>\n" +
1044 "</MixdownSettings>\n").printf(
1051 Tagging.Tag.taglist_to_xml_string(tags)
1054 public void from_xml_node_helper(Xml.Node* node) {
1055 // MixdownSettings is below root
1056 // Loop over the passed node's children
1057 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
1058 // Spaces between tags are also nodes, discard them
1059 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
1062 // Get the node's name
1063 if ("MixdownSettings" == iter->name) {
1064 from_xml_node(iter);
1069 public void from_xml_node(Xml.Node* node) {
1070 // MixdownSettings is root
1071 // Loop over the passed node's children
1072 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
1073 // Spaces between tags are also nodes, discard them
1074 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
1077 // Get the node's name
1078 string node_name = iter->name;
1079 // Get the nodes type
1080 string? type = XmlHelpers.get_node_attribute(iter, "type");
1081 // Get the node's content with <tags> stripped
1088 this.encoder = iter->get_content();
1091 this.quality = iter->get_content();
1094 this.location = iter->get_content();
1097 this.artist = iter->get_content();
1100 this.title = iter->get_content();
1103 this.album = iter->get_content();
1112 Tagging.Tag.taglist_from_xml_node_helper(iter, ref this.tags);
1127 public struct ProjectSettings {
1128 public string location;
1130 public string working_directory;
1131 public int last_track_number;
1132 public MonitorSettings monitor;
1133 public MixerSettings mixer;
1134 public MixdownSettings mixdown;
1135 public unowned List<Track?> tracks;
1137 public ProjectSettings() {
1138 this.name = "New Project";
1140 this.working_directory = "";
1141 this.last_track_number = 0;
1142 this.monitor = MonitorSettings();
1143 this.mixer = MixerSettings();
1144 this.mixdown = MixdownSettings();
1147 public ProjectSettings.with_values(string name, string location, string working_directory, int last_track_number, MonitorSettings monitor, MixerSettings mixer, MixdownSettings mixdown, List<Track?> tracks) {
1149 this.location = location;
1150 this.working_directory = working_directory;
1151 this.last_track_number = last_track_number;
1152 this.monitor = monitor;
1154 this.mixdown = mixdown;
1155 this.tracks = tracks;
1157 public string to_xml_string() {
1158 return ("<ProjectSettings version=\"1.0\">\n" +
1159 "<name type=\"string\"><![CDATA[%s]]></name>\n" +
1160 "<location type=\"string\"><![CDATA[%s]]></location>\n" +
1161 "<working_directory type=\"string\"><![CDATA[%s]]></working_directory>\n" +
1162 "<last_track_number type=\"int\">%i</last_track_number>\n" +
1163 "<monitor type=\"MonitorSettings\">\n%s</monitor>\n" +
1164 "<mixer type=\"MixerSettings\">\n%s</mixer>\n" +
1165 "<mixdown type=\"MixdownSettings\">\n%s</mixdown>\n" +
1166 "<tracks type=\"TrackList\">\n%s</tracks>\n" +
1167 "</ProjectSettings>\n").printf(
1172 monitor.to_xml_string(),
1173 mixer.to_xml_string(),
1174 mixdown.to_xml_string(),
1175 Track.tracklist_to_xml_string(tracks)
1178 public void from_xml_node(Xml.Node* node) {
1179 // ProjectSettings is root
1180 // Loop over the passed node's children
1181 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
1182 // Spaces between tags are also nodes, discard them
1183 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
1186 // Get the node's name
1187 string node_name = iter->name;
1188 // Get the nodes type
1189 string? type = XmlHelpers.get_node_attribute(iter, "type");
1190 // Get the node's content with <tags> stripped
1197 this.name = iter->get_content();
1200 this.location = iter->get_content();
1202 case "working_directory":
1203 this.working_directory = iter->get_content();
1211 case "last_track_number":
1212 this.last_track_number = iter->get_content().to_int();
1236 case "MonitorSettings":
1239 this.monitor.from_xml_node_helper(iter);
1245 case "MixerSettings":
1248 this.mixer.from_xml_node_helper(iter);
1254 case "MixdownSettings":
1257 this.mixdown.from_xml_node_helper(iter);
1266 Track.tracklist_from_xml_node_helper(iter, ref this.tracks);