annotate layer/SpectrogramLayer.h @ 1447:8afea53332f3 single-point

Add option to make pane sizes auto-resize-only (i.e. remove user control via a splitter); also place alignment views above panes instead of below, meaning the extra bit of space that we currently have for the pane without one at least goes to the primary pane
author Chris Cannam
date Tue, 30 Apr 2019 15:53:21 +0100
parents a18e78b9c78b
children 6cf3cb6641e1
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@1266 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@1406 62 const ZoomConstraint *getZoomConstraint() const override { return this; }
Chris@1406 63 const Model *getModel() const override { return m_model; }
Chris@1406 64 void paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const override;
Chris@1406 65 void setSynchronousPainting(bool synchronous) override;
Chris@0 66
Chris@1406 67 int getVerticalScaleWidth(LayerGeometryProvider *v, bool detailed, QPainter &) const override;
Chris@1406 68 void paintVerticalScale(LayerGeometryProvider *v, bool detailed, QPainter &paint, QRect rect) const override;
Chris@0 69
Chris@1406 70 bool getCrosshairExtents(LayerGeometryProvider *, QPainter &, QPoint cursorPos,
Chris@1406 71 std::vector<QRect> &extents) const override;
Chris@1406 72 void paintCrosshairs(LayerGeometryProvider *, QPainter &, QPoint) const override;
Chris@77 73
Chris@1406 74 QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override;
Chris@0 75
Chris@1406 76 bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
Chris@1266 77 int &resolution,
Chris@1406 78 SnapType snap) const override;
Chris@13 79
Chris@1406 80 void measureDoubleClick(LayerGeometryProvider *, QMouseEvent *) override;
Chris@283 81
Chris@1406 82 bool hasLightBackground() const override;
Chris@224 83
Chris@0 84 void setModel(const DenseTimeValueModel *model);
Chris@0 85
Chris@1406 86 PropertyList getProperties() const override;
Chris@1406 87 QString getPropertyLabel(const PropertyName &) const override;
Chris@1406 88 QString getPropertyIconName(const PropertyName &) const override;
Chris@1406 89 PropertyType getPropertyType(const PropertyName &) const override;
Chris@1406 90 QString getPropertyGroupName(const PropertyName &) const override;
Chris@1406 91 int getPropertyRangeAndValue(const PropertyName &,
Chris@1406 92 int *min, int *max, int *deflt) const override;
Chris@1406 93 QString getPropertyValueLabel(const PropertyName &,
Chris@1406 94 int value) const override;
Chris@1406 95 QString getPropertyValueIconName(const PropertyName &,
Chris@1406 96 int value) const override;
Chris@1406 97 RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const override;
Chris@1406 98 void setProperty(const PropertyName &, int value) override;
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@1379 114 void setOversampling(int oversampling);
Chris@1379 115 int getOversampling() const;
Chris@1379 116
Chris@0 117 void setWindowType(WindowType type);
Chris@0 118 WindowType getWindowType() const;
Chris@0 119
Chris@0 120 /**
Chris@110 121 * Set the gain multiplier for sample values in this view.
Chris@0 122 * The default is 1.0.
Chris@0 123 */
Chris@0 124 void setGain(float gain);
Chris@0 125 float getGain() const;
Chris@0 126
Chris@37 127 /**
Chris@110 128 * Set the threshold for sample values to qualify for being shown
Chris@110 129 * in the FFT, in voltage units.
Chris@37 130 *
Chris@1127 131 * The default is 10^-8 (-80dB).
Chris@37 132 */
Chris@37 133 void setThreshold(float threshold);
Chris@37 134 float getThreshold() const;
Chris@37 135
Chris@805 136 void setMinFrequency(int);
Chris@805 137 int getMinFrequency() const;
Chris@37 138
Chris@805 139 void setMaxFrequency(int); // 0 -> no maximum
Chris@805 140 int getMaxFrequency() const;
Chris@0 141
Chris@0 142 /**
Chris@1092 143 * Specify the scale for sample levels. See ColourScale and
Chris@1092 144 * WaveformLayer for comparison and details of meter and dB
Chris@1092 145 * scaling. The default is LogColourScale.
Chris@0 146 */
Chris@1105 147 void setColourScale(ColourScaleType);
Chris@1105 148 ColourScaleType getColourScale() const;
Chris@0 149
Chris@0 150 /**
Chris@1137 151 * Specify multiple factor for colour scale. This is 2.0 for
Chris@1137 152 * log-power spectrogram and 1.0 otherwise.
Chris@1137 153 */
Chris@1137 154 void setColourScaleMultiple(double);
Chris@1137 155 double getColourScaleMultiple() const;
Chris@1137 156
Chris@1137 157 /**
Chris@0 158 * Specify the scale for the y axis.
Chris@0 159 */
Chris@1103 160 void setBinScale(BinScale);
Chris@1103 161 BinScale getBinScale() const;
Chris@0 162
Chris@35 163 /**
Chris@35 164 * Specify the processing of frequency bins for the y axis.
Chris@35 165 */
Chris@1103 166 void setBinDisplay(BinDisplay);
Chris@1103 167 BinDisplay getBinDisplay() const;
Chris@862 168
Chris@719 169 /**
Chris@1104 170 * Specify the normalization mode for individual columns.
Chris@719 171 */
Chris@1104 172 void setNormalization(ColumnNormalization);
Chris@1104 173 ColumnNormalization getNormalization() const;
Chris@1104 174
Chris@1104 175 /**
Chris@1104 176 * Specify whether to normalize the visible area.
Chris@1104 177 */
Chris@1104 178 void setNormalizeVisibleArea(bool);
Chris@1104 179 bool getNormalizeVisibleArea() const;
Chris@120 180
Chris@719 181 /**
Chris@862 182 * Specify the colour map. See ColourMapper for the colour map
Chris@862 183 * values.
Chris@719 184 */
Chris@197 185 void setColourMap(int map);
Chris@197 186 int getColourMap() const;
Chris@0 187
Chris@9 188 /**
Chris@9 189 * Specify the colourmap rotation for the colour scale.
Chris@9 190 */
Chris@9 191 void setColourRotation(int);
Chris@9 192 int getColourRotation() const;
Chris@9 193
Chris@1406 194 VerticalPosition getPreferredFrameCountPosition() const override {
Chris@1266 195 return PositionTop;
Chris@0 196 }
Chris@0 197
Chris@1406 198 bool isLayerOpaque() const override { return true; }
Chris@287 199
Chris@1406 200 ColourSignificance getLayerColourSignificance() const override {
Chris@287 201 return ColourHasMeaningfulValue;
Chris@287 202 }
Chris@15 203
Chris@918 204 double getYForFrequency(const LayerGeometryProvider *v, double frequency) const;
Chris@918 205 double getFrequencyForY(const LayerGeometryProvider *v, int y) const;
Chris@42 206
Chris@1085 207 //!!! VerticalBinLayer methods. Note overlap with get*BinRange()
Chris@1406 208 double getYForBin(const LayerGeometryProvider *, double bin) const override;
Chris@1406 209 double getBinForY(const LayerGeometryProvider *, double y) const override;
Chris@1085 210
Chris@1406 211 int getCompletion(LayerGeometryProvider *v) const override;
Chris@1406 212 QString getError(LayerGeometryProvider *v) const override;
Chris@0 213
Chris@1406 214 bool getValueExtents(double &min, double &max,
Chris@1406 215 bool &logarithmic, QString &unit) const override;
Chris@101 216
Chris@1406 217 bool getDisplayExtents(double &min, double &max) const override;
Chris@79 218
Chris@1406 219 bool setDisplayExtents(double min, double max) override;
Chris@120 220
Chris@1406 221 bool getYScaleValue(const LayerGeometryProvider *, int, double &, QString &) const override;
Chris@261 222
Chris@1406 223 void toXml(QTextStream &stream, QString indent = "",
Chris@1406 224 QString extraAttributes = "") const override;
Chris@6 225
Chris@1406 226 void setProperties(const QXmlAttributes &attributes) override;
Chris@11 227
Chris@1406 228 void setLayerDormant(const LayerGeometryProvider *v, bool dormant) override;
Chris@29 229
Chris@1406 230 bool isLayerScrollable(const LayerGeometryProvider *) const override;
Chris@94 231
Chris@1406 232 int getVerticalZoomSteps(int &defaultStep) const override;
Chris@1406 233 int getCurrentVerticalZoomStep() const override;
Chris@1406 234 void setVerticalZoomStep(int) override;
Chris@1406 235 RangeMapper *getNewVerticalZoomRangeMapper() const override;
Chris@133 236
Chris@1406 237 const Model *getSliceableModel() const override;
Chris@193 238
Chris@0 239 protected slots:
Chris@0 240 void cacheInvalid();
Chris@906 241 void cacheInvalid(sv_frame_t startFrame, sv_frame_t endFrame);
Chris@122 242
Chris@122 243 void preferenceChanged(PropertyContainer::PropertyName name);
Chris@0 244
Chris@0 245 protected:
Chris@0 246 const DenseTimeValueModel *m_model; // I do not own this
Chris@484 247
Chris@35 248 int m_channel;
Chris@1023 249 int m_windowSize;
Chris@35 250 WindowType m_windowType;
Chris@1023 251 int m_windowHopLevel;
Chris@1379 252 int m_oversampling;
Chris@35 253 float m_gain;
Chris@215 254 float m_initialGain;
Chris@37 255 float m_threshold;
Chris@215 256 float m_initialThreshold;
Chris@35 257 int m_colourRotation;
Chris@215 258 int m_initialRotation;
Chris@1023 259 int m_minFrequency;
Chris@1023 260 int m_maxFrequency;
Chris@1023 261 int m_initialMaxFrequency;
Chris@1106 262 ColourScaleType m_colourScale;
Chris@1137 263 double m_colourScaleMultiple;
Chris@197 264 int m_colourMap;
Chris@1362 265 bool m_colourInverted;
Chris@1239 266 mutable QColor m_crosshairColour;
Chris@1104 267 BinScale m_binScale;
Chris@1104 268 BinDisplay m_binDisplay;
Chris@1104 269 ColumnNormalization m_normalization; // of individual columns
Chris@1104 270 bool m_normalizeVisibleArea;
Chris@133 271 int m_lastEmittedZoomStep;
Chris@389 272 bool m_synchronous;
Chris@0 273
Chris@608 274 mutable bool m_haveDetailedScale;
Chris@215 275
Chris@1137 276 static std::pair<ColourScaleType, double> convertToColourScale(int value);
Chris@1137 277 static int convertFromColourScale(ColourScaleType type, double multiple);
Chris@1104 278 static std::pair<ColumnNormalization, bool> convertToColumnNorm(int value);
Chris@1104 279 static int convertFromColumnNorm(ColumnNormalization norm, bool visible);
Chris@1104 280
Chris@0 281 bool m_exiting;
Chris@0 282
Chris@40 283 int getColourScaleWidth(QPainter &) const;
Chris@40 284
Chris@918 285 void illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &painter) const;
Chris@121 286
Chris@905 287 double getEffectiveMinFrequency() const;
Chris@905 288 double getEffectiveMaxFrequency() const;
Chris@38 289
Chris@918 290 bool getXBinRange(LayerGeometryProvider *v, int x, double &windowMin, double &windowMax) const;
Chris@918 291 bool getYBinRange(LayerGeometryProvider *v, int y, double &freqBinMin, double &freqBinMax) const;
Chris@0 292
Chris@918 293 bool getYBinSourceRange(LayerGeometryProvider *v, int y, double &freqMin, double &freqMax) const;
Chris@918 294 bool getAdjustedYBinSourceRange(LayerGeometryProvider *v, int x, int y,
Chris@1266 295 double &freqMin, double &freqMax,
Chris@1266 296 double &adjFreqMin, double &adjFreqMax) const;
Chris@918 297 bool getXBinSourceRange(LayerGeometryProvider *v, int x, RealTime &timeMin, RealTime &timeMax) const;
Chris@918 298 bool getXYBinSourceRange(LayerGeometryProvider *v, int x, int y, double &min, double &max,
Chris@1266 299 double &phaseMin, double &phaseMax) const;
Chris@0 300
Chris@805 301 int getWindowIncrement() const {
Chris@97 302 if (m_windowHopLevel == 0) return m_windowSize;
Chris@97 303 else if (m_windowHopLevel == 1) return (m_windowSize * 3) / 4;
Chris@97 304 else return m_windowSize / (1 << (m_windowHopLevel - 1));
Chris@0 305 }
Chris@113 306
Chris@1379 307 int getFFTSize() const; // m_windowSize * getOversampling()
Chris@115 308
Chris@1211 309 FFTModel *m_fftModel;
Chris@1211 310 FFTModel *getFFTModel() const { return m_fftModel; }
Chris@1212 311 Dense3DModelPeakCache *m_wholeCache;
Chris@1211 312 Dense3DModelPeakCache *m_peakCache;
Chris@1211 313 Dense3DModelPeakCache *getPeakCache() const { return m_peakCache; }
Chris@1054 314 const int m_peakCacheDivisor;
Chris@1212 315 bool canStoreWholeCache() const;
Chris@1211 316 void recreateFFTModel();
Chris@119 317
Chris@1030 318 typedef std::map<int, MagnitudeRange> ViewMagMap; // key is view id
Chris@119 319 mutable ViewMagMap m_viewMags;
Chris@1136 320 mutable ViewMagMap m_lastRenderedMags; // when in normalizeVisibleArea mode
Chris@119 321 void invalidateMagnitudes();
Chris@1089 322
Chris@1089 323 typedef std::map<int, Colour3DPlotRenderer *> ViewRendererMap; // key is view id
Chris@1089 324 mutable ViewRendererMap m_renderers;
Chris@1089 325 Colour3DPlotRenderer *getRenderer(LayerGeometryProvider *) const;
Chris@1106 326 void invalidateRenderers();
Chris@1242 327
Chris@1242 328 void deleteDerivedModels();
Chris@1058 329
Chris@1106 330 void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;
Chris@1142 331
Chris@1143 332 void paintDetailedScale(LayerGeometryProvider *v,
Chris@1143 333 QPainter &paint, QRect rect) const;
Chris@1143 334 void paintDetailedScalePhase(LayerGeometryProvider *v,
Chris@1143 335 QPainter &paint, QRect rect) const;
Chris@1058 336
Chris@1406 337 void updateMeasureRectYCoords(LayerGeometryProvider *v,
Chris@1406 338 const MeasureRect &r) const override;
Chris@1406 339 void setMeasureRectYCoord(LayerGeometryProvider *v,
Chris@1406 340 MeasureRect &r, bool start, int y) const override;
Chris@0 341 };
Chris@0 342
Chris@0 343 #endif