Mercurial > hg > sonic-visualiser
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; | 
