Mercurial > hg > svcore
comparison data/model/FFTModel.cpp @ 1094:b386363ff6c8 simple-fft-model
A small cache for source samples
author | Chris Cannam |
---|---|
date | Fri, 12 Jun 2015 19:18:56 +0100 |
parents | 44b079427b36 |
children | b66734b5f806 |
comparison
equal
deleted
inserted
replaced
1093:44b079427b36 | 1094:b386363ff6c8 |
---|---|
194 } | 194 } |
195 | 195 |
196 vector<float> | 196 vector<float> |
197 FFTModel::getSourceSamples(int column) const | 197 FFTModel::getSourceSamples(int column) const |
198 { | 198 { |
199 // m_fftSize may be greater than m_windowSize, but not the reverse | |
200 | |
201 // cerr << "getSourceSamples(" << column << ")" << endl; | |
202 | |
199 auto range = getSourceSampleRange(column); | 203 auto range = getSourceSampleRange(column); |
200 vector<float> samples(m_fftSize, 0.f); | 204 auto data = getSourceData(range); |
205 | |
201 int off = (m_fftSize - m_windowSize) / 2; | 206 int off = (m_fftSize - m_windowSize) / 2; |
207 | |
208 if (off == 0) { | |
209 return data; | |
210 } else { | |
211 vector<float> pad(off, 0.f); | |
212 vector<float> padded; | |
213 padded.reserve(m_fftSize); | |
214 padded.insert(padded.end(), pad.begin(), pad.end()); | |
215 padded.insert(padded.end(), data.begin(), data.end()); | |
216 padded.insert(padded.end(), pad.begin(), pad.end()); | |
217 return padded; | |
218 } | |
219 } | |
220 | |
221 vector<float> | |
222 FFTModel::getSourceData(pair<sv_frame_t, sv_frame_t> range) const | |
223 { | |
224 // cerr << "getSourceData(" << range.first << "," << range.second | |
225 // << "): saved range is (" << m_savedData.range.first | |
226 // << "," << m_savedData.range.second << ")" << endl; | |
227 | |
228 if (m_savedData.range == range) return m_savedData.data; | |
229 | |
230 if (range.first < m_savedData.range.second && | |
231 range.first >= m_savedData.range.first && | |
232 range.second > m_savedData.range.second) { | |
233 | |
234 //!!! Need FFTModel overlap tests to exercise this | |
235 | |
236 sv_frame_t off = range.first - m_savedData.range.first; | |
237 | |
238 vector<float> partial(m_savedData.data.begin() + off, m_savedData.data.end()); | |
239 | |
240 vector<float> rest = getSourceData({ m_savedData.range.second, range.second }); | |
241 | |
242 partial.insert(partial.end(), rest.begin(), rest.end()); | |
243 return partial; | |
244 } | |
245 | |
246 vector<float> data(range.second - range.first, 0.f); | |
202 decltype(range.first) pfx = 0; | 247 decltype(range.first) pfx = 0; |
203 if (range.first < 0) { | 248 if (range.first < 0) { |
204 pfx = -range.first; | 249 pfx = -range.first; |
205 range = { 0, range.second }; | 250 range = { 0, range.second }; |
206 } | 251 } |
252 // cerr << "requesting " << range.second - range.first << " from file" << endl; | |
207 (void) m_model->getData(m_channel, | 253 (void) m_model->getData(m_channel, |
208 range.first, | 254 range.first, |
209 range.second - range.first, | 255 range.second - range.first, |
210 &samples[off + pfx]); | 256 &data[pfx]); |
211 if (m_channel == -1) { | 257 if (m_channel == -1) { |
212 int channels = m_model->getChannelCount(); | 258 int channels = m_model->getChannelCount(); |
213 if (channels > 1) { | 259 if (channels > 1) { |
214 for (int i = 0; i < range.second - range.first; ++i) { | 260 for (int i = 0; in_range_for(data, i); ++i) { |
215 samples[off + pfx + i] /= float(channels); | 261 data[i] /= float(channels); |
216 } | 262 } |
217 } | 263 } |
218 } | 264 } |
219 return samples; | 265 |
266 m_savedData = { range, data }; | |
267 | |
268 return data; | |
220 } | 269 } |
221 | 270 |
222 vector<complex<float>> | 271 vector<complex<float>> |
223 FFTModel::getFFTColumn(int n) const | 272 FFTModel::getFFTColumn(int n) const |
224 { | 273 { |