annotate layer/SpectrogramLayer.h @ 11:2d5005f2b3d9

* Rework handling of layer properties in file I/O -- we now get the individual layers to load and save them rather than doing it via generic property lists in the base class, so as to ensure we read and write meaningful values rather than generic int values requiring conversion.
author Chris Cannam
date Thu, 19 Jan 2006 12:54:38 +0000
parents 561be41ad083
children 01849cd277e6
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@5 5 Chris Cannam, Queen Mary University of London, 2005-2006
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@9 121 /**
Chris@9 122 * Specify the colourmap rotation for the colour scale.
Chris@9 123 */
Chris@9 124 void setColourRotation(int);
Chris@9 125 int getColourRotation() const;
Chris@9 126
Chris@0 127 virtual VerticalPosition getPreferredFrameCountPosition() const {
Chris@0 128 return PositionTop;
Chris@0 129 }
Chris@0 130
Chris@0 131 virtual int getCompletion() const;
Chris@0 132
Chris@0 133 virtual QString getPropertyContainerIconName() const { return "spectrogram"; }
Chris@0 134
Chris@6 135 virtual QString toXmlString(QString indent = "",
Chris@6 136 QString extraAttributes = "") const;
Chris@6 137
Chris@11 138 void setProperties(const QXmlAttributes &attributes);
Chris@11 139
Chris@0 140 protected slots:
Chris@0 141 void cacheInvalid();
Chris@0 142 void cacheInvalid(size_t startFrame, size_t endFrame);
Chris@0 143
Chris@0 144 void fillTimerTimedOut();
Chris@0 145
Chris@0 146 protected:
Chris@0 147 const DenseTimeValueModel *m_model; // I do not own this
Chris@0 148
Chris@6 149 int m_channel;
Chris@6 150 size_t m_windowSize;
Chris@6 151 WindowType m_windowType;
Chris@6 152 size_t m_windowOverlap;
Chris@6 153 float m_gain;
Chris@9 154 int m_colourRotation;
Chris@6 155 size_t m_maxFrequency;
Chris@6 156 ColourScale m_colourScale;
Chris@6 157 ColourScheme m_colourScheme;
Chris@0 158 FrequencyScale m_frequencyScale;
Chris@0 159
Chris@0 160 class CacheFillThread : public QThread
Chris@0 161 {
Chris@0 162 public:
Chris@0 163 CacheFillThread(SpectrogramLayer &layer) :
Chris@0 164 m_layer(layer), m_fillExtent(0) { }
Chris@0 165
Chris@0 166 size_t getFillExtent() const { return m_fillExtent; }
Chris@0 167 size_t getFillCompletion() const { return m_fillCompletion; }
Chris@0 168 virtual void run();
Chris@0 169
Chris@0 170 protected:
Chris@0 171 SpectrogramLayer &m_layer;
Chris@0 172 size_t m_fillExtent;
Chris@0 173 size_t m_fillCompletion;
Chris@0 174 };
Chris@0 175
Chris@0 176 void fillCache();
Chris@0 177
Chris@0 178 QImage *m_cache;
Chris@0 179 bool m_cacheInvalid;
Chris@0 180
Chris@0 181 mutable QPixmap *m_pixmapCache;
Chris@0 182 mutable bool m_pixmapCacheInvalid;
Chris@0 183 mutable long m_pixmapCacheStartFrame;
Chris@0 184 mutable size_t m_pixmapCacheZoomLevel;
Chris@0 185
Chris@0 186 QWaitCondition m_condition;
Chris@0 187 mutable QMutex m_mutex;
Chris@0 188
Chris@0 189 CacheFillThread *m_fillThread;
Chris@0 190 QTimer *m_updateTimer;
Chris@0 191 size_t m_lastFillExtent;
Chris@0 192 bool m_cachedInitialVisibleArea;
Chris@0 193 bool m_exiting;
Chris@0 194
Chris@0 195 void setCacheColourmap();
Chris@9 196 void rotateCacheColourmap(int distance);
Chris@0 197
Chris@0 198 bool fillCacheColumn(int column,
Chris@0 199 double *inputBuffer,
Chris@0 200 fftw_complex *outputBuffer,
Chris@0 201 fftw_plan plan,
Chris@9 202 size_t windowSize,
Chris@9 203 size_t windowIncrement,
Chris@0 204 const Window<double> &windower,
Chris@0 205 bool lock)
Chris@0 206 const;
Chris@0 207
Chris@0 208 bool getYBinRange(int y, float &freqBinMin, float &freqBinMax) const;
Chris@0 209
Chris@0 210 struct LayerRange {
Chris@0 211 long startFrame;
Chris@0 212 int zoomLevel;
Chris@0 213 size_t modelStart;
Chris@0 214 size_t modelEnd;
Chris@0 215 };
Chris@0 216 /// LayerRange is only passed in to save lookup time
Chris@0 217 bool getXBinRange(int x, float &windowMin, float &windowMax,
Chris@0 218 LayerRange *range = 0) const;
Chris@0 219
Chris@0 220 bool getYBinSourceRange(int y, float &freqMin, float &freqMax) const;
Chris@0 221 bool getXBinSourceRange(int x, RealTime &timeMin, RealTime &timeMax) const;
Chris@0 222 bool getXYBinSourceRange(int x, int y, float &dbMin, float &dbMax) const;
Chris@0 223
Chris@0 224 size_t getWindowIncrement() const {
Chris@0 225 return m_windowSize - m_windowSize * m_windowOverlap / 100;
Chris@0 226 }
Chris@0 227 };
Chris@0 228
Chris@0 229 #endif