annotate layer/SpectrogramLayer.h @ 1:ab83c415a6cd

* Backed out partially complete changes to make the spectrogram only store results up to the requested max frequency. The speed improvement was minimal at the expense of annoyance when changing frequency limit, and although it did save memory, it wasn't yet reliable and fixing it is not a high enough priority.
author Chris Cannam
date Tue, 10 Jan 2006 17:04:02 +0000
parents 2a4f26e85b4c
children 37b110168acf
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@0 5 Chris Cannam, Queen Mary University of London, 2005
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #ifndef _SPECTROGRAM_VIEW_H_
Chris@0 11 #define _SPECTROGRAM_VIEW_H_
Chris@0 12
Chris@0 13 #include "base/Layer.h"
Chris@0 14 #include "base/Window.h"
Chris@0 15 #include "model/PowerOfSqrtTwoZoomConstraint.h"
Chris@0 16 #include "model/DenseTimeValueModel.h"
Chris@0 17
Chris@0 18 #include <QThread>
Chris@0 19 #include <QMutex>
Chris@0 20 #include <QWaitCondition>
Chris@0 21
Chris@0 22 #include <fftw3.h>
Chris@0 23
Chris@0 24 class View;
Chris@0 25 class QPainter;
Chris@0 26 class QImage;
Chris@0 27 class QPixmap;
Chris@0 28 class QTimer;
Chris@0 29 class RealTime;
Chris@0 30
Chris@0 31 /**
Chris@0 32 * SpectrogramLayer represents waveform data (obtained from a
Chris@0 33 * DenseTimeValueModel) in spectrogram form.
Chris@0 34 */
Chris@0 35
Chris@0 36 class SpectrogramLayer : public Layer,
Chris@0 37 public PowerOfSqrtTwoZoomConstraint
Chris@0 38 {
Chris@0 39 Q_OBJECT
Chris@0 40
Chris@0 41 public:
Chris@0 42 enum Configuration { FullRangeDb, MelodicRange };
Chris@0 43
Chris@0 44 SpectrogramLayer(View *w, Configuration = FullRangeDb);
Chris@0 45 ~SpectrogramLayer();
Chris@0 46
Chris@0 47 virtual const ZoomConstraint *getZoomConstraint() const { return this; }
Chris@0 48 virtual const Model *getModel() const { return m_model; }
Chris@0 49 virtual void paint(QPainter &paint, QRect rect) const;
Chris@0 50
Chris@0 51 virtual int getVerticalScaleWidth(QPainter &) const;
Chris@0 52 virtual void paintVerticalScale(QPainter &paint, QRect rect) const;
Chris@0 53
Chris@0 54 virtual QRect getFeatureDescriptionRect(QPainter &, QPoint) const;
Chris@0 55 virtual void paintLocalFeatureDescription(QPainter &, QRect, QPoint) const;
Chris@0 56
Chris@0 57 void setModel(const DenseTimeValueModel *model);
Chris@0 58
Chris@0 59 virtual PropertyList getProperties() const;
Chris@0 60 virtual PropertyType getPropertyType(const PropertyName &) const;
Chris@0 61 virtual QString getPropertyGroupName(const PropertyName &) const;
Chris@0 62 virtual int getPropertyRangeAndValue(const PropertyName &,
Chris@0 63 int *min, int *max) const;
Chris@0 64 virtual QString getPropertyValueLabel(const PropertyName &,
Chris@0 65 int value) const;
Chris@0 66 virtual void setProperty(const PropertyName &, int value);
Chris@0 67
Chris@0 68 /**
Chris@0 69 * Specify the channel to use from the source model.
Chris@0 70 * A value of -1 means to mix all available channels.
Chris@0 71 * The default is channel 0.
Chris@0 72 */
Chris@0 73 void setChannel(int);
Chris@0 74 int getChannel() const;
Chris@0 75
Chris@0 76 void setWindowSize(size_t);
Chris@0 77 size_t getWindowSize() const;
Chris@0 78
Chris@0 79 void setWindowOverlap(size_t percent);
Chris@0 80 size_t getWindowOverlap() const;
Chris@0 81
Chris@0 82 void setWindowType(WindowType type);
Chris@0 83 WindowType getWindowType() const;
Chris@0 84
Chris@0 85 /**
Chris@0 86 * Set the gain multiplier for sample values in this view prior to
Chris@0 87 * FFT calculation.
Chris@0 88 *
Chris@0 89 * The default is 1.0.
Chris@0 90 */
Chris@0 91 void setGain(float gain);
Chris@0 92 float getGain() const;
Chris@0 93
Chris@0 94 void setMaxFrequency(size_t); // 0 -> no maximum
Chris@0 95 size_t getMaxFrequency() const;
Chris@0 96
Chris@0 97 enum ColourScale { LinearColourScale, MeterColourScale, dBColourScale,
Chris@0 98 PhaseColourScale };
Chris@0 99
Chris@0 100 /**
Chris@0 101 * Specify the scale for sample levels. See WaveformLayer for
Chris@0 102 * details of meter and dB scaling. The default is dBColourScale.
Chris@0 103 */
Chris@0 104 void setColourScale(ColourScale);
Chris@0 105 ColourScale getColourScale() const;
Chris@0 106
Chris@0 107 enum FrequencyScale { LinearFrequencyScale, LogFrequencyScale };
Chris@0 108
Chris@0 109 /**
Chris@0 110 * Specify the scale for the y axis.
Chris@0 111 */
Chris@0 112 void setFrequencyScale(FrequencyScale);
Chris@0 113 FrequencyScale getFrequencyScale() const;
Chris@0 114
Chris@0 115 enum ColourScheme { DefaultColours, WhiteOnBlack, BlackOnWhite,
Chris@0 116 RedOnBlue, YellowOnBlack, RedOnBlack };
Chris@0 117
Chris@0 118 void setColourScheme(ColourScheme scheme);
Chris@0 119 ColourScheme getColourScheme() const;
Chris@0 120
Chris@0 121 virtual VerticalPosition getPreferredFrameCountPosition() const {
Chris@0 122 return PositionTop;
Chris@0 123 }
Chris@0 124
Chris@0 125 virtual int getCompletion() const;
Chris@0 126
Chris@0 127 virtual QString getPropertyContainerIconName() const { return "spectrogram"; }
Chris@0 128
Chris@0 129 protected slots:
Chris@0 130 void cacheInvalid();
Chris@0 131 void cacheInvalid(size_t startFrame, size_t endFrame);
Chris@0 132
Chris@0 133 void fillTimerTimedOut();
Chris@0 134
Chris@0 135 protected:
Chris@0 136 const DenseTimeValueModel *m_model; // I do not own this
Chris@0 137
Chris@0 138 int m_channel;
Chris@0 139 size_t m_windowSize;
Chris@0 140 WindowType m_windowType;
Chris@0 141 size_t m_windowOverlap;
Chris@0 142 float m_gain;
Chris@0 143 size_t m_maxFrequency;
Chris@0 144 ColourScale m_colourScale;
Chris@0 145 ColourScheme m_colourScheme;
Chris@0 146 FrequencyScale m_frequencyScale;
Chris@0 147
Chris@0 148 class CacheFillThread : public QThread
Chris@0 149 {
Chris@0 150 public:
Chris@0 151 CacheFillThread(SpectrogramLayer &layer) :
Chris@0 152 m_layer(layer), m_fillExtent(0) { }
Chris@0 153
Chris@0 154 size_t getFillExtent() const { return m_fillExtent; }
Chris@0 155 size_t getFillCompletion() const { return m_fillCompletion; }
Chris@0 156 virtual void run();
Chris@0 157
Chris@0 158 protected:
Chris@0 159 SpectrogramLayer &m_layer;
Chris@0 160 size_t m_fillExtent;
Chris@0 161 size_t m_fillCompletion;
Chris@0 162 };
Chris@0 163
Chris@0 164 void fillCache();
Chris@0 165
Chris@0 166 QImage *m_cache;
Chris@0 167 bool m_cacheInvalid;
Chris@0 168
Chris@0 169 mutable QPixmap *m_pixmapCache;
Chris@0 170 mutable bool m_pixmapCacheInvalid;
Chris@0 171 mutable long m_pixmapCacheStartFrame;
Chris@0 172 mutable size_t m_pixmapCacheZoomLevel;
Chris@0 173
Chris@0 174 QWaitCondition m_condition;
Chris@0 175 mutable QMutex m_mutex;
Chris@0 176
Chris@0 177 CacheFillThread *m_fillThread;
Chris@0 178 QTimer *m_updateTimer;
Chris@0 179 size_t m_lastFillExtent;
Chris@0 180 bool m_cachedInitialVisibleArea;
Chris@0 181 bool m_exiting;
Chris@0 182
Chris@0 183 void setCacheColourmap();
Chris@0 184
Chris@0 185 bool fillCacheColumn(int column,
Chris@0 186 double *inputBuffer,
Chris@0 187 fftw_complex *outputBuffer,
Chris@0 188 fftw_plan plan,
Chris@0 189 const Window<double> &windower,
Chris@0 190 bool lock)
Chris@0 191 const;
Chris@0 192
Chris@0 193 bool getYBinRange(int y, float &freqBinMin, float &freqBinMax) const;
Chris@0 194
Chris@0 195 struct LayerRange {
Chris@0 196 long startFrame;
Chris@0 197 int zoomLevel;
Chris@0 198 size_t modelStart;
Chris@0 199 size_t modelEnd;
Chris@0 200 };
Chris@0 201 /// LayerRange is only passed in to save lookup time
Chris@0 202 bool getXBinRange(int x, float &windowMin, float &windowMax,
Chris@0 203 LayerRange *range = 0) const;
Chris@0 204
Chris@0 205 bool getYBinSourceRange(int y, float &freqMin, float &freqMax) const;
Chris@0 206 bool getXBinSourceRange(int x, RealTime &timeMin, RealTime &timeMax) const;
Chris@0 207 bool getXYBinSourceRange(int x, int y, float &dbMin, float &dbMax) const;
Chris@0 208
Chris@0 209 size_t getWindowIncrement() const {
Chris@0 210 return m_windowSize - m_windowSize * m_windowOverlap / 100;
Chris@0 211 }
Chris@0 212 };
Chris@0 213
Chris@0 214 #endif