annotate layer/SpectrogramLayer.h @ 1135:628cd329c241 spectrogram-minor-refactor

Use a count of bins rather than min and max bins (because the name maxbin tells us nothing about whether the range is inclusive or not)
author Chris Cannam
date Wed, 03 Aug 2016 14:20:27 +0100
parents 9fb8dfd7ce4c
children 9ff838a64461
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@0 148 * Specify the scale for the y axis.
Chris@0 149 */
Chris@1103 150 void setBinScale(BinScale);
Chris@1103 151 BinScale getBinScale() const;
Chris@0 152
Chris@35 153 /**
Chris@35 154 * Specify the processing of frequency bins for the y axis.
Chris@35 155 */
Chris@1103 156 void setBinDisplay(BinDisplay);
Chris@1103 157 BinDisplay getBinDisplay() const;
Chris@862 158
Chris@719 159 /**
Chris@1104 160 * Specify the normalization mode for individual columns.
Chris@719 161 */
Chris@1104 162 void setNormalization(ColumnNormalization);
Chris@1104 163 ColumnNormalization getNormalization() const;
Chris@1104 164
Chris@1104 165 /**
Chris@1104 166 * Specify whether to normalize the visible area.
Chris@1104 167 */
Chris@1104 168 void setNormalizeVisibleArea(bool);
Chris@1104 169 bool getNormalizeVisibleArea() const;
Chris@120 170
Chris@719 171 /**
Chris@862 172 * Specify the colour map. See ColourMapper for the colour map
Chris@862 173 * values.
Chris@719 174 */
Chris@197 175 void setColourMap(int map);
Chris@197 176 int getColourMap() const;
Chris@0 177
Chris@9 178 /**
Chris@9 179 * Specify the colourmap rotation for the colour scale.
Chris@9 180 */
Chris@9 181 void setColourRotation(int);
Chris@9 182 int getColourRotation() const;
Chris@9 183
Chris@0 184 virtual VerticalPosition getPreferredFrameCountPosition() const {
Chris@0 185 return PositionTop;
Chris@0 186 }
Chris@0 187
Chris@15 188 virtual bool isLayerOpaque() const { return true; }
Chris@287 189
Chris@287 190 virtual ColourSignificance getLayerColourSignificance() const {
Chris@287 191 return ColourHasMeaningfulValue;
Chris@287 192 }
Chris@15 193
Chris@918 194 double getYForFrequency(const LayerGeometryProvider *v, double frequency) const;
Chris@918 195 double getFrequencyForY(const LayerGeometryProvider *v, int y) const;
Chris@42 196
Chris@1085 197 //!!! VerticalBinLayer methods. Note overlap with get*BinRange()
Chris@1113 198 double getYForBin(const LayerGeometryProvider *, double bin) const;
Chris@1113 199 double getBinForY(const LayerGeometryProvider *, double y) const;
Chris@1085 200
Chris@918 201 virtual int getCompletion(LayerGeometryProvider *v) const;
Chris@918 202 virtual QString getError(LayerGeometryProvider *v) const;
Chris@0 203
Chris@905 204 virtual bool getValueExtents(double &min, double &max,
Chris@101 205 bool &logarithmic, QString &unit) const;
Chris@101 206
Chris@905 207 virtual bool getDisplayExtents(double &min, double &max) const;
Chris@79 208
Chris@905 209 virtual bool setDisplayExtents(double min, double max);
Chris@120 210
Chris@918 211 virtual bool getYScaleValue(const LayerGeometryProvider *, int, double &, QString &) const;
Chris@261 212
Chris@316 213 virtual void toXml(QTextStream &stream, QString indent = "",
Chris@316 214 QString extraAttributes = "") const;
Chris@6 215
Chris@11 216 void setProperties(const QXmlAttributes &attributes);
Chris@11 217
Chris@918 218 virtual void setLayerDormant(const LayerGeometryProvider *v, bool dormant);
Chris@29 219
Chris@918 220 virtual bool isLayerScrollable(const LayerGeometryProvider *) const { return false; }
Chris@94 221
Chris@133 222 virtual int getVerticalZoomSteps(int &defaultStep) const;
Chris@133 223 virtual int getCurrentVerticalZoomStep() const;
Chris@133 224 virtual void setVerticalZoomStep(int);
Chris@187 225 virtual RangeMapper *getNewVerticalZoomRangeMapper() const;
Chris@133 226
Chris@193 227 virtual const Model *getSliceableModel() const;
Chris@193 228
Chris@0 229 protected slots:
Chris@0 230 void cacheInvalid();
Chris@906 231 void cacheInvalid(sv_frame_t startFrame, sv_frame_t endFrame);
Chris@122 232
Chris@122 233 void preferenceChanged(PropertyContainer::PropertyName name);
Chris@0 234
Chris@0 235 protected:
Chris@0 236 const DenseTimeValueModel *m_model; // I do not own this
Chris@484 237
Chris@35 238 int m_channel;
Chris@1023 239 int m_windowSize;
Chris@35 240 WindowType m_windowType;
Chris@1023 241 int m_windowHopLevel;
Chris@35 242 float m_gain;
Chris@215 243 float m_initialGain;
Chris@37 244 float m_threshold;
Chris@215 245 float m_initialThreshold;
Chris@35 246 int m_colourRotation;
Chris@215 247 int m_initialRotation;
Chris@1023 248 int m_minFrequency;
Chris@1023 249 int m_maxFrequency;
Chris@1023 250 int m_initialMaxFrequency;
Chris@1106 251 ColourScaleType m_colourScale;
Chris@197 252 int m_colourMap;
Chris@77 253 QColor m_crosshairColour;
Chris@1104 254 BinScale m_binScale;
Chris@1104 255 BinDisplay m_binDisplay;
Chris@1104 256 ColumnNormalization m_normalization; // of individual columns
Chris@1104 257 bool m_normalizeVisibleArea;
Chris@133 258 int m_lastEmittedZoomStep;
Chris@389 259 bool m_synchronous;
Chris@0 260
Chris@608 261 mutable bool m_haveDetailedScale;
Chris@215 262
Chris@1105 263 static ColourScaleType convertToColourScale(int value);
Chris@1105 264 static int convertFromColourScale(ColourScaleType);
Chris@1104 265 static std::pair<ColumnNormalization, bool> convertToColumnNorm(int value);
Chris@1104 266 static int convertFromColumnNorm(ColumnNormalization norm, bool visible);
Chris@1104 267
Chris@0 268 bool m_exiting;
Chris@0 269
Chris@40 270 int getColourScaleWidth(QPainter &) const;
Chris@40 271
Chris@918 272 void illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &painter) const;
Chris@121 273
Chris@905 274 double getEffectiveMinFrequency() const;
Chris@905 275 double getEffectiveMaxFrequency() const;
Chris@38 276
Chris@918 277 bool getXBinRange(LayerGeometryProvider *v, int x, double &windowMin, double &windowMax) const;
Chris@918 278 bool getYBinRange(LayerGeometryProvider *v, int y, double &freqBinMin, double &freqBinMax) const;
Chris@0 279
Chris@918 280 bool getYBinSourceRange(LayerGeometryProvider *v, int y, double &freqMin, double &freqMax) const;
Chris@918 281 bool getAdjustedYBinSourceRange(LayerGeometryProvider *v, int x, int y,
Chris@905 282 double &freqMin, double &freqMax,
Chris@905 283 double &adjFreqMin, double &adjFreqMax) const;
Chris@918 284 bool getXBinSourceRange(LayerGeometryProvider *v, int x, RealTime &timeMin, RealTime &timeMax) const;
Chris@918 285 bool getXYBinSourceRange(LayerGeometryProvider *v, int x, int y, double &min, double &max,
Chris@905 286 double &phaseMin, double &phaseMax) const;
Chris@0 287
Chris@805 288 int getWindowIncrement() const {
Chris@97 289 if (m_windowHopLevel == 0) return m_windowSize;
Chris@97 290 else if (m_windowHopLevel == 1) return (m_windowSize * 3) / 4;
Chris@97 291 else return m_windowSize / (1 << (m_windowHopLevel - 1));
Chris@0 292 }
Chris@113 293
Chris@1086 294 int getFFTOversampling() const;
Chris@1087 295 int getFFTSize() const; // m_windowSize * getFFTOversampling()
Chris@115 296
Chris@1089 297 mutable FFTModel *m_fftModel; //!!! should not be mutable, see getFFTModel()?
Chris@1088 298 mutable Dense3DModelPeakCache *m_peakCache;
Chris@1054 299 const int m_peakCacheDivisor;
Chris@119 300
Chris@1030 301 typedef std::map<int, MagnitudeRange> ViewMagMap; // key is view id
Chris@119 302 mutable ViewMagMap m_viewMags;
Chris@1121 303 //!!! mutable std::vector<MagnitudeRange> m_columnMags;
Chris@119 304 void invalidateMagnitudes();
Chris@1121 305 //!!! bool updateViewMagnitudes(LayerGeometryProvider *v) const;
Chris@1089 306
Chris@1089 307 typedef std::map<int, Colour3DPlotRenderer *> ViewRendererMap; // key is view id
Chris@1089 308 mutable ViewRendererMap m_renderers;
Chris@1089 309 Colour3DPlotRenderer *getRenderer(LayerGeometryProvider *) const;
Chris@1106 310 void invalidateRenderers();
Chris@1058 311
Chris@1088 312 FFTModel *getFFTModel() const;
Chris@1088 313 Dense3DModelPeakCache *getPeakCache() const;
Chris@1088 314 void invalidateFFTModel();
Chris@1089 315
Chris@1106 316 void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;
Chris@1058 317
Chris@1058 318 virtual void updateMeasureRectYCoords(LayerGeometryProvider *v,
Chris@1058 319 const MeasureRect &r) const;
Chris@1058 320 virtual void setMeasureRectYCoord(LayerGeometryProvider *v,
Chris@1058 321 MeasureRect &r, bool start, int y) const;
Chris@0 322 };
Chris@0 323
Chris@0 324 #endif