Adding first code drop
[demorecorder] / src / SettingsStructures.vala
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
6 *   Software Foundation
7 *
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
12 *
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.
17 */
18 namespace IdWorks {
19   
20   namespace SettingsStructures {
21
22   public struct VolumeSettings {
23     public double volume;
24     public bool mute;
25     
26     public VolumeSettings() {
27       this.volume = 1.0;
28       this.mute = false;
29     }
30     public VolumeSettings.with_values(double volume, bool mute) {
31       this.volume = volume;
32       this.mute = mute;
33     }
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(
39                  volume
40                , mute.to_string()
41              );
42     }
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) {
49           continue;
50         }
51         // Get the node's name
52         if ("VolumeSettings" == iter->name) {
53           from_xml_node(iter);
54           break;
55         }
56       }
57     }
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) {
64           continue;
65         }
66         // Get the node's name
67         string node_name = iter->name;
68         // Get the nodes type
69         string? type = XmlHelpers.get_node_attribute(iter, "type");
70         // Get the node's content with <tags> stripped
71         if (null != type) {
72           // check the type
73           switch(type) {
74             case "bool":
75               switch(node_name) {
76                 case "mute":
77                   this.mute = iter->get_content().to_bool();
78                   break;
79                 default:
80                   break;
81               }
82               break;
83             case "double":
84               switch(node_name) {
85                 case "volume":
86                   this.volume = iter->get_content().to_double();
87                   break;
88                 default:
89                   break;
90               }
91               break;
92             default:
93               continue;
94           }
95         }
96         
97       }
98     }
99   }
100
101   public struct PanoramaSettings {
102     public double panorama;
103     
104     public PanoramaSettings() {
105       this.panorama = 0.0;
106     }
107     public PanoramaSettings.with_values(double panorama) {
108       this.panorama = panorama;
109     }
110     public string to_xml_string() {
111       return ("<PanoramaSettings>\n" +
112               "<panorama type=\"double\">%02f</panorama>\n" +
113               "</PanoramaSettings>\n").printf(
114                 panorama
115               );
116     }
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) {
123           continue;
124         }
125         // Get the node's name
126         if ("PanoramaSettings" == iter->name) {
127           from_xml_node(iter);
128           break;
129         }
130       }
131     }
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) {
138           continue;
139         }
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
145         if (null != type) {
146           // check the type
147           switch(type) {
148             case "double":
149               switch(node_name) {
150                 case "panorama":
151                   this.panorama = iter->get_content().to_double();
152                   break;
153                 default:
154                   break;
155               }
156               break;
157             default:
158               continue;
159           }
160         }
161         
162       }
163     }
164   }
165
166   public struct DynamicsSettings {
167     public bool active;
168     public string mode;
169     public string characteristics;
170     public double ratio;
171     public double threshold;
172     
173     public DynamicsSettings() {
174       this.active = false;
175       this.mode = "compressor";
176       this.characteristics = "soft-knee";
177       this.ratio = 1.0;
178       this.threshold = 1.0;
179     }
180     public DynamicsSettings.with_values(bool active, string mode, string characteristics, double ratio, double threshold) {
181       this.active = false;
182       this.mode = mode;
183       this.characteristics = characteristics;
184       this.ratio = ratio;
185       this.threshold = threshold;
186     }
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(
195                 active.to_string(),
196                 mode,
197                 characteristics,
198                 ratio,
199                 threshold
200               );
201     }
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) {
208           continue;
209         }
210         // Get the node's name
211         if ("DynamicsSettings" == iter->name) {
212           from_xml_node(iter);
213           break;
214         }
215       }
216     }
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) {
222           continue;
223         }
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
229         if (null != type) {
230           // check the type
231           switch(type) {
232             case "bool":
233               switch(node_name) {
234                 case "active":
235                   this.active = iter->get_content().to_bool();
236                   break;
237                 default:
238                   break;
239               }
240               break;
241             case "double":
242               switch(node_name) {
243                 case "ratio":
244                   this.ratio = iter->get_content().to_double();
245                   break;
246                 case "threshold":
247                   this.threshold = iter->get_content().to_double();
248                   break;
249                 default:
250                   break;
251               }
252               break;
253             case "string":
254               switch(node_name) {
255                 case "mode":
256                   this.mode = iter->get_content();
257                   break;
258                 case "characteristics":
259                   this.characteristics = iter->get_content();
260                   break;
261                 default:
262                   break;
263               }
264               break;
265             default:
266               continue;
267           }
268         }
269         
270       }
271     }
272   }
273
274   public struct EchoSettings {
275     public bool active;
276     public uint64 max_delay;
277     public uint64 delay;
278     public double feedback;
279     public double intensity;
280     
281     public EchoSettings() {
282       this.active = false;
283       this.max_delay = 1 * Time.Nanoseconds.SECOND;
284       this.delay = 0;
285       this.feedback = 0;
286       this.intensity = 0;
287     }
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;
291       this.delay = delay;
292       this.feedback = feedback;
293       this.intensity = intensity;
294     }
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(
303                 active.to_string(),
304                 max_delay,
305                 delay,
306                 feedback,
307                 intensity
308                 );
309     }
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) {
316           continue;
317         }
318         // Get the node's name
319         if ("EchoSettings" == iter->name) {
320           from_xml_node(iter);
321           break;
322         }
323       }
324     }
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) {
331           continue;
332         }
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
338         if (null != type) {
339           // check the type
340           switch(type) {
341             case "bool":
342               switch(node_name) {
343                 case "active":
344                   this.active = iter->get_content().to_bool();
345                   break;
346                 default:
347                   break;
348               }
349               break;
350             case "double":
351               switch(node_name) {
352                 case "feedback":
353                   this.feedback = iter->get_content().to_double();
354                   break;
355                 case "intensity":
356                   this.intensity = iter->get_content().to_double();
357                   break;
358                 default:
359                   break;
360               }
361               break;
362             case "uint64":
363               switch(node_name) {
364                 case "max_delay":
365                   this.max_delay = iter->get_content().to_uint64();
366                   break;
367                 case "delay":
368                   this.delay = iter->get_content().to_uint64();
369                   break;
370                 default:
371                   break;
372               }
373               break;
374             default:
375               continue;
376           }
377         }
378         
379       }
380     }
381   }
382   
383   public struct EqualizerSettings {
384     public bool active;
385     public double[] bands;
386     public string name;
387     
388     public EqualizerSettings() {
389       this.active = true;
390       this.name = "";
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};
392     }
393     public EqualizerSettings.with_name(string val) {
394       this.active = true;
395       this.name = 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};
397     }
398     public EqualizerSettings.with_values(string name, double[] bands) {
399       this.active = true;
400       this.name = name;
401       this.bands = bands;
402     }
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(
418                 active.to_string(),
419                 name,
420                 bands[0],
421                 bands[1],
422                 bands[2],
423                 bands[3],
424                 bands[4],
425                 bands[5],
426                 bands[6],
427                 bands[7],
428                 bands[8],
429                 bands[9]
430               );
431     }
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) {
437           continue;
438         }
439         // Get the node's name
440         if ("EqualizerSettings" == iter->name) {
441           from_xml_node(iter);
442           break;
443         }
444       }
445     }
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) {
451           continue;
452         }
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
458         if (null != type) {
459           // check the type
460           switch(type) {
461             case "bool":
462               switch(node_name) {
463                 case "active":
464                   this.active = iter->get_content().to_bool();
465                   break;
466                 default:
467                   break;
468               }
469               break;
470             case "double":
471               switch(node_name) {
472                 case "band_0":
473                   this.bands[0] = iter->get_content().to_double();
474                   break;
475                 case "band_1":
476                   this.bands[1]= iter->get_content().to_double();
477                   break;
478                 case "band_2":
479                   this.bands[2] = iter->get_content().to_double();
480                   break;
481                 case "band_3":
482                   this.bands[3] = iter->get_content().to_double();
483                   break;
484                 case "band_4":
485                   this.bands[4] = iter->get_content().to_double();
486                   break;
487                 case "band_5":
488                   this.bands[5] = iter->get_content().to_double();
489                   break;
490                 case "band_6":
491                   this.bands[6] = iter->get_content().to_double();
492                   break;
493                 case "band_7":
494                   this.bands[7] = iter->get_content().to_double();
495                   break;
496                 case "band_8":
497                   this.bands[8] = iter->get_content().to_double();
498                   break;
499                 case "band_9":
500                   this.bands[9] = iter->get_content().to_double();
501                   break;
502                 default:
503                   break;
504               }
505               break;
506             case "string":
507               switch(node_name) {
508                 case "name":
509                   this.name = iter->get_content();
510                   break;
511                 default:
512                   break;
513               }
514               break;
515             default:
516               continue;
517           }
518         }
519         
520       }
521     }
522     
523     public string to_string() {
524       return "%s: bands:{%02f %02f %02f %02f %02f %02f %02f %02f %02f %02f}\n".printf(
525       name
526       , bands[0]
527       , bands[1]
528       , bands[2]
529       , bands[3]
530       , bands[4]
531       , bands[5]
532       , bands[6]
533       , bands[7]
534       , bands[8]
535       , bands[9]);
536     }
537     
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(",", "\\,")
541       , bands[0]
542       , bands[1]
543       , bands[2]
544       , bands[3]
545       , bands[4]
546       , bands[5]
547       , bands[6]
548       , bands[7]
549       , bands[8]
550       , bands[9]);
551     }
552     
553     public bool deserialize_from_string(string data) {
554       bool good = false;
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
560         name = values[0];
561         for (int i = 0; i < 10; ++i) {
562           bands[i] = values[i + 1].to_double();
563         }
564         good = true;
565       }
566       return good;
567     }
568   }
569
570   public struct RecordingSettings {
571     public string source;
572     public double pregain;
573     public double volume;
574     public DynamicsSettings dynamics;
575     
576     public RecordingSettings() {
577       this.source = "microphone";
578       this.pregain = 1.0;
579       this.volume = 1.0;
580       this.dynamics = DynamicsSettings();
581     }
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;
587     }
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(
595                 source,
596                 pregain,
597                 volume,
598                 dynamics.to_xml_string()
599               );
600     }
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) {
607           continue;
608         }
609         // Get the node's name
610         if ("RecordingSettings" == iter->name) {
611           from_xml_node(iter);
612           break;
613         }
614       }
615     }
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) {
622           continue;
623         }
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
629         if (null != type) {
630           // check the type
631           switch(type) {
632             case "string":
633               switch(node_name) {
634                 case "source":
635                   this.source = iter->get_content();
636                   break;
637                 default:
638                   break;
639               }
640               break;
641             case "double":
642               switch(node_name) {
643                 case "pregain":
644                   this.pregain = iter->get_content().to_double();
645                   break;
646                 case "volume":
647                   this.volume = iter->get_content().to_double();
648                   break;
649                 default:
650                   break;
651               }
652               break;
653             case "DynamicsSettings":
654               switch(node_name) {
655                 case "dynamics":
656                   this.dynamics.from_xml_node_helper(iter);
657                   break;
658                 default:
659                   break;
660               }
661               break;
662             default:
663               continue;
664           }
665         }
666         
667       }
668     }
669   }
670   
671   public struct MonitorSettings {
672     public bool output_audio;
673     public RecordingSettings input;
674     
675     public MonitorSettings() {
676       this.output_audio = false;
677       this.input = RecordingSettings();
678     }
679     public MonitorSettings.with_values(bool output_audio, RecordingSettings input) {
680       this.output_audio = output_audio;
681       this.input = input;
682     }
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()
690               );
691     }
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) {
698           continue;
699         }
700         // Get the node's name
701         if ("MonitorSettings" == iter->name) {
702           from_xml_node(iter);
703           break;
704         }
705       }
706     }
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) {
713           continue;
714         }
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
720         if (null != type) {
721           // check the type
722           switch(type) {
723             case "bool":
724               switch(node_name) {
725                 case "output_audio":
726                   this.output_audio = iter->get_content().to_bool();
727                   break;
728                 default:
729                   break;
730               }
731               break;
732             case "RecordingSettings":
733               switch(node_name) {
734                 case "input":
735                   this.input.from_xml_node_helper(iter);
736                   break;
737                 default:
738                   break;
739               }
740               break;
741             default:
742               continue;
743           }
744         }
745         
746       }
747     }
748   }
749
750   public struct TrackSettings {
751     public bool active;
752     public string uri;
753     public string name;
754     public string notes;
755     public VolumeSettings volume;
756     public PanoramaSettings panorama;
757     public DynamicsSettings dynamics;
758     public EchoSettings echo;
759     public EqualizerSettings equalizer;
760     
761     public TrackSettings() {
762       this.active = false;
763       this.uri = "";
764       this.name = "Unnamed";
765       this.notes = "";
766       this.volume = VolumeSettings();
767       this.panorama = PanoramaSettings();
768       this.dynamics = DynamicsSettings();
769       this.echo = EchoSettings();
770       this.equalizer = EqualizerSettings();
771     }
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;
774       this.uri = uri;
775       this.name = name;
776       this.notes = notes;
777       this.volume = volume;
778       this.panorama = panorama;
779       this.dynamics = dynamics;
780       this.echo = echo;
781       this.equalizer = equalizer;
782     }
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(
795                 active.to_string(),
796                 uri,
797                 name,
798                 notes,
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()
804               );
805     }
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) {
812           continue;
813         }
814         // Get the node's name
815         if ("TrackSettings" == iter->name) {
816           from_xml_node(iter);
817           break;
818         }
819       }
820     }
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) {
827           continue;
828         }
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
834         if (null != type) {
835           // check the type
836           switch(type) {
837             case "string":
838               switch(node_name) {
839                 case "name":
840                   this.name = iter->get_content();
841                   break;
842                 case "uri":
843                   this.uri = iter->get_content();
844                   break;
845                 case "notes":
846                   this.notes = iter->get_content();
847                   break;
848                 default:
849                   break;
850               }
851               break;
852             case "bool":
853               switch(node_name) {
854                 case "active":
855                   this.active = iter->get_content().to_bool();
856                   break;
857                 default:
858                   break;
859               }
860               break;
861             case "VolumeSettings":
862               switch(node_name) {
863                 case "volume":
864                   this.volume.from_xml_node_helper(iter);
865                   break;
866                 default:
867                   break;
868               }
869               break;
870             case "PanoramaSettings":
871               switch(node_name) {
872                 case "panorama":
873                   this.panorama.from_xml_node_helper(iter);
874                   break;
875                 default:
876                   break;
877               }
878               break;
879             case "DynamicsSettings":
880               switch(node_name) {
881                 case "dynamics":
882                   this.dynamics.from_xml_node_helper(iter);
883                   break;
884                 default:
885                   break;
886               }
887               break;
888             case "EchoSettings":
889               switch(node_name) {
890                 case "echo":
891                   this.echo.from_xml_node_helper(iter);
892                   break;
893                 default:
894                   break;
895               }
896               break;
897             case "EqualizerSettings":
898               switch(node_name) {
899                 case "equalizer":
900                   this.equalizer.from_xml_node_helper(iter);
901                   break;
902                 default:
903                   break;
904               }
905               break;
906             default:
907               continue;
908           }
909         }
910         
911       }
912     }
913   }
914
915   public struct MixerSettings {
916     public VolumeSettings volume;
917     public PanoramaSettings panorama;
918     public EqualizerSettings equalizer;
919     
920     public MixerSettings() {
921       this.volume = VolumeSettings();
922       this.panorama = PanoramaSettings();
923       this.equalizer = EqualizerSettings();
924     }
925     public MixerSettings.with_values(VolumeSettings volume, PanoramaSettings panorama, EqualizerSettings equalizer) {
926       this.volume = volume;
927       this.panorama = panorama;
928       this.equalizer = equalizer;
929     }
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()
939               );
940     }
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) {
947           continue;
948         }
949         // Get the node's name
950         if ("MixerSettings" == iter->name) {
951           from_xml_node(iter);
952           break;
953         }
954       }
955     }
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) {
962           continue;
963         }
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
969         if (null != type) {
970           // check the type
971           switch(type) {
972               case "VolumeSettings":
973                 switch(node_name) {
974                   case "volume":
975                     this.volume.from_xml_node_helper(iter);
976                     break;
977                   default:
978                     break;
979                 }
980                 break;
981               case "PanoramaSettings":
982                 switch(node_name) {
983                   case "panorama":
984                     this.panorama.from_xml_node_helper(iter);
985                     break;
986                   default:
987                     break;
988                 }
989                 break;
990               case "EqualizerSettings":
991                 switch(node_name) {
992                   case "equalizer":
993                     this.equalizer.from_xml_node_helper(iter);
994                     break;
995                   default:
996                     break;
997                 }
998                 break;
999               default:
1000                 continue;
1001           }
1002         }
1003         
1004       }
1005     }
1006   }
1007   
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;
1016     
1017     public MixdownSettings() {
1018       this.encoder = "vorbisenc";
1019       this.quality = "high";
1020       this.location = "";
1021       this.artist = "Unknown Artist";
1022       this.title = "Untitled";
1023       this.album = "Untitled";
1024       this.tags = null;
1025     }
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;
1031       this.title = title;
1032       this.album = album;
1033       this.tags = tags;
1034     }
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(
1045                 encoder,
1046                 quality,
1047                 location,
1048                 artist,
1049                 title,
1050                 album,
1051                 Tagging.Tag.taglist_to_xml_string(tags)
1052               );
1053     }
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) {
1060           continue;
1061         }
1062         // Get the node's name
1063         if ("MixdownSettings" == iter->name) {
1064           from_xml_node(iter);
1065           break;
1066         }
1067       }
1068     }
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) {
1075           continue;
1076         }
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
1082         if (null != type) {
1083           // check the type
1084           switch(type) {
1085             case "string":
1086               switch(node_name) {
1087                 case "encoder":
1088                   this.encoder = iter->get_content();
1089                   break;
1090                 case "quality":
1091                   this.quality = iter->get_content();
1092                   break;
1093                 case "location":
1094                   this.location = iter->get_content();
1095                   break;
1096                 case "artist":
1097                   this.artist = iter->get_content();
1098                   break;
1099                 case "title":
1100                   this.title = iter->get_content();
1101                   break;
1102                 case "album":
1103                   this.album = iter->get_content();
1104                   break;
1105                 default:
1106                   break;
1107               }
1108               break;
1109             case "TagList":
1110               switch(node_name) {
1111                 case "tags":
1112                   Tagging.Tag.taglist_from_xml_node_helper(iter, ref this.tags);
1113                   break;
1114                 default:
1115                   break;
1116               }
1117               break;
1118             default:
1119               continue;
1120           }
1121         }
1122         
1123       }
1124     }
1125   }
1126
1127   public struct ProjectSettings {
1128     public string location;
1129     public string name;
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;
1136     
1137     public ProjectSettings() {
1138       this.name = "New Project";
1139       this.location = "";
1140       this.working_directory = "";
1141       this.last_track_number = 0;
1142       this.monitor = MonitorSettings();
1143       this.mixer = MixerSettings();
1144       this.mixdown = MixdownSettings();
1145       this.tracks = null;
1146     }
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) {
1148       this.name = name;
1149       this.location = location;
1150       this.working_directory = working_directory;
1151       this.last_track_number = last_track_number;
1152       this.monitor = monitor;
1153       this.mixer = mixer;
1154       this.mixdown = mixdown;
1155       this.tracks = tracks;
1156     }
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(
1168                 name,
1169                 location,
1170                 working_directory,
1171                 last_track_number,
1172                 monitor.to_xml_string(),
1173                 mixer.to_xml_string(),
1174                 mixdown.to_xml_string(),
1175                 Track.tracklist_to_xml_string(tracks)
1176               );
1177     }
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) {
1184           continue;
1185         }
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
1191         if (null != type) {
1192           // check the type
1193           switch(type) {
1194             case "string":
1195               switch(node_name) {
1196                 case "name":
1197                   this.name = iter->get_content();
1198                   break;
1199                 case "location":
1200                   this.location = iter->get_content();
1201                   break;
1202                 case "working_directory":
1203                   this.working_directory = iter->get_content();
1204                   break;
1205                 default:
1206                   break;
1207               }
1208               break;
1209             case "int":
1210               switch(node_name) {
1211                 case "last_track_number":
1212                   this.last_track_number = iter->get_content().to_int();
1213                   break;
1214                 default:
1215                   break;
1216               }
1217               break;
1218             case "bool":
1219               switch(node_name) {
1220                 default:
1221                   break;
1222               }
1223               break;
1224             case "double":
1225               switch(node_name) {
1226                 default:
1227                   break;
1228               }
1229               break;
1230             case "uint64":
1231               switch(node_name) {
1232                 default:
1233                   break;
1234               }
1235               break;
1236             case "MonitorSettings":
1237               switch(node_name) {
1238                 case "monitor":
1239                     this.monitor.from_xml_node_helper(iter);
1240                     break;
1241                   default:
1242                     break;
1243                 }
1244               break;
1245             case "MixerSettings":
1246                 switch(node_name) {
1247                   case "mixer":
1248                     this.mixer.from_xml_node_helper(iter);
1249                     break;
1250                   default:
1251                     break;
1252                 }
1253               break;
1254             case "MixdownSettings":
1255                 switch(node_name) {
1256                   case "mixdown":
1257                     this.mixdown.from_xml_node_helper(iter);
1258                     break;
1259                   default:
1260                     break;
1261                 }
1262               break;
1263             case "TrackList":
1264                 switch(node_name) {
1265                   case "tracks":
1266                     Track.tracklist_from_xml_node_helper(iter, ref this.tracks);
1267                     break;
1268                   default:
1269                     break;
1270                 }
1271               break;
1272             default:
1273               continue;
1274           }
1275         }
1276         
1277       }
1278     }
1279   }
1280
1281   }
1282
1283 }