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