Chris@45
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@45
|
2
|
Chris@45
|
3 /*
|
Chris@45
|
4 Sonic Visualiser
|
Chris@45
|
5 An audio file viewer and annotation editor.
|
Chris@45
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@45
|
7 This file copyright 2006 Chris Cannam and QMUL.
|
Chris@45
|
8
|
Chris@45
|
9 This program is free software; you can redistribute it and/or
|
Chris@45
|
10 modify it under the terms of the GNU General Public License as
|
Chris@45
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@45
|
12 License, or (at your option) any later version. See the file
|
Chris@45
|
13 COPYING included with this distribution for more information.
|
Chris@45
|
14 */
|
Chris@45
|
15
|
Chris@45
|
16 #ifndef _SV_FILE_READER_H_
|
Chris@45
|
17 #define _SV_FILE_READER_H_
|
Chris@45
|
18
|
Chris@45
|
19 #include "layer/LayerFactory.h"
|
Chris@106
|
20 #include "transform/Transform.h"
|
Chris@45
|
21
|
Chris@45
|
22 #include <QXmlDefaultHandler>
|
Chris@45
|
23
|
Chris@45
|
24 #include <map>
|
Chris@45
|
25
|
Chris@45
|
26 class Pane;
|
Chris@45
|
27 class Model;
|
Chris@45
|
28 class Document;
|
Chris@45
|
29 class PlayParameters;
|
Chris@45
|
30
|
Chris@45
|
31 class SVFileReaderPaneCallback
|
Chris@45
|
32 {
|
Chris@45
|
33 public:
|
Chris@45
|
34 virtual ~SVFileReaderPaneCallback();
|
Chris@45
|
35 virtual Pane *addPane() = 0;
|
Chris@45
|
36 virtual void setWindowSize(int width, int height) = 0;
|
Chris@45
|
37 virtual void addSelection(int start, int end) = 0;
|
Chris@45
|
38 };
|
Chris@45
|
39
|
Chris@45
|
40 /**
|
Chris@45
|
41 SVFileReader loads Sonic Visualiser XML files. (The SV file
|
Chris@45
|
42 format is bzipped XML.)
|
Chris@45
|
43
|
Chris@45
|
44 Some notes about the SV XML format follow. We're very lazy with
|
Chris@45
|
45 our XML: there's no schema or DTD, and we depend heavily on
|
Chris@45
|
46 elements being in a particular order.
|
Chris@45
|
47
|
Chris@45
|
48 \verbatim
|
Chris@45
|
49
|
Chris@45
|
50 <sv>
|
Chris@45
|
51
|
Chris@45
|
52 <data>
|
Chris@45
|
53
|
Chris@45
|
54 <!-- The data section contains definitions of both models and
|
Chris@45
|
55 visual layers. Layers are considered data in the document;
|
Chris@45
|
56 the structure of views that displays the layers is not. -->
|
Chris@45
|
57
|
Chris@45
|
58 <!-- id numbers are unique within the data type (i.e. no two
|
Chris@45
|
59 models can have the same id, but a model can have the same
|
Chris@45
|
60 id as a layer, etc). SV generates its id numbers just for
|
Chris@45
|
61 the purpose of cross-referencing within the current file;
|
Chris@45
|
62 they don't necessarily have any meaning once the file has
|
Chris@45
|
63 been loaded. -->
|
Chris@45
|
64
|
Chris@45
|
65 <model id="0" name="..." type="..." ... />
|
Chris@45
|
66 <model id="1" name="..." type="..." ... />
|
Chris@45
|
67
|
Chris@45
|
68 <!-- Models that have data associated with them store it
|
Chris@45
|
69 in a neighbouring dataset element. The dataset must follow
|
Chris@45
|
70 the model and precede any derivation or layer elements that
|
Chris@45
|
71 refer to the model. -->
|
Chris@45
|
72
|
Chris@45
|
73 <model id="2" name="..." type="..." dataset="0" ... />
|
Chris@45
|
74
|
Chris@45
|
75 <dataset id="0" type="...">
|
Chris@45
|
76 <point frame="..." value="..." ... />
|
Chris@45
|
77 </dataset>
|
Chris@45
|
78
|
Chris@45
|
79 <!-- Where one model is derived from another via a transform,
|
Chris@45
|
80 it has an associated derivation element. This must follow
|
Chris@45
|
81 both the source and target model elements. The source and
|
Chris@45
|
82 model attributes give the source model id and target model
|
Chris@45
|
83 id respectively. A model can have both dataset and
|
Chris@45
|
84 derivation elements; if it does, dataset must appear first.
|
Chris@45
|
85 If the model's data are not stored, but instead the model
|
Chris@45
|
86 is to be regenerated completely from the transform when
|
Chris@45
|
87 the session is reloaded, then the model should have _only_
|
Chris@45
|
88 a derivation element, and no model element should appear
|
Chris@45
|
89 for it at all. -->
|
Chris@45
|
90
|
Chris@72
|
91 <derivation type="transform" source="0" model="2" channel="-1">
|
Chris@72
|
92 <transform id="vamp:soname:pluginid:output" ... />
|
Chris@72
|
93 </derivation>
|
Chris@72
|
94
|
Chris@72
|
95 <!-- Note that the derivation element just described replaces
|
Chris@72
|
96 this earlier formulation, which had more attributes in the
|
Chris@72
|
97 derivation element and a plugin element describing plugin
|
Chris@72
|
98 parameters and properties. What we actually read and
|
Chris@72
|
99 write these days is a horrid composite of the two formats,
|
Chris@72
|
100 for backward compatibility reasons. -->
|
Chris@72
|
101
|
Chris@72
|
102 <derivation source="0" model="2" transform="vamp:soname:pluginid:output" ...>
|
Chris@72
|
103 <plugin id="pluginid" ... />
|
Chris@45
|
104 </derivation>
|
Chris@45
|
105
|
Chris@45
|
106 <!-- The playparameters element lists playback settings for
|
Chris@45
|
107 a model. -->
|
Chris@45
|
108
|
Chris@45
|
109 <playparameters mute="false" pan="0" gain="1" model="1" ... />
|
Chris@45
|
110
|
Chris@45
|
111 <!-- Layer elements. The models must have already been defined.
|
Chris@45
|
112 The same model may appear in more than one layer (of more
|
Chris@45
|
113 than one type). -->
|
Chris@45
|
114
|
Chris@45
|
115 <layer id="1" type="..." name="..." model="0" ... />
|
Chris@45
|
116 <layer id="2" type="..." name="..." model="1" ... />
|
Chris@45
|
117
|
Chris@45
|
118 </data>
|
Chris@45
|
119
|
Chris@45
|
120
|
Chris@45
|
121 <display>
|
Chris@45
|
122
|
Chris@45
|
123 <!-- The display element contains visual structure for the
|
Chris@45
|
124 layers. It's simpler than the data section. -->
|
Chris@45
|
125
|
Chris@45
|
126 <!-- Overall preferred window size for this session. -->
|
Chris@45
|
127
|
Chris@45
|
128 <window width="..." height="..."/>
|
Chris@45
|
129
|
Chris@45
|
130 <!-- List of view elements to stack up. Each one contains
|
Chris@45
|
131 a list of layers in stacking order, back to front. -->
|
Chris@45
|
132
|
Chris@45
|
133 <view type="pane" ...>
|
Chris@45
|
134 <layer id="1"/>
|
Chris@45
|
135 <layer id="2"/>
|
Chris@45
|
136 </view>
|
Chris@45
|
137
|
Chris@45
|
138 <!-- The layer elements just refer to layers defined in the
|
Chris@45
|
139 data section, so they don't have to have any attributes
|
Chris@45
|
140 other than the id. For sort-of-historical reasons SV
|
Chris@45
|
141 actually does repeat the other attributes here, but
|
Chris@45
|
142 it doesn't need to. -->
|
Chris@45
|
143
|
Chris@45
|
144 <view type="pane" ...>
|
Chris@45
|
145 <layer id="2"/>
|
Chris@45
|
146 <view>
|
Chris@45
|
147
|
Chris@45
|
148 </display>
|
Chris@45
|
149
|
Chris@45
|
150
|
Chris@45
|
151 <!-- List of selected regions by audio frame extents. -->
|
Chris@45
|
152
|
Chris@45
|
153 <selections>
|
Chris@45
|
154 <selection start="..." end="..."/>
|
Chris@45
|
155 </selections>
|
Chris@45
|
156
|
Chris@45
|
157
|
Chris@45
|
158 </sv>
|
Chris@45
|
159
|
Chris@45
|
160 \endverbatim
|
Chris@45
|
161 */
|
Chris@45
|
162
|
Chris@45
|
163
|
Chris@79
|
164 class SVFileReader : public QObject, QXmlDefaultHandler
|
Chris@45
|
165 {
|
Chris@79
|
166 Q_OBJECT
|
Chris@79
|
167
|
Chris@45
|
168 public:
|
Chris@45
|
169 SVFileReader(Document *document,
|
Chris@45
|
170 SVFileReaderPaneCallback &callback,
|
Chris@45
|
171 QString location = ""); // for audio file locate mechanism
|
Chris@45
|
172 virtual ~SVFileReader();
|
Chris@45
|
173
|
Chris@45
|
174 void parse(const QString &xmlData);
|
Chris@45
|
175 void parse(QXmlInputSource &source);
|
Chris@45
|
176
|
Chris@45
|
177 bool isOK();
|
Chris@45
|
178 QString getErrorString() const { return m_errorString; }
|
Chris@45
|
179
|
Chris@45
|
180 // For loading a single layer onto an existing pane
|
Chris@45
|
181 void setCurrentPane(Pane *pane) { m_currentPane = pane; }
|
Chris@45
|
182
|
Chris@45
|
183 virtual bool startElement(const QString &namespaceURI,
|
Chris@45
|
184 const QString &localName,
|
Chris@45
|
185 const QString &qName,
|
Chris@45
|
186 const QXmlAttributes& atts);
|
Chris@45
|
187
|
Chris@45
|
188 virtual bool characters(const QString &);
|
Chris@45
|
189
|
Chris@45
|
190 virtual bool endElement(const QString &namespaceURI,
|
Chris@45
|
191 const QString &localName,
|
Chris@45
|
192 const QString &qName);
|
Chris@45
|
193
|
Chris@45
|
194 bool error(const QXmlParseException &exception);
|
Chris@45
|
195 bool fatalError(const QXmlParseException &exception);
|
Chris@45
|
196
|
Chris@140
|
197 enum FileType
|
Chris@140
|
198 {
|
Chris@140
|
199 SVSessionFile,
|
Chris@140
|
200 SVLayerFile,
|
Chris@140
|
201 UnknownFileType
|
Chris@140
|
202 };
|
Chris@140
|
203
|
Chris@140
|
204 static FileType identifyXmlFile(QString path);
|
Chris@140
|
205
|
Chris@79
|
206 signals:
|
Chris@79
|
207 void modelRegenerationFailed(QString layerName, QString transformName,
|
Chris@79
|
208 QString message);
|
Chris@79
|
209 void modelRegenerationWarning(QString layerName, QString transformName,
|
Chris@79
|
210 QString message);
|
Chris@79
|
211
|
Chris@45
|
212 protected:
|
Chris@45
|
213 bool readWindow(const QXmlAttributes &);
|
Chris@45
|
214 bool readModel(const QXmlAttributes &);
|
Chris@45
|
215 bool readView(const QXmlAttributes &);
|
Chris@45
|
216 bool readLayer(const QXmlAttributes &);
|
Chris@45
|
217 bool readDatasetStart(const QXmlAttributes &);
|
Chris@45
|
218 bool addBinToDataset(const QXmlAttributes &);
|
Chris@45
|
219 bool addPointToDataset(const QXmlAttributes &);
|
Chris@45
|
220 bool addRowToDataset(const QXmlAttributes &);
|
Chris@45
|
221 bool readRowData(const QString &);
|
Chris@45
|
222 bool readDerivation(const QXmlAttributes &);
|
Chris@45
|
223 bool readPlayParameters(const QXmlAttributes &);
|
Chris@45
|
224 bool readPlugin(const QXmlAttributes &);
|
Chris@308
|
225 bool readPluginForTransform(const QXmlAttributes &);
|
Chris@308
|
226 bool readPluginForPlayback(const QXmlAttributes &);
|
Chris@72
|
227 bool readTransform(const QXmlAttributes &);
|
Chris@72
|
228 bool readParameter(const QXmlAttributes &);
|
Chris@45
|
229 bool readSelection(const QXmlAttributes &);
|
Chris@45
|
230 bool readMeasurement(const QXmlAttributes &);
|
Chris@45
|
231 void addUnaddedModels();
|
Chris@45
|
232
|
Chris@45
|
233 bool haveModel(int id) {
|
Chris@45
|
234 return (m_models.find(id) != m_models.end()) && m_models[id];
|
Chris@45
|
235 }
|
Chris@45
|
236
|
Chris@45
|
237 Document *m_document;
|
Chris@45
|
238 SVFileReaderPaneCallback &m_paneCallback;
|
Chris@45
|
239 QString m_location;
|
Chris@45
|
240 Pane *m_currentPane;
|
Chris@45
|
241 std::map<int, Layer *> m_layers;
|
Chris@45
|
242 std::map<int, Model *> m_models;
|
Chris@45
|
243 std::set<Model *> m_addedModels;
|
Chris@45
|
244 std::map<int, int> m_awaitingDatasets; // map dataset id -> model id
|
Chris@45
|
245 Layer *m_currentLayer;
|
Chris@45
|
246 Model *m_currentDataset;
|
Chris@45
|
247 Model *m_currentDerivedModel;
|
Chris@45
|
248 int m_currentDerivedModelId;
|
Chris@45
|
249 PlayParameters *m_currentPlayParameters;
|
Chris@72
|
250 Transform m_currentTransform;
|
Chris@72
|
251 Model *m_currentTransformSource;
|
Chris@72
|
252 int m_currentTransformChannel;
|
Chris@72
|
253 bool m_currentTransformIsNewStyle;
|
Chris@45
|
254 QString m_datasetSeparator;
|
Chris@45
|
255 bool m_inRow;
|
Chris@45
|
256 bool m_inLayer;
|
Chris@45
|
257 bool m_inView;
|
Chris@45
|
258 bool m_inData;
|
Chris@45
|
259 bool m_inSelections;
|
Chris@45
|
260 int m_rowNumber;
|
Chris@45
|
261 QString m_errorString;
|
Chris@45
|
262 bool m_ok;
|
Chris@45
|
263 };
|
Chris@45
|
264
|
Chris@45
|
265 #endif
|