comparison document/SVFileReader.cpp @ 55:ca1e3f5657d5

* Simplify maker names in plugin menu * Make sure derived models have a name (based on the transform) * Don't start deriving a model from a derived model until the derived model is ready * Tidy up completion management in writable wave file model * Make writable models save/reload correctly from session file (i.e. regenerating from the original transform) * Same for dense 3d models -- don't save the data, just the transform details * Add a comment describing the SV file format
author Chris Cannam
date Fri, 13 Oct 2006 12:51:05 +0000
parents 5f9fdca0c7d8
children bedc7517b6e8
comparison
equal deleted inserted replaced
54:ec77936c268e 55:ca1e3f5657d5
36 #include <QString> 36 #include <QString>
37 #include <QMessageBox> 37 #include <QMessageBox>
38 #include <QFileDialog> 38 #include <QFileDialog>
39 39
40 #include <iostream> 40 #include <iostream>
41
42 /*
43 Some notes about the SV XML format. We're very lazy with our XML:
44 there's no schema or DTD, and we depend heavily on elements being
45 in a particular order.
46
47 <sv>
48
49 <data>
50
51 <!-- The data section contains definitions of both models and
52 visual layers. Layers are considered data in the document;
53 the structure of views that displays the layers is not. -->
54
55 <!-- id numbers are unique within the data type (i.e. no two
56 models can have the same id, but a model can have the same
57 id as a layer, etc). SV generates its id numbers just for
58 the purpose of cross-referencing within the current file;
59 they don't necessarily have any meaning once the file has
60 been loaded. -->
61
62 <model id="0" name="..." type="..." ... />
63 <model id="1" name="..." type="..." ... />
64
65 <!-- Models that have data associated with them store it
66 in a neighbouring dataset element. The dataset must follow
67 the model and precede any derivation or layer elements that
68 refer to the model. -->
69
70 <model id="2" name="..." type="..." dataset="0" ... />
71
72 <dataset id="0" type="...">
73 <point frame="..." value="..." ... />
74 </dataset>
75
76 <!-- Where one model is derived from another via a transform,
77 it has an associated derivation element. This must follow
78 both the source and target model elements. The source and
79 model attributes give the source model id and target model
80 id respectively. A model can have both dataset and
81 derivation elements; if it does, dataset must appear first.
82 If the model's data are not stored, but instead the model
83 is to be regenerated completely from the transform when
84 the session is reloaded, then the model should have _only_
85 a derivation element, and no model element should appear
86 for it at all. -->
87
88 <derivation source="0" model="2" transform="..." ...>
89 <plugin id="..." ... />
90 </derivation>
91
92 <!-- The playparameters element lists playback settings for
93 a model. -->
94
95 <playparameters mute="false" pan="0" gain="1" model="1" ... />
96
97 <!-- Layer elements. The models must have already been defined.
98 The same model may appear in more than one layer (of more
99 than one type). -->
100
101 <layer id="1" type="..." name="..." model="0" ... />
102 <layer id="2" type="..." name="..." model="1" ... />
103
104 </data>
105
106
107 <display>
108
109 <!-- The display element contains visual structure for the
110 layers. It's simpler than the data section. -->
111
112 <!-- Overall preferred window size for this session. -->
113
114 <window width="..." height="..."/>
115
116 <!-- List of view elements to stack up. Each one contains
117 a list of layers in stacking order, back to front. -->
118
119 <view type="pane" ...>
120 <layer id="1"/>
121 <layer id="2"/>
122 </view>
123
124 <!-- The layer elements just refer to layers defined in the
125 data section, so they don't have to have any attributes
126 other than the id. For sort-of-historical reasons SV
127 actually does repeat the other attributes here, but
128 it doesn't need to. -->
129
130 <view type="pane" ...>
131 <layer id="2"/>
132 <view>
133
134 </display>
135
136
137 <!-- List of selected regions by audio frame extents. -->
138
139 <selections>
140 <selection start="..." end="..."/>
141 </selections>
142
143
144 </sv>
145
146 */
147
41 148
42 SVFileReader::SVFileReader(Document *document, 149 SVFileReader::SVFileReader(Document *document,
43 SVFileReaderPaneCallback &callback) : 150 SVFileReaderPaneCallback &callback) :
44 m_document(document), 151 m_document(document),
45 m_paneCallback(callback), 152 m_paneCallback(callback),
46 m_currentPane(0), 153 m_currentPane(0),
47 m_currentDataset(0), 154 m_currentDataset(0),
48 m_currentDerivedModel(0), 155 m_currentDerivedModel(0),
156 m_currentDerivedModelId(-1),
49 m_currentPlayParameters(0), 157 m_currentPlayParameters(0),
50 m_datasetSeparator(" "), 158 m_datasetSeparator(" "),
51 m_inRow(false), 159 m_inRow(false),
52 m_rowNumber(0), 160 m_rowNumber(0),
53 m_ok(false) 161 m_ok(false)
256 364
257 addUnaddedModels(); 365 addUnaddedModels();
258 m_inData = false; 366 m_inData = false;
259 367
260 } else if (name == "derivation") { 368 } else if (name == "derivation") {
261 369
262 if (m_currentDerivedModel) { 370 if (!m_currentDerivedModel) {
371 if (m_currentDerivedModel < 0) {
372 std::cerr << "WARNING: SV-XML: Bad derivation output model id "
373 << m_currentDerivedModelId << std::endl;
374 } else if (m_models[m_currentDerivedModelId]) {
375 std::cerr << "WARNING: SV-XML: Derivation has existing model "
376 << m_currentDerivedModelId
377 << " as target, not regenerating" << std::endl;
378 } else {
379 m_currentDerivedModel = m_models[m_currentDerivedModelId] =
380 m_document->addDerivedModel(m_currentTransform,
381 m_currentTransformSource,
382 m_currentTransformContext,
383 m_currentTransformConfiguration);
384 }
385 } else {
263 m_document->addDerivedModel(m_currentTransform, 386 m_document->addDerivedModel(m_currentTransform,
264 m_document->getMainModel(), //!!! 387 m_currentTransformSource,
265 m_currentTransformContext, 388 m_currentTransformContext,
266 m_currentDerivedModel, 389 m_currentDerivedModel,
267 m_currentTransformConfiguration); 390 m_currentTransformConfiguration);
268 m_addedModels.insert(m_currentDerivedModel);
269 m_currentDerivedModel = 0;
270 m_currentTransform = "";
271 m_currentTransformConfiguration = "";
272 } 391 }
392
393 m_addedModels.insert(m_currentDerivedModel);
394 m_currentDerivedModel = 0;
395 m_currentDerivedModelId = -1;
396 m_currentTransform = "";
397 m_currentTransformConfiguration = "";
273 398
274 } else if (name == "row") { 399 } else if (name == "row") {
275 m_inRow = false; 400 m_inRow = false;
276 } else if (name == "view") { 401 } else if (name == "view") {
277 m_inView = false; 402 m_inView = false;
364 489
365 READ_MANDATORY(int, sampleRate, toInt); 490 READ_MANDATORY(int, sampleRate, toInt);
366 491
367 QString type = attributes.value("type").trimmed(); 492 QString type = attributes.value("type").trimmed();
368 bool mainModel = (attributes.value("mainModel").trimmed() == "true"); 493 bool mainModel = (attributes.value("mainModel").trimmed() == "true");
369 494
370 if (type == "wavefile") { 495 if (type == "wavefile") {
371 496
372 QString file = attributes.value("file"); 497 QString file = attributes.value("file");
373 WaveFileModel *model = new WaveFileModel(file); 498 WaveFileModel *model = new WaveFileModel(file);
374 499
410 535
411 } else if (type == "dense") { 536 } else if (type == "dense") {
412 537
413 READ_MANDATORY(int, dimensions, toInt); 538 READ_MANDATORY(int, dimensions, toInt);
414 539
415 // Currently the only dense model we support here 540 // Currently the only dense model we support here is the dense
416 // is the dense 3d model. Dense time-value models 541 // 3d model. Dense time-value models are always file-backed
417 // are always file-backed waveform data, at this 542 // waveform data, at this point, and they come in as wavefile
418 // point, and they come in as the wavefile model 543 // models.
419 // type above.
420 544
421 if (dimensions == 3) { 545 if (dimensions == 3) {
422 546
423 READ_MANDATORY(int, windowSize, toInt); 547 READ_MANDATORY(int, windowSize, toInt);
424 READ_MANDATORY(int, yBinCount, toInt); 548 READ_MANDATORY(int, yBinCount, toInt);
884 1008
885 if (!modelOk) { 1009 if (!modelOk) {
886 std::cerr << "WARNING: SV-XML: No model id specified for derivation" << std::endl; 1010 std::cerr << "WARNING: SV-XML: No model id specified for derivation" << std::endl;
887 return false; 1011 return false;
888 } 1012 }
889 1013
890 QString transform = attributes.value("transform"); 1014 QString transform = attributes.value("transform");
891 1015
892 if (m_models.find(modelId) != m_models.end()) { 1016 if (m_models.find(modelId) != m_models.end()) {
893
894 m_currentDerivedModel = m_models[modelId]; 1017 m_currentDerivedModel = m_models[modelId];
895 m_currentTransform = transform;
896 m_currentTransformConfiguration = "";
897
898 m_currentTransformContext = PluginTransform::ExecutionContext();
899
900 bool ok = false;
901 int channel = attributes.value("channel").trimmed().toInt(&ok);
902 if (ok) m_currentTransformContext.channel = channel;
903
904 int domain = attributes.value("domain").trimmed().toInt(&ok);
905 if (ok) m_currentTransformContext.domain = Vamp::Plugin::InputDomain(domain);
906
907 int stepSize = attributes.value("stepSize").trimmed().toInt(&ok);
908 if (ok) m_currentTransformContext.stepSize = stepSize;
909
910 int blockSize = attributes.value("blockSize").trimmed().toInt(&ok);
911 if (ok) m_currentTransformContext.blockSize = blockSize;
912
913 int windowType = attributes.value("windowType").trimmed().toInt(&ok);
914 if (ok) m_currentTransformContext.windowType = WindowType(windowType);
915
916 } else { 1018 } else {
917 std::cerr << "WARNING: SV-XML: Unknown derived model " << modelId 1019 // we'll regenerate the model when the derivation element ends
918 << " for transform \"" << transform.toLocal8Bit().data() << "\"" 1020 m_currentDerivedModel = 0;
919 << std::endl; 1021 }
920 return false; 1022
921 } 1023 m_currentDerivedModelId = modelId;
1024
1025 int sourceId = 0;
1026 bool sourceOk = false;
1027 sourceId = attributes.value("source").trimmed().toInt(&sourceOk);
1028
1029 if (sourceOk && m_models[sourceId]) {
1030 m_currentTransformSource = m_models[sourceId];
1031 } else {
1032 m_currentTransformSource = m_document->getMainModel();
1033 }
1034
1035 m_currentTransform = transform;
1036 m_currentTransformConfiguration = "";
1037
1038 m_currentTransformContext = PluginTransform::ExecutionContext();
1039
1040 bool ok = false;
1041 int channel = attributes.value("channel").trimmed().toInt(&ok);
1042 if (ok) m_currentTransformContext.channel = channel;
1043
1044 int domain = attributes.value("domain").trimmed().toInt(&ok);
1045 if (ok) m_currentTransformContext.domain = Vamp::Plugin::InputDomain(domain);
1046
1047 int stepSize = attributes.value("stepSize").trimmed().toInt(&ok);
1048 if (ok) m_currentTransformContext.stepSize = stepSize;
1049
1050 int blockSize = attributes.value("blockSize").trimmed().toInt(&ok);
1051 if (ok) m_currentTransformContext.blockSize = blockSize;
1052
1053 int windowType = attributes.value("windowType").trimmed().toInt(&ok);
1054 if (ok) m_currentTransformContext.windowType = WindowType(windowType);
922 1055
923 return true; 1056 return true;
924 } 1057 }
925 1058
926 bool 1059 bool
979 } 1112 }
980 1113
981 bool 1114 bool
982 SVFileReader::readPlugin(const QXmlAttributes &attributes) 1115 SVFileReader::readPlugin(const QXmlAttributes &attributes)
983 { 1116 {
984 if (!m_currentDerivedModel && !m_currentPlayParameters) { 1117 if (m_currentDerivedModelId < 0 && !m_currentPlayParameters) {
985 std::cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << std::endl; 1118 std::cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << std::endl;
986 return false; 1119 return false;
987 } 1120 }
988 1121
989 QString configurationXml = "<plugin"; 1122 QString configurationXml = "<plugin";
990 1123
991 for (int i = 0; i < attributes.length(); ++i) { 1124 for (int i = 0; i < attributes.length(); ++i) {
992 configurationXml += QString(" %1=\"%2\"") 1125 configurationXml += QString(" %1=\"%2\"")
993 .arg(attributes.qName(i)).arg(attributes.value(i)); 1126 .arg(attributes.qName(i))
1127 .arg(XmlExportable::encodeEntities(attributes.value(i)));
994 } 1128 }
995 1129
996 configurationXml += "/>"; 1130 configurationXml += "/>";
997 1131
998 if (m_currentPlayParameters) { 1132 if (m_currentPlayParameters) {