annotate layer/SpectrogramLayer.h @ 1212:a1ee3108d1d3 3.0-integration

Make the colour 3d plot renderer able to support more than one level of peak cache; introduce a second "peak" cache for the spectrogram layer that actually has a 1-1 column relationship with the underlying FFT model, and use it in addition to the existing peak cache if memory is plentiful. Makes spectrograms appear much faster in many common situations.
author Chris Cannam
date Thu, 05 Jan 2017 14:02:54 +0000
parents 7a19738b9762
children de1792daae07
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@1030 16 #ifndef SPECTROGRAM_LAYER_H
Chris@1030 17 #define SPECTROGRAM_LAYER_H
Chris@0 18
Chris@193 19 #include "SliceableLayer.h"
Chris@0 20 #include "base/Window.h"
Chris@1058 21 #include "base/MagnitudeRange.h"
Chris@71 22 #include "base/RealTime.h"
Chris@92 23 #include "base/Thread.h"
Chris@122 24 #include "base/PropertyContainer.h"
Chris@128 25 #include "data/model/PowerOfSqrtTwoZoomConstraint.h"
Chris@128 26 #include "data/model/DenseTimeValueModel.h"
Chris@130 27 #include "data/model/FFTModel.h"
Chris@0 28
Chris@1085 29 #include "VerticalBinLayer.h"
Chris@1092 30 #include "ColourScale.h"
Chris@1093 31 #include "Colour3DPlotRenderer.h"
Chris@1030 32
Chris@0 33 #include <QMutex>
Chris@0 34 #include <QWaitCondition>
Chris@95 35 #include <QImage>
Chris@95 36 #include <QPixmap>
Chris@0 37
Chris@0 38 class View;
Chris@0 39 class QPainter;
Chris@0 40 class QImage;
Chris@0 41 class QPixmap;
Chris@0 42 class QTimer;
Chris@130 43 class FFTModel;
Chris@484 44 class Dense3DModelPeakCache;
Chris@0 45
Chris@0 46 /**
Chris@0 47 * SpectrogramLayer represents waveform data (obtained from a
Chris@0 48 * DenseTimeValueModel) in spectrogram form.
Chris@0 49 */
Chris@0 50
Chris@1110 51 class SpectrogramLayer : public VerticalBinLayer,
Chris@31 52 public PowerOfSqrtTwoZoomConstraint
Chris@0 53 {
Chris@0 54 Q_OBJECT
Chris@0 55
Chris@0 56 public:
Chris@37 57 enum Configuration { FullRangeDb, MelodicRange, MelodicPeaks };
Chris@0 58
Chris@44 59 SpectrogramLayer(Configuration = FullRangeDb);
Chris@0 60 ~SpectrogramLayer();
Chris@0 61
Chris@0 62 virtual const ZoomConstraint *getZoomConstraint() const { return this; }
Chris@0 63 virtual const Model *getModel() const { return m_model; }
Chris@916 64 virtual void paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;
Chris@389 65 virtual void setSynchronousPainting(bool synchronous);
Chris@0 66
Chris@918 67 virtual int getVerticalScaleWidth(LayerGeometryProvider *v, bool detailed, QPainter &) const;
Chris@918 68 virtual void paintVerticalScale(LayerGeometryProvider *v, bool detailed, QPainter &paint, QRect rect) const;
Chris@0 69
Chris@918 70 virtual bool getCrosshairExtents(LayerGeometryProvider *, QPainter &, QPoint cursorPos,
Chris@77 71 std::vector<QRect> &extents) const;
Chris@918 72 virtual void paintCrosshairs(LayerGeometryProvider *, QPainter &, QPoint) const;
Chris@77 73
Chris@918 74 virtual QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const;
Chris@0 75
Chris@918 76 virtual bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
Chris@805 77 int &resolution,
Chris@28 78 SnapType snap) const;
Chris@13 79
Chris@918 80 virtual void measureDoubleClick(LayerGeometryProvider *, QMouseEvent *);
Chris@283 81
Chris@224 82 virtual bool hasLightBackground() const;
Chris@224 83
Chris@0 84 void setModel(const DenseTimeValueModel *model);
Chris@0 85
Chris@0 86 virtual PropertyList getProperties() const;
Chris@87 87 virtual QString getPropertyLabel(const PropertyName &) const;
Chris@335 88 virtual QString getPropertyIconName(const PropertyName &) const;
Chris@0 89 virtual PropertyType getPropertyType(const PropertyName &) const;
Chris@0 90 virtual QString getPropertyGroupName(const PropertyName &) const;
Chris@0 91 virtual int getPropertyRangeAndValue(const PropertyName &,
Chris@216 92 int *min, int *max, int *deflt) const;
Chris@0 93 virtual QString getPropertyValueLabel(const PropertyName &,
Chris@0 94 int value) const;
Chris@862 95 virtual QString getPropertyValueIconName(const PropertyName &,
Chris@862 96 int value) const;
Chris@167 97 virtual RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const;
Chris@0 98 virtual void setProperty(const PropertyName &, int value);
Chris@0 99
Chris@0 100 /**
Chris@0 101 * Specify the channel to use from the source model.
Chris@0 102 * A value of -1 means to mix all available channels.
Chris@0 103 * The default is channel 0.
Chris@0 104 */
Chris@0 105 void setChannel(int);
Chris@0 106 int getChannel() const;
Chris@0 107
Chris@805 108 void setWindowSize(int);
Chris@805 109 int getWindowSize() const;
Chris@0 110
Chris@805 111 void setWindowHopLevel(int level);
Chris@805 112 int getWindowHopLevel() const;
Chris@0 113
Chris@0 114 void setWindowType(WindowType type);
Chris@0 115 WindowType getWindowType() const;
Chris@0 116
Chris@0 117 /**
Chris@110 118 * Set the gain multiplier for sample values in this view.
Chris@0 119 * The default is 1.0.
Chris@0 120 */
Chris@0 121 void setGain(float gain);
Chris@0 122 float getGain() const;
Chris@0 123
Chris@37 124 /**
Chris@110 125 * Set the threshold for sample values to qualify for being shown
Chris@110 126 * in the FFT, in voltage units.
Chris@37 127 *
Chris@1127 128 * The default is 10^-8 (-80dB).
Chris@37 129 */
Chris@37 130 void setThreshold(float threshold);
Chris@37 131 float getThreshold() const;
Chris@37 132
Chris@805 133 void setMinFrequency(int);
Chris@805 134 int getMinFrequency() const;
Chris@37 135
Chris@805 136 void setMaxFrequency(int); // 0 -> no maximum
Chris@805 137 int getMaxFrequency() const;
Chris@0 138
Chris@0 139 /**
Chris@1092 140 * Specify the scale for sample levels. See ColourScale and
Chris@1092 141 * WaveformLayer for comparison and details of meter and dB
Chris@1092 142 * scaling. The default is LogColourScale.
Chris@0 143 */
Chris@1105 144 void setColourScale(ColourScaleType);
Chris@1105 145 ColourScaleType getColourScale() const;
Chris@0 146
Chris@0 147 /**
Chris@1137 148 * Specify multiple factor for colour scale. This is 2.0 for
Chris@1137 149 * log-power spectrogram and 1.0 otherwise.
Chris@1137 150 */
Chris@1137 151 void setColourScaleMultiple(double);
Chris@1137 152 double getColourScaleMultiple() const;
Chris@1137 153
Chris@1137 154 /**
Chris@0 155 * Specify the scale for the y axis.
Chris@0 156 */
Chris@1103 157 void setBinScale(BinScale);
Chris@1103 158 BinScale getBinScale() const;
Chris@0 159
Chris@35 160 /**
Chris@35 161 * Specify the processing of frequency bins for the y axis.
Chris@35 162 */
Chris@1103 163 void setBinDisplay(BinDisplay);
Chris@1103 164 BinDisplay getBinDisplay() const;
Chris@862 165
Chris@719 166 /**
Chris@1104 167 * Specify the normalization mode for individual columns.
Chris@719 168 */
Chris@1104 169 void setNormalization(ColumnNormalization);
Chris@1104 170 ColumnNormalization getNormalization() const;
Chris@1104 171
Chris@1104 172 /**
Chris@1104 173 * Specify whether to normalize the visible area.
Chris@1104 174 */
Chris@1104 175 void setNormalizeVisibleArea(bool);
Chris@1104 176 bool getNormalizeVisibleArea() const;
Chris@120 177
Chris@719 178 /**
Chris@862 179 * Specify the colour map. See ColourMapper for the colour map
Chris@862 180 * values.
Chris@719 181 */
Chris@197 182 void setColourMap(int map);
Chris@197 183 int getColourMap() const;
Chris@0 184
Chris@9 185 /**
Chris@9 186 * Specify the colourmap rotation for the colour scale.
Chris@9 187 */
Chris@9 188 void setColourRotation(int);
Chris@9 189 int getColourRotation() const;
Chris@9 190
Chris@0 191 virtual VerticalPosition getPreferredFrameCountPosition() const {
Chris@0 192 return PositionTop;
Chris@0 193 }
Chris@0 194
Chris@15 195 virtual bool isLayerOpaque() const { return true; }
Chris@287 196
Chris@287 197 virtual ColourSignificance getLayerColourSignificance() const {
Chris@287 198 return ColourHasMeaningfulValue;
Chris@287 199 }
Chris@15 200
Chris@918 201 double getYForFrequency(const LayerGeometryProvider *v, double frequency) const;
Chris@918 202 double getFrequencyForY(const LayerGeometryProvider *v, int y) const;
Chris@42 203
Chris@1085 204 //!!! VerticalBinLayer methods. Note overlap with get*BinRange()
Chris@1113 205 double getYForBin(const LayerGeometryProvider *, double bin) const;
Chris@1113 206 double getBinForY(const LayerGeometryProvider *, double y) const;
Chris@1085 207
Chris@918 208 virtual int getCompletion(LayerGeometryProvider *v) const;
Chris@918 209 virtual QString getError(LayerGeometryProvider *v) const;
Chris@0 210
Chris@905 211 virtual bool getValueExtents(double &min, double &max,
Chris@101 212 bool &logarithmic, QString &unit) const;
Chris@101 213
Chris@905 214 virtual bool getDisplayExtents(double &min, double &max) const;
Chris@79 215
Chris@905 216 virtual bool setDisplayExtents(double min, double max);
Chris@120 217
Chris@918 218 virtual bool getYScaleValue(const LayerGeometryProvider *, int, double &, QString &) const;
Chris@261 219
Chris@316 220 virtual void toXml(QTextStream &stream, QString indent = "",
Chris@316 221 QString extraAttributes = "") const;
Chris@6 222
Chris@11 223 void setProperties(const QXmlAttributes &attributes);
Chris@11 224
Chris@918 225 virtual void setLayerDormant(const LayerGeometryProvider *v, bool dormant);
Chris@29 226
Chris@918 227 virtual bool isLayerScrollable(const LayerGeometryProvider *) const { return false; }
Chris@94 228
Chris@133 229 virtual int getVerticalZoomSteps(int &defaultStep) const;
Chris@133 230 virtual int getCurrentVerticalZoomStep() const;
Chris@133 231 virtual void setVerticalZoomStep(int);
Chris@187 232 virtual RangeMapper *getNewVerticalZoomRangeMapper() const;
Chris@133 233
Chris@193 234 virtual const Model *getSliceableModel() const;
Chris@193 235
Chris@0 236 protected slots:
Chris@0 237 void cacheInvalid();
Chris@906 238 void cacheInvalid(sv_frame_t startFrame, sv_frame_t endFrame);
Chris@122 239
Chris@122 240 void preferenceChanged(PropertyContainer::PropertyName name);
Chris@0 241
Chris@0 242 protected:
Chris@0 243 const DenseTimeValueModel *m_model; // I do not own this
Chris@484 244
Chris@35 245 int m_channel;
Chris@1023 246 int m_windowSize;
Chris@35 247 WindowType m_windowType;
Chris@1023 248 int m_windowHopLevel;
Chris@35 249 float m_gain;
Chris@215 250 float m_initialGain;
Chris@37 251 float m_threshold;
Chris@215 252 float m_initialThreshold;
Chris@35 253 int m_colourRotation;
Chris@215 254 int m_initialRotation;
Chris@1023 255 int m_minFrequency;
Chris@1023 256 int m_maxFrequency;
Chris@1023 257 int m_initialMaxFrequency;
Chris@1106 258 ColourScaleType m_colourScale;
Chris@1137 259 double m_colourScaleMultiple;
Chris@197 260 int m_colourMap;
Chris@77 261 QColor m_crosshairColour;
Chris@1104 262 BinScale m_binScale;
Chris@1104 263 BinDisplay m_binDisplay;
Chris@1104 264 ColumnNormalization m_normalization; // of individual columns
Chris@1104 265 bool m_normalizeVisibleArea;
Chris@133 266 int m_lastEmittedZoomStep;
Chris@389 267 bool m_synchronous;
Chris@0 268
Chris@608 269 mutable bool m_haveDetailedScale;
Chris@215 270
Chris@1137 271 static std::pair<ColourScaleType, double> convertToColourScale(int value);
Chris@1137 272 static int convertFromColourScale(ColourScaleType type, double multiple);
Chris@1104 273 static std::pair<ColumnNormalization, bool> convertToColumnNorm(int value);
Chris@1104 274 static int convertFromColumnNorm(ColumnNormalization norm, bool visible);
Chris@1104 275
Chris@0 276 bool m_exiting;
Chris@0 277
Chris@40 278 int getColourScaleWidth(QPainter &) const;
Chris@40 279
Chris@918 280 void illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &painter) const;
Chris@121 281
Chris@905 282 double getEffectiveMinFrequency() const;
Chris@905 283 double getEffectiveMaxFrequency() const;
Chris@38 284
Chris@918 285 bool getXBinRange(LayerGeometryProvider *v, int x, double &windowMin, double &windowMax) const;
Chris@918 286 bool getYBinRange(LayerGeometryProvider *v, int y, double &freqBinMin, double &freqBinMax) const;
Chris@0 287
Chris@918 288 bool getYBinSourceRange(LayerGeometryProvider *v, int y, double &freqMin, double &freqMax) const;
Chris@918 289 bool getAdjustedYBinSourceRange(LayerGeometryProvider *v, int x, int y,
Chris@905 290 double &freqMin, double &freqMax,
Chris@905 291 double &adjFreqMin, double &adjFreqMax) const;
Chris@918 292 bool getXBinSourceRange(LayerGeometryProvider *v, int x, RealTime &timeMin, RealTime &timeMax) const;
Chris@918 293 bool getXYBinSourceRange(LayerGeometryProvider *v, int x, int y, double &min, double &max,
Chris@905 294 double &phaseMin, double &phaseMax) const;
Chris@0 295
Chris@805 296 int getWindowIncrement() const {
Chris@97 297 if (m_windowHopLevel == 0) return m_windowSize;
Chris@97 298 else if (m_windowHopLevel == 1) return (m_windowSize * 3) / 4;
Chris@97 299 else return m_windowSize / (1 << (m_windowHopLevel - 1));
Chris@0 300 }
Chris@113 301
Chris@1086 302 int getFFTOversampling() const;
Chris@1087 303 int getFFTSize() const; // m_windowSize * getFFTOversampling()
Chris@115 304
Chris@1211 305 FFTModel *m_fftModel;
Chris@1211 306 FFTModel *getFFTModel() const { return m_fftModel; }
Chris@1212 307 Dense3DModelPeakCache *m_wholeCache;
Chris@1211 308 Dense3DModelPeakCache *m_peakCache;
Chris@1211 309 Dense3DModelPeakCache *getPeakCache() const { return m_peakCache; }
Chris@1054 310 const int m_peakCacheDivisor;
Chris@1212 311 bool canStoreWholeCache() const;
Chris@1211 312 void recreateFFTModel();
Chris@119 313
Chris@1030 314 typedef std::map<int, MagnitudeRange> ViewMagMap; // key is view id
Chris@119 315 mutable ViewMagMap m_viewMags;
Chris@1136 316 mutable ViewMagMap m_lastRenderedMags; // when in normalizeVisibleArea mode
Chris@119 317 void invalidateMagnitudes();
Chris@1089 318
Chris@1089 319 typedef std::map<int, Colour3DPlotRenderer *> ViewRendererMap; // key is view id
Chris@1089 320 mutable ViewRendererMap m_renderers;
Chris@1089 321 Colour3DPlotRenderer *getRenderer(LayerGeometryProvider *) const;
Chris@1106 322 void invalidateRenderers();
Chris@1058 323
Chris@1106 324 void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;
Chris@1142 325
Chris@1143 326 void paintDetailedScale(LayerGeometryProvider *v,
Chris@1143 327 QPainter &paint, QRect rect) const;
Chris@1143 328 void paintDetailedScalePhase(LayerGeometryProvider *v,
Chris@1143 329 QPainter &paint, QRect rect) const;
Chris@1058 330
Chris@1058 331 virtual void updateMeasureRectYCoords(LayerGeometryProvider *v,
Chris@1058 332 const MeasureRect &r) const;
Chris@1058 333 virtual void setMeasureRectYCoord(LayerGeometryProvider *v,
Chris@1058 334 MeasureRect &r, bool start, int y) const;
Chris@0 335 };
Chris@0 336
Chris@0 337 #endif