comparison transform/FeatureExtractionPluginTransform.cpp @ 27:61259228d029

* More to do with passing around step/blocksize etc from plugin dialog to plugins. Still some puzzling unresolved details.
author Chris Cannam
date Tue, 19 Sep 2006 14:37:06 +0000
parents d88d117e0c34
children 660a973c157a
comparison
equal deleted inserted replaced
26:d88d117e0c34 27:61259228d029
32 32
33 #include <iostream> 33 #include <iostream>
34 34
35 FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel, 35 FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel,
36 QString pluginId, 36 QString pluginId,
37 int channel, 37 const ExecutionContext &context,
38 QString configurationXml, 38 QString configurationXml,
39 QString outputName, 39 QString outputName) :
40 size_t stepSize, 40 PluginTransform(inputModel, context),
41 size_t blockSize,
42 WindowType windowType) :
43 Transform(inputModel),
44 m_plugin(0), 41 m_plugin(0),
45 m_channel(channel),
46 m_stepSize(0),
47 m_blockSize(0),
48 m_windowType(windowType),
49 m_descriptor(0), 42 m_descriptor(0),
50 m_outputFeatureNo(0) 43 m_outputFeatureNo(0)
51 { 44 {
52 // std::cerr << "FeatureExtractionPluginTransform::FeatureExtractionPluginTransform: plugin " << pluginId.toStdString() << ", outputName " << outputName.toStdString() << std::endl; 45 // std::cerr << "FeatureExtractionPluginTransform::FeatureExtractionPluginTransform: plugin " << pluginId.toStdString() << ", outputName " << outputName.toStdString() << std::endl;
53 46
68 return; 61 return;
69 } 62 }
70 63
71 if (configurationXml != "") { 64 if (configurationXml != "") {
72 PluginXml(m_plugin).setParametersFromXml(configurationXml); 65 PluginXml(m_plugin).setParametersFromXml(configurationXml);
73 }
74
75 if (m_blockSize == 0) m_blockSize = m_plugin->getPreferredBlockSize();
76 if (m_stepSize == 0) m_stepSize = m_plugin->getPreferredStepSize();
77
78 if (m_blockSize == 0) m_blockSize = 1024;
79 if (m_stepSize == 0) {
80 if (m_plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) {
81 m_stepSize = m_blockSize / 2;
82 } else {
83 m_stepSize = m_blockSize;
84 }
85 } 66 }
86 67
87 DenseTimeValueModel *input = getInput(); 68 DenseTimeValueModel *input = getInput();
88 if (!input) return; 69 if (!input) return;
89 70
98 << m_plugin->getMaxChannelCount() << ", input model has " 79 << m_plugin->getMaxChannelCount() << ", input model has "
99 << input->getChannelCount() << ")" << std::endl; 80 << input->getChannelCount() << ")" << std::endl;
100 return; 81 return;
101 } 82 }
102 83
103 if (!m_plugin->initialise(channelCount, m_stepSize, m_blockSize)) { 84 std::cerr << "Initialising feature extraction plugin with channels = "
85 << channelCount << ", step = " << m_context.stepSize
86 << ", block = " << m_context.blockSize << std::endl;
87
88 if (!m_plugin->initialise(channelCount,
89 m_context.stepSize,
90 m_context.blockSize)) {
104 std::cerr << "FeatureExtractionPluginTransform: Plugin " 91 std::cerr << "FeatureExtractionPluginTransform: Plugin "
105 << m_plugin->getName() << " failed to initialise!" << std::endl; 92 << m_plugin->getName() << " failed to initialise!" << std::endl;
106 return; 93 return;
107 } 94 }
108 95
158 modelResolution = size_t(modelRate / m_descriptor->sampleRate + 0.001); 145 modelResolution = size_t(modelRate / m_descriptor->sampleRate + 0.001);
159 } 146 }
160 break; 147 break;
161 148
162 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: 149 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep:
163 modelResolution = m_stepSize; 150 modelResolution = m_context.stepSize;
164 break; 151 break;
165 152
166 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: 153 case Vamp::Plugin::OutputDescriptor::FixedSampleRate:
167 modelRate = size_t(m_descriptor->sampleRate + 0.001); 154 modelRate = size_t(m_descriptor->sampleRate + 0.001);
168 break; 155 break;
246 channelCount = 1; 233 channelCount = 1;
247 } 234 }
248 235
249 float **buffers = new float*[channelCount]; 236 float **buffers = new float*[channelCount];
250 for (size_t ch = 0; ch < channelCount; ++ch) { 237 for (size_t ch = 0; ch < channelCount; ++ch) {
251 buffers[ch] = new float[m_blockSize]; 238 buffers[ch] = new float[m_context.blockSize];
252 } 239 }
253 240
254 bool frequencyDomain = (m_plugin->getInputDomain() == 241 bool frequencyDomain = (m_plugin->getInputDomain() ==
255 Vamp::Plugin::FrequencyDomain); 242 Vamp::Plugin::FrequencyDomain);
256 std::vector<FFTModel *> fftModels; 243 std::vector<FFTModel *> fftModels;
257 244
258 if (frequencyDomain) { 245 if (frequencyDomain) {
259 for (size_t ch = 0; ch < channelCount; ++ch) { 246 for (size_t ch = 0; ch < channelCount; ++ch) {
260 fftModels.push_back(new FFTModel 247 fftModels.push_back(new FFTModel
261 (getInput(), 248 (getInput(),
262 channelCount == 1 ? m_channel : ch, 249 channelCount == 1 ? m_context.channel : ch,
263 m_windowType, 250 m_context.windowType,
264 m_blockSize, 251 m_context.blockSize,
265 m_stepSize, 252 m_context.stepSize,
266 m_blockSize, 253 m_context.blockSize,
267 false)); 254 false));
268 } 255 }
269 } 256 }
270 257
271 long startFrame = m_input->getStartFrame(); 258 long startFrame = m_input->getStartFrame();
275 long prevCompletion = 0; 262 long prevCompletion = 0;
276 263
277 while (1) { 264 while (1) {
278 265
279 if (frequencyDomain) { 266 if (frequencyDomain) {
280 if (blockFrame - int(m_blockSize)/2 > endFrame) break; 267 if (blockFrame - int(m_context.blockSize)/2 > endFrame) break;
281 } else { 268 } else {
282 if (blockFrame >= endFrame) break; 269 if (blockFrame >= endFrame) break;
283 } 270 }
284 271
285 // std::cerr << "FeatureExtractionPluginTransform::run: blockFrame " 272 // std::cerr << "FeatureExtractionPluginTransform::run: blockFrame "
286 // << blockFrame << std::endl; 273 // << blockFrame << std::endl;
287 274
288 long completion = 275 long completion =
289 (((blockFrame - startFrame) / m_stepSize) * 99) / 276 (((blockFrame - startFrame) / m_context.stepSize) * 99) /
290 ( (endFrame - startFrame) / m_stepSize); 277 ( (endFrame - startFrame) / m_context.stepSize);
291 278
292 // channelCount is either m_input->channelCount or 1 279 // channelCount is either m_input->channelCount or 1
293 280
294 for (size_t ch = 0; ch < channelCount; ++ch) { 281 for (size_t ch = 0; ch < channelCount; ++ch) {
295 if (frequencyDomain) { 282 if (frequencyDomain) {
296 int column = (blockFrame - startFrame) / m_stepSize; 283 int column = (blockFrame - startFrame) / m_context.stepSize;
297 for (size_t i = 0; i < m_blockSize/2; ++i) { 284 for (size_t i = 0; i < m_context.blockSize/2; ++i) {
298 fftModels[ch]->getValuesAt 285 fftModels[ch]->getValuesAt
299 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); 286 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]);
300 } 287 }
301 /*!!! 288 /*!!!
302 float sum = 0.0; 289 float sum = 0.0;
303 for (size_t i = 0; i < m_blockSize/2; ++i) { 290 for (size_t i = 0; i < m_context.blockSize/2; ++i) {
304 sum += buffers[ch][i*2]; 291 sum += buffers[ch][i*2];
305 } 292 }
306 if (fabs(sum) < 0.0001) { 293 if (fabs(sum) < 0.0001) {
307 std::cerr << "WARNING: small sum for column " << column << " (sum is " << sum << ")" << std::endl; 294 std::cerr << "WARNING: small sum for column " << column << " (sum is " << sum << ")" << std::endl;
308 } 295 }
309 */ 296 */
310 } else { 297 } else {
311 getFrames(ch, channelCount, 298 getFrames(ch, channelCount,
312 blockFrame, m_blockSize, buffers[ch]); 299 blockFrame, m_context.blockSize, buffers[ch]);
313 } 300 }
314 } 301 }
315 302
316 Vamp::Plugin::FeatureSet features = m_plugin->process 303 Vamp::Plugin::FeatureSet features = m_plugin->process
317 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); 304 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate));
325 if (blockFrame == startFrame || completion > prevCompletion) { 312 if (blockFrame == startFrame || completion > prevCompletion) {
326 setCompletion(completion); 313 setCompletion(completion);
327 prevCompletion = completion; 314 prevCompletion = completion;
328 } 315 }
329 316
330 blockFrame += m_stepSize; 317 blockFrame += m_context.stepSize;
331 } 318 }
332 319
333 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); 320 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures();
334 321
335 for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) { 322 for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) {
363 if (size <= 0) return; 350 if (size <= 0) return;
364 startFrame = 0; 351 startFrame = 0;
365 } 352 }
366 353
367 long got = getInput()->getValues 354 long got = getInput()->getValues
368 ((channelCount == 1 ? m_channel : channel), 355 ((channelCount == 1 ? m_context.channel : channel),
369 startFrame, startFrame + size, buffer + offset); 356 startFrame, startFrame + size, buffer + offset);
370 357
371 while (got < size) { 358 while (got < size) {
372 buffer[offset + got] = 0.0; 359 buffer[offset + got] = 0.0;
373 ++got; 360 ++got;
374 } 361 }
375 362
376 if (m_channel == -1 && channelCount == 1 && 363 if (m_context.channel == -1 && channelCount == 1 &&
377 getInput()->getChannelCount() > 1) { 364 getInput()->getChannelCount() > 1) {
378 // use mean instead of sum, as plugin input 365 // use mean instead of sum, as plugin input
379 int cc = getInput()->getChannelCount(); 366 int cc = getInput()->getChannelCount();
380 for (long i = 0; i < size; ++i) { 367 for (long i = 0; i < size; ++i) {
381 buffer[i] /= cc; 368 buffer[i] /= cc;