Mercurial > hg > svcore
comparison transform/FeatureExtractionPluginTransform.cpp @ 128:f47f4c7c158c
* Add FFT data server class to provide a file cache mapping for each
required set of FFT parameters and source model. Make use of it in
feature extraction plugin transform, though not in other places yet.
* Add zero-pad option to spectrogram layer and remove window shape option
from the property box. To be revised.
author | Chris Cannam |
---|---|
date | Mon, 26 Jun 2006 16:12:11 +0000 |
parents | c1de4b4e9c29 |
children | 69d50575c52a |
comparison
equal
deleted
inserted
replaced
127:514ebb0c5c6c | 128:f47f4c7c158c |
---|---|
1 | |
2 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
3 | 2 |
4 /* | 3 /* |
5 Sonic Visualiser | 4 Sonic Visualiser |
6 An audio file viewer and annotation editor. | 5 An audio file viewer and annotation editor. |
26 #include "model/SparseTimeValueModel.h" | 25 #include "model/SparseTimeValueModel.h" |
27 #include "model/DenseThreeDimensionalModel.h" | 26 #include "model/DenseThreeDimensionalModel.h" |
28 #include "model/DenseTimeValueModel.h" | 27 #include "model/DenseTimeValueModel.h" |
29 #include "model/NoteModel.h" | 28 #include "model/NoteModel.h" |
30 | 29 |
30 #include "fileio/FFTDataServer.h" | |
31 | |
31 #include <fftw3.h> | 32 #include <fftw3.h> |
32 | 33 |
33 #include <iostream> | 34 #include <iostream> |
34 | 35 |
35 FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel, | 36 FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel, |
239 float **buffers = new float*[channelCount]; | 240 float **buffers = new float*[channelCount]; |
240 for (size_t ch = 0; ch < channelCount; ++ch) { | 241 for (size_t ch = 0; ch < channelCount; ++ch) { |
241 buffers[ch] = new float[m_blockSize]; | 242 buffers[ch] = new float[m_blockSize]; |
242 } | 243 } |
243 | 244 |
245 /*!!! | |
244 float *fftInput = 0; | 246 float *fftInput = 0; |
245 fftwf_complex *fftOutput = 0; | 247 fftwf_complex *fftOutput = 0; |
246 fftwf_plan fftPlan = 0; | 248 fftwf_plan fftPlan = 0; |
247 Window<float> windower(HanningWindow, m_blockSize); | 249 Window<float> windower(HanningWindow, m_blockSize); |
248 | 250 |
254 FFTW_ESTIMATE); | 256 FFTW_ESTIMATE); |
255 if (!fftPlan) { | 257 if (!fftPlan) { |
256 std::cerr << "ERROR: FeatureExtractionPluginTransform::run(): fftw_plan failed! Results will be garbage" << std::endl; | 258 std::cerr << "ERROR: FeatureExtractionPluginTransform::run(): fftw_plan failed! Results will be garbage" << std::endl; |
257 } | 259 } |
258 } | 260 } |
261 */ | |
262 | |
263 bool frequencyDomain = (m_plugin->getInputDomain() == | |
264 Vamp::Plugin::FrequencyDomain); | |
265 std::vector<FFTDataServer *> fftServers; | |
266 | |
267 if (frequencyDomain) { | |
268 for (size_t ch = 0; ch < channelCount; ++ch) { | |
269 fftServers.push_back(FFTDataServer::getInstance | |
270 (getInput(), | |
271 channelCount == 1 ? m_channel : ch, | |
272 HanningWindow, | |
273 m_blockSize, | |
274 m_stepSize, | |
275 m_blockSize, | |
276 false)); | |
277 } | |
278 } | |
259 | 279 |
260 long startFrame = m_input->getStartFrame(); | 280 long startFrame = m_input->getStartFrame(); |
261 long endFrame = m_input->getEndFrame(); | 281 long endFrame = m_input->getEndFrame(); |
262 long blockFrame = startFrame; | 282 long blockFrame = startFrame; |
263 | 283 |
264 long prevCompletion = 0; | 284 long prevCompletion = 0; |
265 | 285 |
266 while (1) { | 286 while (1) { |
267 | 287 |
268 if (fftPlan) { | 288 if (frequencyDomain) { |
269 if (blockFrame - int(m_blockSize)/2 > endFrame) break; | 289 if (blockFrame - int(m_blockSize)/2 > endFrame) break; |
270 } else { | 290 } else { |
271 if (blockFrame >= endFrame) break; | 291 if (blockFrame >= endFrame) break; |
272 } | 292 } |
273 | 293 |
279 ( (endFrame - startFrame) / m_stepSize); | 299 ( (endFrame - startFrame) / m_stepSize); |
280 | 300 |
281 // channelCount is either m_input->channelCount or 1 | 301 // channelCount is either m_input->channelCount or 1 |
282 | 302 |
283 for (size_t ch = 0; ch < channelCount; ++ch) { | 303 for (size_t ch = 0; ch < channelCount; ++ch) { |
284 if (fftPlan) { | 304 //!!! if (fftPlan) { |
285 getFrames(ch, channelCount, | 305 // getFrames(ch, channelCount, |
286 blockFrame - m_blockSize/2, m_blockSize, buffers[ch]); | 306 // blockFrame - m_blockSize/2, m_blockSize, buffers[ch]); |
307 | |
308 if (frequencyDomain) { | |
309 int column = (blockFrame - startFrame) / m_stepSize; | |
310 for (size_t i = 0; i < m_blockSize/2; ++i) { | |
311 fftServers[ch]->getValuesAt | |
312 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); | |
313 } | |
287 } else { | 314 } else { |
288 getFrames(ch, channelCount, | 315 getFrames(ch, channelCount, |
289 blockFrame, m_blockSize, buffers[ch]); | 316 blockFrame, m_blockSize, buffers[ch]); |
290 } | 317 } |
291 } | 318 } |
292 | 319 /*!!! |
293 if (fftPlan) { | 320 if (fftPlan) { |
294 for (size_t ch = 0; ch < channelCount; ++ch) { | 321 for (size_t ch = 0; ch < channelCount; ++ch) { |
295 for (size_t i = 0; i < m_blockSize; ++i) { | 322 for (size_t i = 0; i < m_blockSize; ++i) { |
296 fftInput[i] = buffers[ch][i]; | 323 fftInput[i] = buffers[ch][i]; |
297 } | 324 } |
306 buffers[ch][i*2] = fftOutput[i][0]; | 333 buffers[ch][i*2] = fftOutput[i][0]; |
307 buffers[ch][i*2 + 1] = fftOutput[i][1]; | 334 buffers[ch][i*2 + 1] = fftOutput[i][1]; |
308 } | 335 } |
309 } | 336 } |
310 } | 337 } |
311 | 338 */ |
312 Vamp::Plugin::FeatureSet features = m_plugin->process | 339 Vamp::Plugin::FeatureSet features = m_plugin->process |
313 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); | 340 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); |
314 | 341 |
315 for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { | 342 for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { |
316 Vamp::Plugin::Feature feature = | 343 Vamp::Plugin::Feature feature = |
323 prevCompletion = completion; | 350 prevCompletion = completion; |
324 } | 351 } |
325 | 352 |
326 blockFrame += m_stepSize; | 353 blockFrame += m_stepSize; |
327 } | 354 } |
328 | 355 /*!!! |
329 if (fftPlan) { | 356 if (fftPlan) { |
330 fftwf_destroy_plan(fftPlan); | 357 fftwf_destroy_plan(fftPlan); |
331 fftwf_free(fftInput); | 358 fftwf_free(fftInput); |
332 fftwf_free(fftOutput); | 359 fftwf_free(fftOutput); |
333 } | 360 } |
334 | 361 */ |
335 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); | 362 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); |
336 | 363 |
337 for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { | 364 for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { |
338 Vamp::Plugin::Feature feature = | 365 Vamp::Plugin::Feature feature = |
339 features[m_outputFeatureNo][fi]; | 366 features[m_outputFeatureNo][fi]; |