comparison layer/SpectrogramLayer.h @ 1148:c0d841cb8ab9 tony-2.0-integration

Merge latest SV 3.0 branch code
author Chris Cannam
date Fri, 19 Aug 2016 15:58:57 +0100
parents c53ed1a6fcbd
children 7a19738b9762
comparison
equal deleted inserted replaced
1009:96cf499fad62 1148:c0d841cb8ab9
11 published by the Free Software Foundation; either version 2 of the 11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15 15
16 #ifndef _SPECTROGRAM_LAYER_H_ 16 #ifndef SPECTROGRAM_LAYER_H
17 #define _SPECTROGRAM_LAYER_H_ 17 #define SPECTROGRAM_LAYER_H
18 18
19 #include "SliceableLayer.h" 19 #include "SliceableLayer.h"
20 #include "base/Window.h" 20 #include "base/Window.h"
21 #include "base/MagnitudeRange.h"
21 #include "base/RealTime.h" 22 #include "base/RealTime.h"
22 #include "base/Thread.h" 23 #include "base/Thread.h"
23 #include "base/PropertyContainer.h" 24 #include "base/PropertyContainer.h"
24 #include "data/model/PowerOfSqrtTwoZoomConstraint.h" 25 #include "data/model/PowerOfSqrtTwoZoomConstraint.h"
25 #include "data/model/DenseTimeValueModel.h" 26 #include "data/model/DenseTimeValueModel.h"
26 #include "data/model/FFTModel.h" 27 #include "data/model/FFTModel.h"
28
29 #include "VerticalBinLayer.h"
30 #include "ColourScale.h"
31 #include "Colour3DPlotRenderer.h"
27 32
28 #include <QMutex> 33 #include <QMutex>
29 #include <QWaitCondition> 34 #include <QWaitCondition>
30 #include <QImage> 35 #include <QImage>
31 #include <QPixmap> 36 #include <QPixmap>
36 class QPixmap; 41 class QPixmap;
37 class QTimer; 42 class QTimer;
38 class FFTModel; 43 class FFTModel;
39 class Dense3DModelPeakCache; 44 class Dense3DModelPeakCache;
40 45
41
42 /** 46 /**
43 * SpectrogramLayer represents waveform data (obtained from a 47 * SpectrogramLayer represents waveform data (obtained from a
44 * DenseTimeValueModel) in spectrogram form. 48 * DenseTimeValueModel) in spectrogram form.
45 */ 49 */
46 50
47 class SpectrogramLayer : public SliceableLayer, 51 class SpectrogramLayer : public VerticalBinLayer,
48 public PowerOfSqrtTwoZoomConstraint 52 public PowerOfSqrtTwoZoomConstraint
49 { 53 {
50 Q_OBJECT 54 Q_OBJECT
51 55
52 public: 56 public:
108 int getWindowHopLevel() const; 112 int getWindowHopLevel() const;
109 113
110 void setWindowType(WindowType type); 114 void setWindowType(WindowType type);
111 WindowType getWindowType() const; 115 WindowType getWindowType() const;
112 116
113 void setZeroPadLevel(int level);
114 int getZeroPadLevel() const;
115
116 /** 117 /**
117 * Set the gain multiplier for sample values in this view. 118 * Set the gain multiplier for sample values in this view.
118 * The default is 1.0. 119 * The default is 1.0.
119 */ 120 */
120 void setGain(float gain); 121 void setGain(float gain);
122 123
123 /** 124 /**
124 * Set the threshold for sample values to qualify for being shown 125 * Set the threshold for sample values to qualify for being shown
125 * in the FFT, in voltage units. 126 * in the FFT, in voltage units.
126 * 127 *
127 * The default is 0.0. 128 * The default is 10^-8 (-80dB).
128 */ 129 */
129 void setThreshold(float threshold); 130 void setThreshold(float threshold);
130 float getThreshold() const; 131 float getThreshold() const;
131 132
132 void setMinFrequency(int); 133 void setMinFrequency(int);
133 int getMinFrequency() const; 134 int getMinFrequency() const;
134 135
135 void setMaxFrequency(int); // 0 -> no maximum 136 void setMaxFrequency(int); // 0 -> no maximum
136 int getMaxFrequency() const; 137 int getMaxFrequency() const;
137 138
138 enum ColourScale { 139 /**
139 LinearColourScale, 140 * Specify the scale for sample levels. See ColourScale and
140 MeterColourScale, 141 * WaveformLayer for comparison and details of meter and dB
141 dBSquaredColourScale, 142 * scaling. The default is LogColourScale.
142 dBColourScale, 143 */
143 PhaseColourScale 144 void setColourScale(ColourScaleType);
144 }; 145 ColourScaleType getColourScale() const;
145 146
146 /** 147 /**
147 * Specify the scale for sample levels. See WaveformLayer for 148 * Specify multiple factor for colour scale. This is 2.0 for
148 * details of meter and dB scaling. The default is dBColourScale. 149 * log-power spectrogram and 1.0 otherwise.
149 */ 150 */
150 void setColourScale(ColourScale); 151 void setColourScaleMultiple(double);
151 ColourScale getColourScale() const; 152 double getColourScaleMultiple() const;
152
153 enum FrequencyScale {
154 LinearFrequencyScale,
155 LogFrequencyScale
156 };
157 153
158 /** 154 /**
159 * Specify the scale for the y axis. 155 * Specify the scale for the y axis.
160 */ 156 */
161 void setFrequencyScale(FrequencyScale); 157 void setBinScale(BinScale);
162 FrequencyScale getFrequencyScale() const; 158 BinScale getBinScale() const;
163 159
164 enum BinDisplay {
165 AllBins,
166 PeakBins,
167 PeakFrequencies
168 };
169
170 /** 160 /**
171 * Specify the processing of frequency bins for the y axis. 161 * Specify the processing of frequency bins for the y axis.
172 */ 162 */
173 void setBinDisplay(BinDisplay); 163 void setBinDisplay(BinDisplay);
174 BinDisplay getBinDisplay() const; 164 BinDisplay getBinDisplay() const;
175 165
176 enum Normalization { 166 /**
177 NoNormalization, 167 * Specify the normalization mode for individual columns.
178 NormalizeColumns, 168 */
179 NormalizeVisibleArea, 169 void setNormalization(ColumnNormalization);
180 NormalizeHybrid 170 ColumnNormalization getNormalization() const;
181 }; 171
182 172 /**
183 /** 173 * Specify whether to normalize the visible area.
184 * Specify the normalization mode for bin values. 174 */
185 */ 175 void setNormalizeVisibleArea(bool);
186 void setNormalization(Normalization); 176 bool getNormalizeVisibleArea() const;
187 Normalization getNormalization() const;
188 177
189 /** 178 /**
190 * Specify the colour map. See ColourMapper for the colour map 179 * Specify the colour map. See ColourMapper for the colour map
191 * values. 180 * values.
192 */ 181 */
210 } 199 }
211 200
212 double getYForFrequency(const LayerGeometryProvider *v, double frequency) const; 201 double getYForFrequency(const LayerGeometryProvider *v, double frequency) const;
213 double getFrequencyForY(const LayerGeometryProvider *v, int y) const; 202 double getFrequencyForY(const LayerGeometryProvider *v, int y) const;
214 203
204 //!!! VerticalBinLayer methods. Note overlap with get*BinRange()
205 double getYForBin(const LayerGeometryProvider *, double bin) const;
206 double getBinForY(const LayerGeometryProvider *, double y) const;
207
215 virtual int getCompletion(LayerGeometryProvider *v) const; 208 virtual int getCompletion(LayerGeometryProvider *v) const;
216 virtual QString getError(LayerGeometryProvider *v) const; 209 virtual QString getError(LayerGeometryProvider *v) const;
217 210
218 virtual bool getValueExtents(double &min, double &max, 211 virtual bool getValueExtents(double &min, double &max,
219 bool &logarithmic, QString &unit) const; 212 bool &logarithmic, QString &unit) const;
248 241
249 protected: 242 protected:
250 const DenseTimeValueModel *m_model; // I do not own this 243 const DenseTimeValueModel *m_model; // I do not own this
251 244
252 int m_channel; 245 int m_channel;
253 int m_windowSize; 246 int m_windowSize;
254 WindowType m_windowType; 247 WindowType m_windowType;
255 int m_windowHopLevel; 248 int m_windowHopLevel;
256 int m_zeroPadLevel;
257 int m_fftSize;
258 float m_gain; 249 float m_gain;
259 float m_initialGain; 250 float m_initialGain;
260 float m_threshold; 251 float m_threshold;
261 float m_initialThreshold; 252 float m_initialThreshold;
262 int m_colourRotation; 253 int m_colourRotation;
263 int m_initialRotation; 254 int m_initialRotation;
264 int m_minFrequency; 255 int m_minFrequency;
265 int m_maxFrequency; 256 int m_maxFrequency;
266 int m_initialMaxFrequency; 257 int m_initialMaxFrequency;
267 ColourScale m_colourScale; 258 ColourScaleType m_colourScale;
259 double m_colourScaleMultiple;
268 int m_colourMap; 260 int m_colourMap;
269 QColor m_crosshairColour; 261 QColor m_crosshairColour;
270 FrequencyScale m_frequencyScale; 262 BinScale m_binScale;
271 BinDisplay m_binDisplay; 263 BinDisplay m_binDisplay;
272 Normalization m_normalization; 264 ColumnNormalization m_normalization; // of individual columns
265 bool m_normalizeVisibleArea;
273 int m_lastEmittedZoomStep; 266 int m_lastEmittedZoomStep;
274 bool m_synchronous; 267 bool m_synchronous;
275 268
276 mutable bool m_haveDetailedScale; 269 mutable bool m_haveDetailedScale;
277 mutable int m_lastPaintBlockWidth; 270
278 mutable RealTime m_lastPaintTime; 271 static std::pair<ColourScaleType, double> convertToColourScale(int value);
279 272 static int convertFromColourScale(ColourScaleType type, double multiple);
280 enum { NO_VALUE = 0 }; // colour index for unused pixels 273 static std::pair<ColumnNormalization, bool> convertToColumnNorm(int value);
281 274 static int convertFromColumnNorm(ColumnNormalization norm, bool visible);
282 class Palette
283 {
284 public:
285 QColor getColour(unsigned char index) const {
286 return m_colours[index];
287 }
288
289 void setColour(unsigned char index, QColor colour) {
290 m_colours[index] = colour;
291 }
292
293 private:
294 QColor m_colours[256];
295 };
296
297 Palette m_palette;
298
299 /**
300 * ImageCache covers the area of the view, at view resolution.
301 * Not all of it is necessarily valid at once (it is refreshed
302 * in parts when scrolling, for example).
303 */
304 struct ImageCache
305 {
306 QImage image;
307 QRect validArea;
308 sv_frame_t startFrame;
309 int zoomLevel;
310 };
311 typedef std::map<const View *, ImageCache> ViewImageCache;
312 void invalidateImageCaches();
313 void invalidateImageCaches(sv_frame_t startFrame, sv_frame_t endFrame);
314 mutable ViewImageCache m_imageCaches;
315
316 /**
317 * When painting, we draw directly onto the draw buffer and then
318 * copy this to the part of the image cache that needed refreshing
319 * before copying the image cache onto the window. (Remind me why
320 * we don't draw directly onto the cache?)
321 */
322 mutable QImage m_drawBuffer;
323 275
324 bool m_exiting; 276 bool m_exiting;
325
326 void initialisePalette();
327 void rotatePalette(int distance);
328
329 unsigned char getDisplayValue(LayerGeometryProvider *v, double input) const;
330 277
331 int getColourScaleWidth(QPainter &) const; 278 int getColourScaleWidth(QPainter &) const;
332 279
333 void illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &painter) const; 280 void illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &painter) const;
334 281
335 double getEffectiveMinFrequency() const; 282 double getEffectiveMinFrequency() const;
336 double getEffectiveMaxFrequency() const; 283 double getEffectiveMaxFrequency() const;
337 284
338 // Note that the getYBin... methods return the nominal bin in the
339 // un-smoothed spectrogram. This is not necessarily the same bin
340 // as is pulled from the spectrogram and drawn at the given
341 // position, if the spectrogram has oversampling smoothing. Use
342 // getSmoothedYBinRange to obtain that.
343
344 bool getXBinRange(LayerGeometryProvider *v, int x, double &windowMin, double &windowMax) const; 285 bool getXBinRange(LayerGeometryProvider *v, int x, double &windowMin, double &windowMax) const;
345 bool getYBinRange(LayerGeometryProvider *v, int y, double &freqBinMin, double &freqBinMax) const; 286 bool getYBinRange(LayerGeometryProvider *v, int y, double &freqBinMin, double &freqBinMax) const;
346 bool getSmoothedYBinRange(LayerGeometryProvider *v, int y, double &freqBinMin, double &freqBinMax) const;
347 287
348 bool getYBinSourceRange(LayerGeometryProvider *v, int y, double &freqMin, double &freqMax) const; 288 bool getYBinSourceRange(LayerGeometryProvider *v, int y, double &freqMin, double &freqMax) const;
349 bool getAdjustedYBinSourceRange(LayerGeometryProvider *v, int x, int y, 289 bool getAdjustedYBinSourceRange(LayerGeometryProvider *v, int x, int y,
350 double &freqMin, double &freqMax, 290 double &freqMin, double &freqMax,
351 double &adjFreqMin, double &adjFreqMax) const; 291 double &adjFreqMin, double &adjFreqMax) const;
357 if (m_windowHopLevel == 0) return m_windowSize; 297 if (m_windowHopLevel == 0) return m_windowSize;
358 else if (m_windowHopLevel == 1) return (m_windowSize * 3) / 4; 298 else if (m_windowHopLevel == 1) return (m_windowSize * 3) / 4;
359 else return m_windowSize / (1 << (m_windowHopLevel - 1)); 299 else return m_windowSize / (1 << (m_windowHopLevel - 1));
360 } 300 }
361 301
362 int getZeroPadLevel(const LayerGeometryProvider *v) const; 302 int getFFTOversampling() const;
363 int getFFTSize(const LayerGeometryProvider *v) const; 303 int getFFTSize() const; // m_windowSize * getFFTOversampling()
364 FFTModel *getFFTModel(const LayerGeometryProvider *v) const; 304
365 Dense3DModelPeakCache *getPeakCache(const LayerGeometryProvider *v) const; 305 mutable FFTModel *m_fftModel; //!!! should not be mutable, see getFFTModel()?
366 void invalidateFFTModels(); 306 mutable Dense3DModelPeakCache *m_peakCache;
367 307 const int m_peakCacheDivisor;
368 typedef std::map<const View *, FFTModel *> ViewFFTMap; 308
369 typedef std::map<const View *, Dense3DModelPeakCache *> PeakCacheMap; 309 typedef std::map<int, MagnitudeRange> ViewMagMap; // key is view id
370 mutable ViewFFTMap m_fftModels;
371 mutable PeakCacheMap m_peakCaches;
372 mutable Model *m_sliceableModel;
373
374 class MagnitudeRange {
375 public:
376 MagnitudeRange() : m_min(0), m_max(0) { }
377 bool operator==(const MagnitudeRange &r) {
378 return r.m_min == m_min && r.m_max == m_max;
379 }
380 bool isSet() const { return (m_min != 0.f || m_max != 0.f); }
381 void set(float min, float max) {
382 m_min = min;
383 m_max = max;
384 if (m_max < m_min) m_max = m_min;
385 }
386 bool sample(float f) {
387 bool changed = false;
388 if (isSet()) {
389 if (f < m_min) { m_min = f; changed = true; }
390 if (f > m_max) { m_max = f; changed = true; }
391 } else {
392 m_max = m_min = f;
393 changed = true;
394 }
395 return changed;
396 }
397 bool sample(const MagnitudeRange &r) {
398 bool changed = false;
399 if (isSet()) {
400 if (r.m_min < m_min) { m_min = r.m_min; changed = true; }
401 if (r.m_max > m_max) { m_max = r.m_max; changed = true; }
402 } else {
403 m_min = r.m_min;
404 m_max = r.m_max;
405 changed = true;
406 }
407 return changed;
408 }
409 float getMin() const { return m_min; }
410 float getMax() const { return m_max; }
411 private:
412 float m_min;
413 float m_max;
414 };
415
416 typedef std::map<const LayerGeometryProvider *, MagnitudeRange> ViewMagMap;
417 mutable ViewMagMap m_viewMags; 310 mutable ViewMagMap m_viewMags;
418 mutable std::vector<MagnitudeRange> m_columnMags; 311 mutable ViewMagMap m_lastRenderedMags; // when in normalizeVisibleArea mode
419 void invalidateMagnitudes(); 312 void invalidateMagnitudes();
420 bool updateViewMagnitudes(LayerGeometryProvider *v) const; 313
421 bool paintDrawBuffer(LayerGeometryProvider *v, int w, int h, 314 typedef std::map<int, Colour3DPlotRenderer *> ViewRendererMap; // key is view id
422 const std::vector<int> &binforx, 315 mutable ViewRendererMap m_renderers;
423 const std::vector<double> &binfory, 316 Colour3DPlotRenderer *getRenderer(LayerGeometryProvider *) const;
424 bool usePeaksCache, 317 void invalidateRenderers();
425 MagnitudeRange &overallMag, 318
426 bool &overallMagChanged) const; 319 FFTModel *getFFTModel() const;
427 bool paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, int w, int h, 320 Dense3DModelPeakCache *getPeakCache() const;
428 const std::vector<int> &binforx, 321 void invalidateFFTModel();
429 int minbin, 322
430 int maxbin, 323 void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;
431 double displayMinFreq, 324
432 double displayMaxFreq, 325 void paintDetailedScale(LayerGeometryProvider *v,
433 bool logarithmic, 326 QPainter &paint, QRect rect) const;
434 MagnitudeRange &overallMag, 327 void paintDetailedScalePhase(LayerGeometryProvider *v,
435 bool &overallMagChanged) const; 328 QPainter &paint, QRect rect) const;
436 329
437 virtual void updateMeasureRectYCoords(LayerGeometryProvider *v, const MeasureRect &r) const; 330 virtual void updateMeasureRectYCoords(LayerGeometryProvider *v,
438 virtual void setMeasureRectYCoord(LayerGeometryProvider *v, MeasureRect &r, bool start, int y) const; 331 const MeasureRect &r) const;
332 virtual void setMeasureRectYCoord(LayerGeometryProvider *v,
333 MeasureRect &r, bool start, int y) const;
439 }; 334 };
440 335
441 #endif 336 #endif