annotate framework/SVFileReader.h @ 771:1d6cca5a5621 pitch-align

Allow use of proper sparse models (i.e. retaining event time info) in alignment; use this to switch to note alignment, which is what we have most recently been doing in the external program. Not currently producing correct results, though
author Chris Cannam
date Fri, 29 May 2020 17:39:02 +0100
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