annotate data/model/Model.h @ 1777:d484490cdf69

Split EditableDenseThreeDimensionalModel into explicitly compressed and uncompressed variants. Simplifies the uncompressed version, and we may want to consider whether we need the compressed one at all.
author Chris Cannam
date Tue, 10 Sep 2019 16:34:47 +0100
parents aa0b56d72f27
children 13bd41bd8a17
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@1731 22 #include "base/ById.h"
Chris@150 23 #include "base/XmlExportable.h"
Chris@391 24 #include "base/Playable.h"
Chris@1038 25 #include "base/BaseTypes.h"
Chris@1060 26 #include "base/DataExportOptions.h"
Chris@150 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@179 35 class Model : public QObject,
Chris@1742 36 public WithTypedId<Model>,
Chris@1429 37 public XmlExportable,
Chris@391 38 public Playable
Chris@150 39 {
Chris@150 40 Q_OBJECT
Chris@150 41
Chris@150 42 public:
Chris@1735 43 typedef Id ModelId;
Chris@1735 44
Chris@150 45 virtual ~Model();
Chris@150 46
Chris@150 47 /**
Chris@150 48 * Return true if the model was constructed successfully. Classes
Chris@150 49 * that refer to the model should always test this before use.
Chris@150 50 */
Chris@150 51 virtual bool isOK() const = 0;
Chris@150 52
Chris@150 53 /**
Chris@150 54 * Return the first audio frame spanned by the model.
Chris@150 55 */
Chris@1038 56 virtual sv_frame_t getStartFrame() const = 0;
Chris@150 57
Chris@150 58 /**
Chris@1611 59 * Return the audio frame at the end of the model, i.e. the final
Chris@1659 60 * frame contained within the model plus 1 (rounded up to the
Chris@1659 61 * model's "resolution" granularity, if more than 1). The end
Chris@1659 62 * frame minus the start frame should yield the total duration in
Chris@1659 63 * frames (as a multiple of the resolution) spanned by the
Chris@1659 64 * model. This is broadly consistent with the definition of the
Chris@1659 65 * end frame of a Selection object.
Chris@1725 66 *
Chris@1725 67 * If the end has been extended by extendEndFrame() beyond the
Chris@1725 68 * true end frame, return the extended end instead. This is
Chris@1725 69 * usually the behaviour you want.
Chris@150 70 */
Chris@1725 71 sv_frame_t getEndFrame() const {
Chris@1725 72 sv_frame_t trueEnd = getTrueEndFrame();
Chris@1725 73 if (m_extendTo > trueEnd) {
Chris@1725 74 return m_extendTo;
Chris@1725 75 } else {
Chris@1725 76 return trueEnd;
Chris@1725 77 }
Chris@1725 78 }
Chris@1725 79
Chris@1725 80 /**
Chris@1725 81 * Return the audio frame at the end of the model. This is
Chris@1725 82 * identical to getEndFrame(), except that it ignores any extended
Chris@1725 83 * duration set with extendEndFrame().
Chris@1725 84 */
Chris@1725 85 virtual sv_frame_t getTrueEndFrame() const = 0;
Chris@1725 86
Chris@1725 87 /**
Chris@1725 88 * Extend the end of the model. If this is set to something beyond
Chris@1725 89 * the true end of the data within the model, then getEndFrame()
Chris@1725 90 * will return this value instead of the true end. (This is used
Chris@1725 91 * by the Tony application.)
Chris@1725 92 */
Chris@1725 93 void extendEndFrame(sv_frame_t to) {
Chris@1725 94 m_extendTo = to;
Chris@1725 95 }
Chris@150 96
Chris@150 97 /**
Chris@150 98 * Return the frame rate in frames per second.
Chris@150 99 */
Chris@1040 100 virtual sv_samplerate_t getSampleRate() const = 0;
Chris@150 101
Chris@150 102 /**
Chris@297 103 * Return the frame rate of the underlying material, if the model
Chris@297 104 * itself has already been resampled.
Chris@297 105 */
Chris@1040 106 virtual sv_samplerate_t getNativeRate() const { return getSampleRate(); }
Chris@297 107
Chris@297 108 /**
Chris@333 109 * Return the "work title" of the model, if known.
Chris@333 110 */
Chris@333 111 virtual QString getTitle() const;
Chris@333 112
Chris@333 113 /**
Chris@333 114 * Return the "artist" or "maker" of the model, if known.
Chris@333 115 */
Chris@333 116 virtual QString getMaker() const;
Chris@333 117
Chris@333 118 /**
Chris@345 119 * Return the location of the data in this model (e.g. source
Chris@345 120 * URL). This should not normally be returned for editable models
Chris@345 121 * that have been edited.
Chris@345 122 */
Chris@345 123 virtual QString getLocation() const;
Chris@345 124
Chris@345 125 /**
Chris@345 126 * Return the type of the model. For display purposes only.
Chris@345 127 */
Chris@345 128 virtual QString getTypeName() const = 0;
Chris@345 129
Chris@345 130 /**
cannam@1452 131 * Return true if this is a sparse model.
cannam@1452 132 */
cannam@1452 133 virtual bool isSparse() const { return false; }
Chris@1500 134
Chris@1500 135 /**
Chris@150 136 * Return true if the model has finished loading or calculating
Chris@150 137 * all its data, for a model that is capable of calculating in a
Chris@1671 138 * background thread.
Chris@150 139 *
Chris@1671 140 * If "completion" is non-NULL, return through it an estimated
Chris@1671 141 * percentage value showing how far through the background
Chris@1671 142 * operation it thinks it is (for progress reporting). This should
Chris@1671 143 * be identical to the value returned by getCompletion().
Chris@1671 144 *
Chris@1671 145 * A model that carries out all its calculation from the
Chris@1671 146 * constructor or accessor functions would typically return true
Chris@1671 147 * (and completion == 100) as long as isOK() is true. Other models
Chris@1671 148 * may make the return value here depend on the internal
Chris@1671 149 * completion status.
Chris@1669 150 *
Chris@1669 151 * See also getCompletion().
Chris@150 152 */
Chris@1671 153 virtual bool isReady(int *cp = nullptr) const {
Chris@1671 154 int c = getCompletion();
Chris@1671 155 if (cp) *cp = c;
Chris@1671 156 if (!isOK()) return false;
Chris@1671 157 else return (c == 100);
Chris@150 158 }
Chris@1671 159
Chris@1671 160 /**
Chris@1671 161 * Return an estimated percentage value showing how far through
Chris@1671 162 * any background operation used to calculate or load the model
Chris@1671 163 * data the model thinks it is. Must return 100 when the model is
Chris@1671 164 * complete.
Chris@1671 165 *
Chris@1671 166 * A model that carries out all its calculation from the
Chris@1671 167 * constructor or accessor functions might return 0 if isOK() is
Chris@1671 168 * false and 100 if isOK() is true. Other models may make the
Chris@1671 169 * return value here depend on the internal completion status.
Chris@1671 170 *
Chris@1671 171 * See also isReady().
Chris@1671 172 */
Chris@1671 173 virtual int getCompletion() const = 0;
Chris@150 174
Chris@179 175 /**
Chris@179 176 * If this model imposes a zoom constraint, i.e. some limit to the
Chris@179 177 * set of resolutions at which its data can meaningfully be
Chris@179 178 * displayed, then return it.
Chris@179 179 */
Chris@179 180 virtual const ZoomConstraint *getZoomConstraint() const {
Chris@179 181 return 0;
Chris@179 182 }
Chris@179 183
Chris@297 184 /**
Chris@1735 185 * If this model was derived from another, return the id of the
Chris@1735 186 * model it was derived from. The assumption is that the source
Chris@1735 187 * model's alignment will also apply to this model, unless some
Chris@1735 188 * other property (such as a specific alignment model set on this
Chris@1735 189 * model) indicates otherwise.
Chris@297 190 */
Chris@1735 191 virtual ModelId getSourceModel() const {
Chris@297 192 return m_sourceModel;
Chris@297 193 }
Chris@297 194
Chris@297 195 /**
Chris@297 196 * Set the source model for this model.
Chris@297 197 */
Chris@1735 198 virtual void setSourceModel(ModelId model);
Chris@319 199
Chris@319 200 /**
Chris@1735 201 * Specify an alignment between this model's timeline and that of
Chris@1735 202 * a reference model. The alignment model, of type AlignmentModel,
Chris@1761 203 * records both the reference and the alignment.
Chris@319 204 */
Chris@1735 205 virtual void setAlignment(ModelId alignmentModel);
Chris@319 206
Chris@319 207 /**
Chris@407 208 * Retrieve the alignment model for this model. This is not a
Chris@407 209 * generally useful function, as the alignment you really want may
Chris@407 210 * be performed by the source model instead. You should normally
Chris@407 211 * use getAlignmentReference, alignToReference and
Chris@407 212 * alignFromReference instead of this. The main intended
Chris@407 213 * application for this function is in streaming out alignments to
Chris@407 214 * the session file.
Chris@407 215 */
Chris@1735 216 virtual const ModelId getAlignment() const;
Chris@407 217
Chris@407 218 /**
Chris@319 219 * Return the reference model for the current alignment timeline,
Chris@319 220 * if any.
Chris@319 221 */
Chris@1735 222 virtual const ModelId getAlignmentReference() const;
Chris@319 223
Chris@319 224 /**
Chris@319 225 * Return the frame number of the reference model that corresponds
Chris@319 226 * to the given frame number in this model.
Chris@319 227 */
Chris@1038 228 virtual sv_frame_t alignToReference(sv_frame_t frame) const;
Chris@319 229
Chris@319 230 /**
Chris@319 231 * Return the frame number in this model that corresponds to the
Chris@319 232 * given frame number of the reference model.
Chris@319 233 */
Chris@1038 234 virtual sv_frame_t alignFromReference(sv_frame_t referenceFrame) const;
Chris@319 235
Chris@319 236 /**
Chris@319 237 * Return the completion percentage for the alignment model: 100
Chris@319 238 * if there is no alignment model or it has been entirely
Chris@319 239 * calculated, or less than 100 if it is still being calculated.
Chris@319 240 */
Chris@319 241 virtual int getAlignmentCompletion() const;
Chris@297 242
Chris@558 243 /**
Chris@558 244 * Set the event, feature, or signal type URI for the features
Chris@558 245 * contained in this model, according to the Audio Features RDF
Chris@558 246 * ontology.
Chris@558 247 */
Chris@558 248 void setRDFTypeURI(QString uri) { m_typeUri = uri; }
Chris@558 249
Chris@558 250 /**
Chris@558 251 * Retrieve the event, feature, or signal type URI for the
Chris@558 252 * features contained in this model, if previously set with
Chris@558 253 * setRDFTypeURI.
Chris@558 254 */
Chris@558 255 QString getRDFTypeURI() const { return m_typeUri; }
Chris@558 256
Chris@1580 257 void toXml(QTextStream &stream,
Chris@1608 258 QString indent = "",
Chris@1608 259 QString extraAttributes = "") const override;
Chris@150 260
Chris@1679 261 virtual QString toDelimitedDataString(QString delimiter,
Chris@1679 262 DataExportOptions options,
Chris@1679 263 sv_frame_t startFrame,
Chris@1679 264 sv_frame_t duration) const = 0;
Chris@150 265
Chris@150 266 signals:
Chris@150 267 /**
Chris@150 268 * Emitted when a model has been edited (or more data retrieved
Chris@150 269 * from cache, in the case of a cached model that generates slowly)
Chris@150 270 */
Chris@1752 271 void modelChanged(ModelId myId);
Chris@150 272
Chris@150 273 /**
Chris@150 274 * Emitted when a model has been edited (or more data retrieved
Chris@150 275 * from cache, in the case of a cached model that generates slowly)
Chris@150 276 */
Chris@1752 277 void modelChangedWithin(ModelId myId, sv_frame_t startFrame, sv_frame_t endFrame);
Chris@150 278
Chris@150 279 /**
Chris@150 280 * Emitted when some internal processing has advanced a stage, but
Chris@150 281 * the model has not changed externally. Views should respond by
Chris@150 282 * updating any progress meters or other monitoring, but not
Chris@150 283 * refreshing the actual view.
Chris@150 284 */
Chris@1752 285 void completionChanged(ModelId myId);
Chris@150 286
Chris@319 287 /**
Chris@411 288 * Emitted when internal processing is complete (i.e. when
Chris@411 289 * isReady() would return true, with completion at 100).
Chris@411 290 */
Chris@1752 291 void ready(ModelId myId);
Chris@411 292
Chris@411 293 /**
Chris@319 294 * Emitted when the completion percentage changes for the
Chris@1767 295 * calculation of this model's alignment model. (The ModelId
Chris@1767 296 * provided is that of this model, not the alignment model.)
Chris@319 297 */
Chris@1752 298 void alignmentCompletionChanged(ModelId myId);
Chris@319 299
Chris@1767 300 private slots:
Chris@1767 301 void alignmentModelCompletionChanged(ModelId);
Chris@1767 302
Chris@150 303 protected:
Chris@1500 304 Model() :
Chris@1725 305 m_extendTo(0) { }
Chris@150 306
Chris@150 307 // Not provided.
Chris@1735 308 Model(const Model &) =delete;
Chris@1735 309 Model &operator=(const Model &) =delete;
Chris@297 310
Chris@1735 311 ModelId m_sourceModel;
Chris@1735 312 ModelId m_alignmentModel;
Chris@558 313 QString m_typeUri;
Chris@1725 314 sv_frame_t m_extendTo;
Chris@150 315 };
Chris@150 316
Chris@1741 317 typedef Model::Id ModelId;
Chris@1742 318 typedef TypedById<Model, Model::Id> ModelById;
Chris@1731 319
Chris@150 320 #endif