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