annotate data/model/Model.h @ 1061:c1e43c8d2527 tonioni

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