annotate data/model/Model.h @ 1520:954d0cf29ca7 import-audio-data

Switch the normalisation option in WritableWaveFileModel from normalising on read to normalising on write, so that the saved file is already normalised and therefore can be read again without having to remember to normalise it
author Chris Cannam
date Wed, 12 Sep 2018 13:56:56 +0100
parents 9d37c8cf9686
children c01cbe41aeb5
rev   line source
Chris@150 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@150 2
Chris@150 3 /*
Chris@150 4 Sonic Visualiser
Chris@150 5 An audio file viewer and annotation editor.
Chris@150 6 Centre for Digital Music, Queen Mary, University of London.
Chris@150 7 This file copyright 2006 Chris Cannam.
Chris@150 8
Chris@150 9 This program is free software; you can redistribute it and/or
Chris@150 10 modify it under the terms of the GNU General Public License as
Chris@150 11 published by the Free Software Foundation; either version 2 of the
Chris@150 12 License, or (at your option) any later version. See the file
Chris@150 13 COPYING included with this distribution for more information.
Chris@150 14 */
Chris@150 15
Chris@1500 16 #ifndef SV_MODEL_H
Chris@1500 17 #define SV_MODEL_H
Chris@150 18
Chris@150 19 #include <vector>
Chris@150 20 #include <QObject>
Chris@150 21
Chris@150 22 #include "base/XmlExportable.h"
Chris@391 23 #include "base/Playable.h"
Chris@1038 24 #include "base/BaseTypes.h"
Chris@1060 25 #include "base/DataExportOptions.h"
Chris@150 26
Chris@179 27 class ZoomConstraint;
Chris@319 28 class AlignmentModel;
Chris@179 29
Chris@1500 30 typedef int ModelId;
Chris@1500 31
Chris@150 32 /**
Chris@150 33 * Model is the base class for all data models that represent any sort
Chris@150 34 * of data on a time scale based on an audio frame rate.
Chris@150 35 */
Chris@150 36
Chris@179 37 class Model : public QObject,
Chris@1429 38 public XmlExportable,
Chris@391 39 public Playable
Chris@150 40 {
Chris@150 41 Q_OBJECT
Chris@150 42
Chris@150 43 public:
Chris@150 44 virtual ~Model();
Chris@150 45
Chris@150 46 /**
Chris@150 47 * Return true if the model was constructed successfully. Classes
Chris@150 48 * that refer to the model should always test this before use.
Chris@150 49 */
Chris@150 50 virtual bool isOK() const = 0;
Chris@150 51
Chris@150 52 /**
Chris@150 53 * Return the first audio frame spanned by the model.
Chris@150 54 */
Chris@1038 55 virtual sv_frame_t getStartFrame() const = 0;
Chris@150 56
Chris@150 57 /**
Chris@1451 58 * Return the audio frame at the end of the model, i.e. 1 more
Chris@1451 59 * than the final frame contained within the model. The end frame
Chris@1451 60 * minus the start frame should yield the total duration in frames
Chris@1451 61 * spanned by the model. This is consistent with the definition of
Chris@1451 62 * the end frame of a Selection object.
Chris@150 63 */
Chris@1038 64 virtual sv_frame_t getEndFrame() const = 0;
Chris@150 65
Chris@150 66 /**
Chris@150 67 * Return the frame rate in frames per second.
Chris@150 68 */
Chris@1040 69 virtual sv_samplerate_t getSampleRate() const = 0;
Chris@150 70
Chris@150 71 /**
Chris@297 72 * Return the frame rate of the underlying material, if the model
Chris@297 73 * itself has already been resampled.
Chris@297 74 */
Chris@1040 75 virtual sv_samplerate_t getNativeRate() const { return getSampleRate(); }
Chris@297 76
Chris@297 77 /**
Chris@333 78 * Return the "work title" of the model, if known.
Chris@333 79 */
Chris@333 80 virtual QString getTitle() const;
Chris@333 81
Chris@333 82 /**
Chris@333 83 * Return the "artist" or "maker" of the model, if known.
Chris@333 84 */
Chris@333 85 virtual QString getMaker() const;
Chris@333 86
Chris@333 87 /**
Chris@345 88 * Return the location of the data in this model (e.g. source
Chris@345 89 * URL). This should not normally be returned for editable models
Chris@345 90 * that have been edited.
Chris@345 91 */
Chris@345 92 virtual QString getLocation() const;
Chris@345 93
Chris@345 94 /**
Chris@345 95 * Return the type of the model. For display purposes only.
Chris@345 96 */
Chris@345 97 virtual QString getTypeName() const = 0;
Chris@345 98
Chris@345 99 /**
cannam@1452 100 * Return true if this is a sparse model.
cannam@1452 101 */
cannam@1452 102 virtual bool isSparse() const { return false; }
Chris@1500 103
Chris@1500 104 /**
Chris@1500 105 * Return an id for this model. The id is guaranteed to be a
Chris@1500 106 * unique identifier for this model among all models that may ever
Chris@1500 107 * exist within this single run of the application.
Chris@1500 108 */
Chris@1500 109 ModelId getId() const { return m_id; }
cannam@1452 110
cannam@1452 111 /**
Chris@923 112 * Mark the model as abandoning. This means that the application
Chris@923 113 * no longer needs it, so it can stop doing any background
Chris@923 114 * calculations it may be involved in. Note that as far as the
Chris@923 115 * model API is concerned, this does nothing more than tell the
Chris@923 116 * model to return true from isAbandoning(). The actual response
Chris@923 117 * to this will depend on the model's context -- it's possible
Chris@923 118 * nothing at all will change.
Chris@923 119 */
Chris@923 120 virtual void abandon() {
Chris@923 121 m_abandoning = true;
Chris@923 122 }
Chris@923 123
Chris@923 124 /**
Chris@923 125 * Query whether the model has been marked as abandoning.
Chris@923 126 */
Chris@923 127 virtual bool isAbandoning() const {
Chris@923 128 return m_abandoning;
Chris@923 129 }
Chris@923 130
Chris@150 131 /**
Chris@150 132 * Return true if the model has finished loading or calculating
Chris@150 133 * all its data, for a model that is capable of calculating in a
Chris@150 134 * background thread. The default implementation is appropriate
Chris@150 135 * for a thread that does not background any work but carries out
Chris@150 136 * all its calculation from the constructor or accessors.
Chris@150 137 *
Chris@150 138 * If "completion" is non-NULL, this function should return
Chris@150 139 * through it an estimated percentage value showing how far
Chris@150 140 * through the background operation it thinks it is (for progress
Chris@150 141 * reporting). If it has no way to calculate progress, it may
Chris@1133 142 * return the special value COMPLETION_UNKNOWN. See also
Chris@1133 143 * getCompletion().
Chris@150 144 */
Chris@150 145 virtual bool isReady(int *completion = 0) const {
Chris@1429 146 bool ok = isOK();
Chris@1429 147 if (completion) *completion = (ok ? 100 : 0);
Chris@1429 148 return ok;
Chris@150 149 }
Chris@150 150 static const int COMPLETION_UNKNOWN;
Chris@150 151
Chris@179 152 /**
Chris@179 153 * If this model imposes a zoom constraint, i.e. some limit to the
Chris@179 154 * set of resolutions at which its data can meaningfully be
Chris@179 155 * displayed, then return it.
Chris@179 156 */
Chris@179 157 virtual const ZoomConstraint *getZoomConstraint() const {
Chris@179 158 return 0;
Chris@179 159 }
Chris@179 160
Chris@297 161 /**
Chris@297 162 * If this model was derived from another, return the model it was
Chris@297 163 * derived from. The assumption is that the source model's
Chris@297 164 * alignment will also apply to this model, unless some other
Chris@319 165 * property (such as a specific alignment model set on this model)
Chris@319 166 * indicates otherwise.
Chris@297 167 */
Chris@297 168 virtual Model *getSourceModel() const {
Chris@297 169 return m_sourceModel;
Chris@297 170 }
Chris@297 171
Chris@297 172 /**
Chris@297 173 * Set the source model for this model.
Chris@297 174 */
Chris@319 175 virtual void setSourceModel(Model *model);
Chris@319 176
Chris@319 177 /**
Chris@319 178 * Specify an aligment between this model's timeline and that of a
Chris@319 179 * reference model. The alignment model records both the
Chris@319 180 * reference and the alignment. This model takes ownership of the
Chris@319 181 * alignment model.
Chris@319 182 */
Chris@319 183 virtual void setAlignment(AlignmentModel *alignment);
Chris@319 184
Chris@319 185 /**
Chris@407 186 * Retrieve the alignment model for this model. This is not a
Chris@407 187 * generally useful function, as the alignment you really want may
Chris@407 188 * be performed by the source model instead. You should normally
Chris@407 189 * use getAlignmentReference, alignToReference and
Chris@407 190 * alignFromReference instead of this. The main intended
Chris@407 191 * application for this function is in streaming out alignments to
Chris@407 192 * the session file.
Chris@407 193 */
Chris@407 194 virtual const AlignmentModel *getAlignment() const;
Chris@407 195
Chris@407 196 /**
Chris@319 197 * Return the reference model for the current alignment timeline,
Chris@319 198 * if any.
Chris@319 199 */
Chris@319 200 virtual const Model *getAlignmentReference() const;
Chris@319 201
Chris@319 202 /**
Chris@319 203 * Return the frame number of the reference model that corresponds
Chris@319 204 * to the given frame number in this model.
Chris@319 205 */
Chris@1038 206 virtual sv_frame_t alignToReference(sv_frame_t frame) const;
Chris@319 207
Chris@319 208 /**
Chris@319 209 * Return the frame number in this model that corresponds to the
Chris@319 210 * given frame number of the reference model.
Chris@319 211 */
Chris@1038 212 virtual sv_frame_t alignFromReference(sv_frame_t referenceFrame) const;
Chris@319 213
Chris@319 214 /**
Chris@319 215 * Return the completion percentage for the alignment model: 100
Chris@319 216 * if there is no alignment model or it has been entirely
Chris@319 217 * calculated, or less than 100 if it is still being calculated.
Chris@319 218 */
Chris@319 219 virtual int getAlignmentCompletion() const;
Chris@297 220
Chris@558 221 /**
Chris@558 222 * Set the event, feature, or signal type URI for the features
Chris@558 223 * contained in this model, according to the Audio Features RDF
Chris@558 224 * ontology.
Chris@558 225 */
Chris@558 226 void setRDFTypeURI(QString uri) { m_typeUri = uri; }
Chris@558 227
Chris@558 228 /**
Chris@558 229 * Retrieve the event, feature, or signal type URI for the
Chris@558 230 * features contained in this model, if previously set with
Chris@558 231 * setRDFTypeURI.
Chris@558 232 */
Chris@558 233 QString getRDFTypeURI() const { return m_typeUri; }
Chris@558 234
Chris@150 235 virtual void toXml(QTextStream &stream,
Chris@150 236 QString indent = "",
Chris@150 237 QString extraAttributes = "") const;
Chris@150 238
Chris@838 239 virtual QString toDelimitedDataString(QString delimiter) const {
Chris@1072 240 return toDelimitedDataStringSubset
Chris@1451 241 (delimiter, getStartFrame(), getEndFrame());
Chris@838 242 }
Chris@1060 243 virtual QString toDelimitedDataStringWithOptions(QString delimiter, DataExportOptions opts) const {
Chris@1072 244 return toDelimitedDataStringSubsetWithOptions
Chris@1451 245 (delimiter, opts, getStartFrame(), getEndFrame());
Chris@1060 246 }
Chris@1038 247 virtual QString toDelimitedDataStringSubset(QString, sv_frame_t /* f0 */, sv_frame_t /* f1 */) const {
Chris@838 248 return "";
Chris@838 249 }
Chris@1060 250 virtual QString toDelimitedDataStringSubsetWithOptions(QString delimiter, DataExportOptions, sv_frame_t f0, sv_frame_t f1) const {
Chris@1060 251 // Default implementation supports no options
Chris@1060 252 return toDelimitedDataStringSubset(delimiter, f0, f1);
Chris@1060 253 }
Chris@150 254
Chris@319 255 public slots:
Chris@319 256 void aboutToDelete();
Chris@319 257 void sourceModelAboutToBeDeleted();
Chris@319 258
Chris@150 259 signals:
Chris@150 260 /**
Chris@150 261 * Emitted when a model has been edited (or more data retrieved
Chris@150 262 * from cache, in the case of a cached model that generates slowly)
Chris@150 263 */
Chris@150 264 void modelChanged();
Chris@150 265
Chris@150 266 /**
Chris@150 267 * Emitted when a model has been edited (or more data retrieved
Chris@150 268 * from cache, in the case of a cached model that generates slowly)
Chris@150 269 */
Chris@1038 270 void modelChangedWithin(sv_frame_t startFrame, sv_frame_t endFrame);
Chris@150 271
Chris@150 272 /**
Chris@150 273 * Emitted when some internal processing has advanced a stage, but
Chris@150 274 * the model has not changed externally. Views should respond by
Chris@150 275 * updating any progress meters or other monitoring, but not
Chris@150 276 * refreshing the actual view.
Chris@150 277 */
Chris@150 278 void completionChanged();
Chris@150 279
Chris@319 280 /**
Chris@411 281 * Emitted when internal processing is complete (i.e. when
Chris@411 282 * isReady() would return true, with completion at 100).
Chris@411 283 */
Chris@411 284 void ready();
Chris@411 285
Chris@411 286 /**
Chris@319 287 * Emitted when the completion percentage changes for the
Chris@319 288 * calculation of this model's alignment model.
Chris@319 289 */
Chris@319 290 void alignmentCompletionChanged();
Chris@319 291
Chris@319 292 /**
Chris@319 293 * Emitted when something notifies this model (through calling
Chris@319 294 * aboutToDelete() that it is about to delete it. Note that this
Chris@319 295 * depends on an external agent such as a Document object or
Chris@319 296 * owning model telling the model that it is about to delete it;
Chris@319 297 * there is nothing in the model to guarantee that this signal
Chris@319 298 * will be emitted before the actual deletion.
Chris@319 299 */
Chris@319 300 void aboutToBeDeleted();
Chris@319 301
Chris@150 302 protected:
Chris@1500 303 Model() :
Chris@1500 304 m_id(getNextId()),
Chris@923 305 m_sourceModel(0),
Chris@923 306 m_alignment(0),
Chris@923 307 m_abandoning(false),
Chris@923 308 m_aboutToDelete(false) { }
Chris@150 309
Chris@150 310 // Not provided.
Chris@150 311 Model(const Model &);
Chris@150 312 Model &operator=(const Model &);
Chris@297 313
Chris@1500 314 const ModelId m_id;
Chris@297 315 Model *m_sourceModel;
Chris@319 316 AlignmentModel *m_alignment;
Chris@558 317 QString m_typeUri;
Chris@923 318 bool m_abandoning;
Chris@319 319 bool m_aboutToDelete;
Chris@1500 320
Chris@1500 321 int getNextId();
Chris@150 322 };
Chris@150 323
Chris@150 324 #endif