annotate data/model/Model.h @ 823:f0558e69a074

Rename Resampling- to DecodingWavFileReader, and use it whenever we have an audio file that is not quickly seekable using libsndfile. Avoids very slow performance when analysing ogg files.
author Chris Cannam
date Wed, 17 Jul 2013 15:40:01 +0100
parents 1d7ebc05157e
children 33fca917c800
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@150 16 #ifndef _MODEL_H_
Chris@150 17 #define _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@150 24
Chris@290 25 typedef std::vector<float> SampleBlock;
Chris@290 26
Chris@179 27 class ZoomConstraint;
Chris@319 28 class AlignmentModel;
Chris@179 29
Chris@150 30 /**
Chris@150 31 * Model is the base class for all data models that represent any sort
Chris@150 32 * of data on a time scale based on an audio frame rate.
Chris@150 33 */
Chris@150 34
Chris@179 35 class Model : public QObject,
Chris@391 36 public XmlExportable,
Chris@391 37 public Playable
Chris@150 38 {
Chris@150 39 Q_OBJECT
Chris@150 40
Chris@150 41 public:
Chris@150 42 virtual ~Model();
Chris@150 43
Chris@150 44 /**
Chris@150 45 * Return true if the model was constructed successfully. Classes
Chris@150 46 * that refer to the model should always test this before use.
Chris@150 47 */
Chris@150 48 virtual bool isOK() const = 0;
Chris@150 49
Chris@150 50 /**
Chris@150 51 * Return the first audio frame spanned by the model.
Chris@150 52 */
Chris@150 53 virtual size_t getStartFrame() const = 0;
Chris@150 54
Chris@150 55 /**
Chris@150 56 * Return the last audio frame spanned by the model.
Chris@150 57 */
Chris@150 58 virtual size_t getEndFrame() const = 0;
Chris@150 59
Chris@150 60 /**
Chris@150 61 * Return the frame rate in frames per second.
Chris@150 62 */
Chris@150 63 virtual size_t getSampleRate() const = 0;
Chris@150 64
Chris@150 65 /**
Chris@297 66 * Return the frame rate of the underlying material, if the model
Chris@297 67 * itself has already been resampled.
Chris@297 68 */
Chris@297 69 virtual size_t getNativeRate() const { return getSampleRate(); }
Chris@297 70
Chris@297 71 /**
Chris@333 72 * Return the "work title" of the model, if known.
Chris@333 73 */
Chris@333 74 virtual QString getTitle() const;
Chris@333 75
Chris@333 76 /**
Chris@333 77 * Return the "artist" or "maker" of the model, if known.
Chris@333 78 */
Chris@333 79 virtual QString getMaker() const;
Chris@333 80
Chris@333 81 /**
Chris@345 82 * Return the location of the data in this model (e.g. source
Chris@345 83 * URL). This should not normally be returned for editable models
Chris@345 84 * that have been edited.
Chris@345 85 */
Chris@345 86 virtual QString getLocation() const;
Chris@345 87
Chris@345 88 /**
Chris@345 89 * Return the type of the model. For display purposes only.
Chris@345 90 */
Chris@345 91 virtual QString getTypeName() const = 0;
Chris@345 92
Chris@345 93 /**
Chris@150 94 * Return a copy of this model.
Chris@150 95 *
Chris@150 96 * If the model is not editable, this may be effectively a shallow
Chris@150 97 * copy. If the model is editable, however, this operation must
Chris@150 98 * properly copy all of the model's editable data.
Chris@150 99 *
Chris@150 100 * In general this operation is not useful for non-editable dense
Chris@150 101 * models such as waveforms, because there may be no efficient
Chris@150 102 * copy operation implemented -- for such models it is better not
Chris@150 103 * to copy at all.
Chris@150 104 *
Chris@150 105 * Caller owns the returned value.
Chris@150 106 */
Chris@150 107 virtual Model *clone() const = 0;
Chris@150 108
Chris@150 109 /**
Chris@150 110 * Return true if the model has finished loading or calculating
Chris@150 111 * all its data, for a model that is capable of calculating in a
Chris@150 112 * background thread. The default implementation is appropriate
Chris@150 113 * for a thread that does not background any work but carries out
Chris@150 114 * all its calculation from the constructor or accessors.
Chris@150 115 *
Chris@150 116 * If "completion" is non-NULL, this function should return
Chris@150 117 * through it an estimated percentage value showing how far
Chris@150 118 * through the background operation it thinks it is (for progress
Chris@150 119 * reporting). If it has no way to calculate progress, it may
Chris@150 120 * return the special value COMPLETION_UNKNOWN.
Chris@150 121 */
Chris@150 122 virtual bool isReady(int *completion = 0) const {
Chris@150 123 bool ok = isOK();
Chris@150 124 if (completion) *completion = (ok ? 100 : 0);
Chris@150 125 return ok;
Chris@150 126 }
Chris@150 127 static const int COMPLETION_UNKNOWN;
Chris@150 128
Chris@179 129 /**
Chris@179 130 * If this model imposes a zoom constraint, i.e. some limit to the
Chris@179 131 * set of resolutions at which its data can meaningfully be
Chris@179 132 * displayed, then return it.
Chris@179 133 */
Chris@179 134 virtual const ZoomConstraint *getZoomConstraint() const {
Chris@179 135 return 0;
Chris@179 136 }
Chris@179 137
Chris@297 138 /**
Chris@297 139 * If this model was derived from another, return the model it was
Chris@297 140 * derived from. The assumption is that the source model's
Chris@297 141 * alignment will also apply to this model, unless some other
Chris@319 142 * property (such as a specific alignment model set on this model)
Chris@319 143 * indicates otherwise.
Chris@297 144 */
Chris@297 145 virtual Model *getSourceModel() const {
Chris@297 146 return m_sourceModel;
Chris@297 147 }
Chris@297 148
Chris@297 149 /**
Chris@297 150 * Set the source model for this model.
Chris@297 151 */
Chris@319 152 virtual void setSourceModel(Model *model);
Chris@319 153
Chris@319 154 /**
Chris@319 155 * Specify an aligment between this model's timeline and that of a
Chris@319 156 * reference model. The alignment model records both the
Chris@319 157 * reference and the alignment. This model takes ownership of the
Chris@319 158 * alignment model.
Chris@319 159 */
Chris@319 160 virtual void setAlignment(AlignmentModel *alignment);
Chris@319 161
Chris@319 162 /**
Chris@407 163 * Retrieve the alignment model for this model. This is not a
Chris@407 164 * generally useful function, as the alignment you really want may
Chris@407 165 * be performed by the source model instead. You should normally
Chris@407 166 * use getAlignmentReference, alignToReference and
Chris@407 167 * alignFromReference instead of this. The main intended
Chris@407 168 * application for this function is in streaming out alignments to
Chris@407 169 * the session file.
Chris@407 170 */
Chris@407 171 virtual const AlignmentModel *getAlignment() const;
Chris@407 172
Chris@407 173 /**
Chris@319 174 * Return the reference model for the current alignment timeline,
Chris@319 175 * if any.
Chris@319 176 */
Chris@319 177 virtual const Model *getAlignmentReference() const;
Chris@319 178
Chris@319 179 /**
Chris@319 180 * Return the frame number of the reference model that corresponds
Chris@319 181 * to the given frame number in this model.
Chris@319 182 */
Chris@319 183 virtual size_t alignToReference(size_t frame) const;
Chris@319 184
Chris@319 185 /**
Chris@319 186 * Return the frame number in this model that corresponds to the
Chris@319 187 * given frame number of the reference model.
Chris@319 188 */
Chris@319 189 virtual size_t alignFromReference(size_t referenceFrame) const;
Chris@319 190
Chris@319 191 /**
Chris@319 192 * Return the completion percentage for the alignment model: 100
Chris@319 193 * if there is no alignment model or it has been entirely
Chris@319 194 * calculated, or less than 100 if it is still being calculated.
Chris@319 195 */
Chris@319 196 virtual int getAlignmentCompletion() const;
Chris@297 197
Chris@558 198 /**
Chris@558 199 * Set the event, feature, or signal type URI for the features
Chris@558 200 * contained in this model, according to the Audio Features RDF
Chris@558 201 * ontology.
Chris@558 202 */
Chris@558 203 void setRDFTypeURI(QString uri) { m_typeUri = uri; }
Chris@558 204
Chris@558 205 /**
Chris@558 206 * Retrieve the event, feature, or signal type URI for the
Chris@558 207 * features contained in this model, if previously set with
Chris@558 208 * setRDFTypeURI.
Chris@558 209 */
Chris@558 210 QString getRDFTypeURI() const { return m_typeUri; }
Chris@558 211
Chris@150 212 virtual void toXml(QTextStream &stream,
Chris@150 213 QString indent = "",
Chris@150 214 QString extraAttributes = "") const;
Chris@150 215
Chris@150 216 virtual QString toDelimitedDataString(QString) const { return ""; }
Chris@150 217
Chris@319 218 public slots:
Chris@319 219 void aboutToDelete();
Chris@319 220 void sourceModelAboutToBeDeleted();
Chris@319 221
Chris@150 222 signals:
Chris@150 223 /**
Chris@150 224 * Emitted when a model has been edited (or more data retrieved
Chris@150 225 * from cache, in the case of a cached model that generates slowly)
Chris@150 226 */
Chris@150 227 void modelChanged();
Chris@150 228
Chris@150 229 /**
Chris@150 230 * Emitted when a model has been edited (or more data retrieved
Chris@150 231 * from cache, in the case of a cached model that generates slowly)
Chris@150 232 */
Chris@150 233 void modelChanged(size_t startFrame, size_t endFrame);
Chris@150 234
Chris@150 235 /**
Chris@150 236 * Emitted when some internal processing has advanced a stage, but
Chris@150 237 * the model has not changed externally. Views should respond by
Chris@150 238 * updating any progress meters or other monitoring, but not
Chris@150 239 * refreshing the actual view.
Chris@150 240 */
Chris@150 241 void completionChanged();
Chris@150 242
Chris@319 243 /**
Chris@411 244 * Emitted when internal processing is complete (i.e. when
Chris@411 245 * isReady() would return true, with completion at 100).
Chris@411 246 */
Chris@411 247 void ready();
Chris@411 248
Chris@411 249 /**
Chris@319 250 * Emitted when the completion percentage changes for the
Chris@319 251 * calculation of this model's alignment model.
Chris@319 252 */
Chris@319 253 void alignmentCompletionChanged();
Chris@319 254
Chris@319 255 /**
Chris@319 256 * Emitted when something notifies this model (through calling
Chris@319 257 * aboutToDelete() that it is about to delete it. Note that this
Chris@319 258 * depends on an external agent such as a Document object or
Chris@319 259 * owning model telling the model that it is about to delete it;
Chris@319 260 * there is nothing in the model to guarantee that this signal
Chris@319 261 * will be emitted before the actual deletion.
Chris@319 262 */
Chris@319 263 void aboutToBeDeleted();
Chris@319 264
Chris@150 265 protected:
Chris@319 266 Model() : m_sourceModel(0), m_alignment(0), m_aboutToDelete(false) { }
Chris@150 267
Chris@150 268 // Not provided.
Chris@150 269 Model(const Model &);
Chris@150 270 Model &operator=(const Model &);
Chris@297 271
Chris@297 272 Model *m_sourceModel;
Chris@319 273 AlignmentModel *m_alignment;
Chris@558 274 QString m_typeUri;
Chris@319 275 bool m_aboutToDelete;
Chris@150 276 };
Chris@150 277
Chris@150 278 #endif