annotate framework/SVFileReader.h @ 730:8cf265f9b1b3

Merge from branch csv-export-dialog
author Chris Cannam
date Tue, 14 Jan 2020 15:49:03 +0000
parents 610fa108fbcc
children
rev   line source
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@635 16 #ifndef SV_FILE_READER_H
Chris@635 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@685 28 class Path;
Chris@45 29 class Document;
Chris@45 30 class PlayParameters;
Chris@45 31
Chris@45 32 class SVFileReaderPaneCallback
Chris@45 33 {
Chris@45 34 public:
Chris@45 35 virtual ~SVFileReaderPaneCallback();
Chris@45 36 virtual Pane *addPane() = 0;
Chris@45 37 virtual void setWindowSize(int width, int height) = 0;
Chris@435 38 virtual void addSelection(sv_frame_t start, sv_frame_t end) = 0;
Chris@45 39 };
Chris@45 40
Chris@45 41 /**
Chris@45 42 SVFileReader loads Sonic Visualiser XML files. (The SV file
Chris@45 43 format is bzipped XML.)
Chris@45 44
Chris@45 45 Some notes about the SV XML format follow. We're very lazy with
Chris@45 46 our XML: there's no schema or DTD, and we depend heavily on
Chris@45 47 elements being in a particular order.
Chris@45 48
Chris@45 49 \verbatim
Chris@45 50
Chris@45 51 <sv>
Chris@45 52
Chris@45 53 <data>
Chris@45 54
Chris@45 55 <!-- The data section contains definitions of both models and
Chris@45 56 visual layers. Layers are considered data in the document;
Chris@45 57 the structure of views that displays the layers is not. -->
Chris@45 58
Chris@45 59 <!-- id numbers are unique within the data type (i.e. no two
Chris@45 60 models can have the same id, but a model can have the same
Chris@45 61 id as a layer, etc). SV generates its id numbers just for
Chris@45 62 the purpose of cross-referencing within the current file;
Chris@45 63 they don't necessarily have any meaning once the file has
Chris@45 64 been loaded. -->
Chris@45 65
Chris@45 66 <model id="0" name="..." type="..." ... />
Chris@45 67 <model id="1" name="..." type="..." ... />
Chris@45 68
Chris@45 69 <!-- Models that have data associated with them store it
Chris@45 70 in a neighbouring dataset element. The dataset must follow
Chris@45 71 the model and precede any derivation or layer elements that
Chris@45 72 refer to the model. -->
Chris@45 73
Chris@45 74 <model id="2" name="..." type="..." dataset="0" ... />
Chris@45 75
Chris@45 76 <dataset id="0" type="...">
Chris@45 77 <point frame="..." value="..." ... />
Chris@45 78 </dataset>
Chris@45 79
Chris@45 80 <!-- Where one model is derived from another via a transform,
Chris@45 81 it has an associated derivation element. This must follow
Chris@45 82 both the source and target model elements. The source and
Chris@45 83 model attributes give the source model id and target model
Chris@45 84 id respectively. A model can have both dataset and
Chris@45 85 derivation elements; if it does, dataset must appear first.
Chris@45 86 If the model's data are not stored, but instead the model
Chris@45 87 is to be regenerated completely from the transform when
Chris@45 88 the session is reloaded, then the model should have _only_
Chris@45 89 a derivation element, and no model element should appear
Chris@45 90 for it at all. -->
Chris@45 91
Chris@72 92 <derivation type="transform" source="0" model="2" channel="-1">
Chris@72 93 <transform id="vamp:soname:pluginid:output" ... />
Chris@72 94 </derivation>
Chris@72 95
Chris@72 96 <!-- Note that the derivation element just described replaces
Chris@72 97 this earlier formulation, which had more attributes in the
Chris@72 98 derivation element and a plugin element describing plugin
Chris@72 99 parameters and properties. What we actually read and
Chris@72 100 write these days is a horrid composite of the two formats,
Chris@72 101 for backward compatibility reasons. -->
Chris@72 102
Chris@72 103 <derivation source="0" model="2" transform="vamp:soname:pluginid:output" ...>
Chris@72 104 <plugin id="pluginid" ... />
Chris@45 105 </derivation>
Chris@45 106
Chris@45 107 <!-- The playparameters element lists playback settings for
Chris@45 108 a model. -->
Chris@45 109
Chris@45 110 <playparameters mute="false" pan="0" gain="1" model="1" ... />
Chris@45 111
Chris@45 112 <!-- Layer elements. The models must have already been defined.
Chris@45 113 The same model may appear in more than one layer (of more
Chris@45 114 than one type). -->
Chris@45 115
Chris@45 116 <layer id="1" type="..." name="..." model="0" ... />
Chris@45 117 <layer id="2" type="..." name="..." model="1" ... />
Chris@45 118
Chris@45 119 </data>
Chris@45 120
Chris@45 121
Chris@45 122 <display>
Chris@45 123
Chris@45 124 <!-- The display element contains visual structure for the
Chris@45 125 layers. It's simpler than the data section. -->
Chris@45 126
Chris@587 127 <!-- Overall preferred window size for this session. (Now
Chris@587 128 deprecated, it wasn't a good idea to try to persist this) -->
Chris@45 129
Chris@45 130 <window width="..." height="..."/>
Chris@45 131
Chris@45 132 <!-- List of view elements to stack up. Each one contains
Chris@45 133 a list of layers in stacking order, back to front. -->
Chris@45 134
Chris@45 135 <view type="pane" ...>
Chris@45 136 <layer id="1"/>
Chris@45 137 <layer id="2"/>
Chris@45 138 </view>
Chris@45 139
Chris@45 140 <!-- The layer elements just refer to layers defined in the
Chris@45 141 data section, so they don't have to have any attributes
Chris@45 142 other than the id. For sort-of-historical reasons SV
Chris@45 143 actually does repeat the other attributes here, but
Chris@45 144 it doesn't need to. -->
Chris@45 145
Chris@45 146 <view type="pane" ...>
Chris@45 147 <layer id="2"/>
Chris@45 148 <view>
Chris@45 149
Chris@45 150 </display>
Chris@45 151
Chris@45 152
Chris@45 153 <!-- List of selected regions by audio frame extents. -->
Chris@45 154
Chris@45 155 <selections>
Chris@45 156 <selection start="..." end="..."/>
Chris@45 157 </selections>
Chris@45 158
Chris@45 159
Chris@45 160 </sv>
Chris@45 161
Chris@45 162 \endverbatim
Chris@45 163 */
Chris@45 164
Chris@45 165
Chris@79 166 class SVFileReader : public QObject, QXmlDefaultHandler
Chris@45 167 {
Chris@79 168 Q_OBJECT
Chris@79 169
Chris@45 170 public:
Chris@45 171 SVFileReader(Document *document,
Chris@595 172 SVFileReaderPaneCallback &callback,
Chris@45 173 QString location = ""); // for audio file locate mechanism
Chris@45 174 virtual ~SVFileReader();
Chris@45 175
Chris@45 176 void parse(const QString &xmlData);
Chris@45 177 void parse(QXmlInputSource &source);
Chris@45 178
Chris@45 179 bool isOK();
Chris@45 180 QString getErrorString() const { return m_errorString; }
Chris@45 181
Chris@45 182 // For loading a single layer onto an existing pane
Chris@45 183 void setCurrentPane(Pane *pane) { m_currentPane = pane; }
Chris@45 184
Chris@634 185 bool startElement(const QString &namespaceURI,
Chris@685 186 const QString &localName,
Chris@685 187 const QString &qName,
Chris@685 188 const QXmlAttributes& atts) override;
Chris@685 189
Chris@634 190 bool characters(const QString &) override;
Chris@45 191
Chris@634 192 bool endElement(const QString &namespaceURI,
Chris@685 193 const QString &localName,
Chris@685 194 const QString &qName) override;
Chris@45 195
Chris@634 196 bool error(const QXmlParseException &exception) override;
Chris@634 197 bool fatalError(const QXmlParseException &exception) override;
Chris@45 198
Chris@140 199 enum FileType
Chris@140 200 {
Chris@140 201 SVSessionFile,
Chris@140 202 SVLayerFile,
Chris@140 203 UnknownFileType
Chris@140 204 };
Chris@140 205
Chris@140 206 static FileType identifyXmlFile(QString path);
Chris@140 207
Chris@79 208 signals:
Chris@79 209 void modelRegenerationFailed(QString layerName, QString transformName,
Chris@79 210 QString message);
Chris@79 211 void modelRegenerationWarning(QString layerName, QString transformName,
Chris@79 212 QString message);
Chris@79 213
Chris@45 214 protected:
Chris@45 215 bool readWindow(const QXmlAttributes &);
Chris@45 216 bool readModel(const QXmlAttributes &);
Chris@45 217 bool readView(const QXmlAttributes &);
Chris@45 218 bool readLayer(const QXmlAttributes &);
Chris@45 219 bool readDatasetStart(const QXmlAttributes &);
Chris@45 220 bool addBinToDataset(const QXmlAttributes &);
Chris@45 221 bool addPointToDataset(const QXmlAttributes &);
Chris@45 222 bool addRowToDataset(const QXmlAttributes &);
Chris@45 223 bool readRowData(const QString &);
Chris@45 224 bool readDerivation(const QXmlAttributes &);
Chris@45 225 bool readPlayParameters(const QXmlAttributes &);
Chris@45 226 bool readPlugin(const QXmlAttributes &);
Chris@308 227 bool readPluginForTransform(const QXmlAttributes &);
Chris@308 228 bool readPluginForPlayback(const QXmlAttributes &);
Chris@72 229 bool readTransform(const QXmlAttributes &);
Chris@72 230 bool readParameter(const QXmlAttributes &);
Chris@45 231 bool readSelection(const QXmlAttributes &);
Chris@45 232 bool readMeasurement(const QXmlAttributes &);
Chris@629 233
Chris@629 234 void makeAggregateModels();
Chris@45 235 void addUnaddedModels();
Chris@45 236
Chris@685 237 // We use the term "pending" of things that have been referred to
Chris@685 238 // but not yet constructed because their definitions are
Chris@685 239 // incomplete. They are just referred to with an ExportId. Models
Chris@685 240 // that have been constructed are always added straight away to
Chris@685 241 // ById and are referred to with a ModelId (everywhere where
Chris@685 242 // previously we would have used a Model *). m_models maps from
Chris@685 243 // ExportId (as read from the file) to complete Models, or to a
Chris@685 244 // ModelId of None for any model that could not be constructed for
Chris@685 245 // some reason.
Chris@685 246
Chris@685 247 typedef XmlExportable::ExportId ExportId;
Chris@685 248
Chris@685 249 bool haveModel(ExportId id) {
Chris@685 250 return (m_models.find(id) != m_models.end()) && !m_models[id].isNone();
Chris@45 251 }
Chris@685 252
Chris@629 253 struct PendingAggregateRec {
Chris@629 254 QString name;
Chris@629 255 sv_samplerate_t sampleRate;
Chris@685 256 std::vector<ExportId> components;
Chris@629 257 };
Chris@629 258
Chris@45 259 Document *m_document;
Chris@45 260 SVFileReaderPaneCallback &m_paneCallback;
Chris@45 261 QString m_location;
Chris@45 262 Pane *m_currentPane;
Chris@685 263 std::map<ExportId, Layer *> m_layers;
Chris@685 264 std::map<ExportId, ModelId> m_models;
Chris@685 265 std::map<ExportId, Path *> m_paths;
Chris@685 266 std::set<ModelId> m_addedModels; // i.e. added to Document, not just ById
Chris@685 267 std::map<ExportId, PendingAggregateRec> m_pendingAggregates;
Chris@685 268
Chris@685 269 // A model element often contains a dataset id, and the dataset
Chris@685 270 // then follows it. When the model is read, an entry in this map
Chris@685 271 // is added, mapping from the dataset's export id (the actual
Chris@685 272 // dataset has not been read yet) back to the export id of the
Chris@685 273 // object that needs it. We map to export id rather than model id,
Chris@685 274 // because the object might be a path rather than a model.
Chris@685 275 std::map<ExportId, ExportId> m_awaitingDatasets;
Chris@685 276
Chris@685 277 // And then this is the model or path that a dataset element is
Chris@685 278 // currently being read into, i.e. the value looked up from
Chris@685 279 // m_awaitingDatasets at the point where the dataset is found.
Chris@685 280 ExportId m_currentDataset;
Chris@685 281
Chris@45 282 Layer *m_currentLayer;
Chris@685 283 ModelId m_currentDerivedModel;
Chris@685 284 ExportId m_pendingDerivedModel;
Chris@686 285 std::shared_ptr<PlayParameters> m_currentPlayParameters;
Chris@72 286 Transform m_currentTransform;
Chris@685 287 ModelId m_currentTransformSource;
Chris@72 288 int m_currentTransformChannel;
Chris@72 289 bool m_currentTransformIsNewStyle;
Chris@45 290 QString m_datasetSeparator;
Chris@45 291 bool m_inRow;
Chris@45 292 bool m_inLayer;
Chris@45 293 bool m_inView;
Chris@45 294 bool m_inData;
Chris@45 295 bool m_inSelections;
Chris@45 296 int m_rowNumber;
Chris@45 297 QString m_errorString;
Chris@45 298 bool m_ok;
Chris@45 299 };
Chris@45 300
Chris@45 301 #endif