comparison data/model/FFTModel.cpp @ 1093:44b079427b36 simple-fft-model

Make a small cache of recently-used columns
author Chris Cannam
date Fri, 12 Jun 2015 18:50:52 +0100
parents 70f18770b72d
children b386363ff6c8
comparison
equal deleted inserted replaced
1092:70f18770b72d 1093:44b079427b36
41 m_windowType(windowType), 41 m_windowType(windowType),
42 m_windowSize(windowSize), 42 m_windowSize(windowSize),
43 m_windowIncrement(windowIncrement), 43 m_windowIncrement(windowIncrement),
44 m_fftSize(fftSize), 44 m_fftSize(fftSize),
45 m_windower(windowType, windowSize), 45 m_windower(windowType, windowSize),
46 m_fft(fftSize) 46 m_fft(fftSize),
47 m_cacheSize(3)
47 { 48 {
48 if (m_windowSize > m_fftSize) { 49 if (m_windowSize > m_fftSize) {
49 cerr << "ERROR: FFTModel::FFTModel: window size (" << m_windowSize 50 cerr << "ERROR: FFTModel::FFTModel: window size (" << m_windowSize
50 << ") must be at least FFT size (" << m_fftSize << ")" << endl; 51 << ") must be at least FFT size (" << m_fftSize << ")" << endl;
51 throw invalid_argument("FFTModel window size must be at least FFT size"); 52 throw invalid_argument("FFTModel window size must be at least FFT size");
99 } 100 }
100 101
101 float 102 float
102 FFTModel::getMagnitudeAt(int x, int y) const 103 FFTModel::getMagnitudeAt(int x, int y) const
103 { 104 {
104 //!!! 105 if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) return 0.f;
105 return abs(getFFTColumn(x)[y]); 106 auto col = getFFTColumn(x);
107 return abs(col[y]);
106 } 108 }
107 109
108 float 110 float
109 FFTModel::getMaximumMagnitudeAt(int x) const 111 FFTModel::getMaximumMagnitudeAt(int x) const
110 { 112 {
117 } 119 }
118 120
119 float 121 float
120 FFTModel::getPhaseAt(int x, int y) const 122 FFTModel::getPhaseAt(int x, int y) const
121 { 123 {
122 //!!! 124 if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) return 0.f;
123 return arg(getFFTColumn(x)[y]); 125 return arg(getFFTColumn(x)[y]);
124 } 126 }
125 127
126 void 128 void
127 FFTModel::getValuesAt(int x, int y, float &re, float &im) const 129 FFTModel::getValuesAt(int x, int y, float &re, float &im) const
130 re = col[y].real(); 132 re = col[y].real();
131 im = col[y].imag(); 133 im = col[y].imag();
132 } 134 }
133 135
134 bool 136 bool
135 FFTModel::isColumnAvailable(int ) const 137 FFTModel::isColumnAvailable(int) const
136 { 138 {
137 //!!! 139 //!!!
138 return true; 140 return true;
139 } 141 }
140 142
216 } 218 }
217 return samples; 219 return samples;
218 } 220 }
219 221
220 vector<complex<float>> 222 vector<complex<float>>
221 FFTModel::getFFTColumn(int column) const 223 FFTModel::getFFTColumn(int n) const
222 { 224 {
223 auto samples = getSourceSamples(column); 225 for (auto &incache : m_cached) {
226 if (incache.n == n) {
227 return incache.col;
228 }
229 }
230
231 auto samples = getSourceSamples(n);
224 m_windower.cut(&samples[0]); 232 m_windower.cut(&samples[0]);
225 return m_fft.process(samples); 233 auto col = m_fft.process(samples);
234
235 SavedColumn sc { n, col };
236 if (m_cached.size() >= m_cacheSize) {
237 m_cached.pop_front();
238 }
239 m_cached.push_back(sc);
240
241 return col;
226 } 242 }
227 243
228 bool 244 bool
229 FFTModel::estimateStableFrequency(int x, int y, double &frequency) 245 FFTModel::estimateStableFrequency(int x, int y, double &frequency)
230 { 246 {