Mercurial > hg > svcore
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 { |