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