Mercurial > hg > svcore
comparison plugin/transform/FeatureExtractionModelTransformer.cpp @ 383:94fc0591ea43 1.2-stable
* merge from trunk (1.2 ended up being tracked from trunk, but we may want
this branch for fixes later)
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 10:32:45 +0000 |
parents | 277006c62fea |
children |
comparison
equal
deleted
inserted
replaced
349:f39d33b0b265 | 383:94fc0591ea43 |
---|---|
27 #include "data/model/DenseTimeValueModel.h" | 27 #include "data/model/DenseTimeValueModel.h" |
28 #include "data/model/NoteModel.h" | 28 #include "data/model/NoteModel.h" |
29 #include "data/model/FFTModel.h" | 29 #include "data/model/FFTModel.h" |
30 #include "data/model/WaveFileModel.h" | 30 #include "data/model/WaveFileModel.h" |
31 | 31 |
32 #include "TransformFactory.h" | |
33 | |
32 #include <QMessageBox> | 34 #include <QMessageBox> |
33 | 35 |
34 #include <iostream> | 36 #include <iostream> |
35 | 37 |
36 FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Model *inputModel, | 38 FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, |
37 QString pluginId, | 39 const Transform &transform) : |
38 const ExecutionContext &context, | 40 ModelTransformer(in, transform), |
39 QString configurationXml, | |
40 QString outputName) : | |
41 PluginTransformer(inputModel, context), | |
42 m_plugin(0), | 41 m_plugin(0), |
43 m_descriptor(0), | 42 m_descriptor(0), |
44 m_outputFeatureNo(0) | 43 m_outputFeatureNo(0) |
45 { | 44 { |
46 // std::cerr << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << pluginId.toStdString() << ", outputName " << outputName.toStdString() << std::endl; | 45 // std::cerr << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << pluginId.toStdString() << ", outputName " << m_transform.getOutput().toStdString() << std::endl; |
46 | |
47 QString pluginId = transform.getPluginIdentifier(); | |
47 | 48 |
48 FeatureExtractionPluginFactory *factory = | 49 FeatureExtractionPluginFactory *factory = |
49 FeatureExtractionPluginFactory::instanceFor(pluginId); | 50 FeatureExtractionPluginFactory::instanceFor(pluginId); |
50 | 51 |
51 if (!factory) { | 52 if (!factory) { |
52 std::cerr << "FeatureExtractionModelTransformer: No factory available for plugin id \"" | 53 m_message = tr("No factory available for feature extraction plugin id \"%1\" (unknown plugin type, or internal error?)").arg(pluginId); |
53 << pluginId.toStdString() << "\"" << std::endl; | |
54 return; | 54 return; |
55 } | 55 } |
56 | 56 |
57 m_plugin = factory->instantiatePlugin(pluginId, m_input->getSampleRate()); | 57 DenseTimeValueModel *input = getConformingInput(); |
58 | 58 if (!input) { |
59 m_message = tr("Input model for feature extraction plugin \"%1\" is of wrong type (internal error?)").arg(pluginId); | |
60 return; | |
61 } | |
62 | |
63 m_plugin = factory->instantiatePlugin(pluginId, input->getSampleRate()); | |
59 if (!m_plugin) { | 64 if (!m_plugin) { |
60 std::cerr << "FeatureExtractionModelTransformer: Failed to instantiate plugin \"" | 65 m_message = tr("Failed to instantiate plugin \"%1\"").arg(pluginId); |
61 << pluginId.toStdString() << "\"" << std::endl; | |
62 return; | 66 return; |
63 } | 67 } |
64 | 68 |
65 m_context.makeConsistentWithPlugin(m_plugin); | 69 TransformFactory::getInstance()->makeContextConsistentWithPlugin |
66 | 70 (m_transform, m_plugin); |
67 if (configurationXml != "") { | 71 |
68 PluginXml(m_plugin).setParametersFromXml(configurationXml); | 72 TransformFactory::getInstance()->setPluginParameters |
69 } | 73 (m_transform, m_plugin); |
70 | |
71 DenseTimeValueModel *input = getInput(); | |
72 if (!input) return; | |
73 | 74 |
74 size_t channelCount = input->getChannelCount(); | 75 size_t channelCount = input->getChannelCount(); |
75 if (m_plugin->getMaxChannelCount() < channelCount) { | 76 if (m_plugin->getMaxChannelCount() < channelCount) { |
76 channelCount = 1; | 77 channelCount = 1; |
77 } | 78 } |
78 if (m_plugin->getMinChannelCount() > channelCount) { | 79 if (m_plugin->getMinChannelCount() > channelCount) { |
79 std::cerr << "FeatureExtractionModelTransformer:: " | 80 m_message = tr("Cannot provide enough channels to feature extraction plugin \"%1\" (plugin min is %2, max %3; input model has %4)") |
80 << "Can't provide enough channels to plugin (plugin min " | 81 .arg(pluginId) |
81 << m_plugin->getMinChannelCount() << ", max " | 82 .arg(m_plugin->getMinChannelCount()) |
82 << m_plugin->getMaxChannelCount() << ", input model has " | 83 .arg(m_plugin->getMaxChannelCount()) |
83 << input->getChannelCount() << ")" << std::endl; | 84 .arg(input->getChannelCount()); |
84 return; | 85 return; |
85 } | 86 } |
86 | 87 |
87 std::cerr << "Initialising feature extraction plugin with channels = " | 88 std::cerr << "Initialising feature extraction plugin with channels = " |
88 << channelCount << ", step = " << m_context.stepSize | 89 << channelCount << ", step = " << m_transform.getStepSize() |
89 << ", block = " << m_context.blockSize << std::endl; | 90 << ", block = " << m_transform.getBlockSize() << std::endl; |
90 | 91 |
91 if (!m_plugin->initialise(channelCount, | 92 if (!m_plugin->initialise(channelCount, |
92 m_context.stepSize, | 93 m_transform.getStepSize(), |
93 m_context.blockSize)) { | 94 m_transform.getBlockSize())) { |
94 std::cerr << "FeatureExtractionModelTransformer: Plugin " | 95 |
95 << m_plugin->getIdentifier() << " failed to initialise!" << std::endl; | 96 size_t pstep = m_transform.getStepSize(); |
96 return; | 97 size_t pblock = m_transform.getBlockSize(); |
98 | |
99 m_transform.setStepSize(0); | |
100 m_transform.setBlockSize(0); | |
101 TransformFactory::getInstance()->makeContextConsistentWithPlugin | |
102 (m_transform, m_plugin); | |
103 | |
104 if (m_transform.getStepSize() != pstep || | |
105 m_transform.getBlockSize() != pblock) { | |
106 | |
107 if (!m_plugin->initialise(channelCount, | |
108 m_transform.getStepSize(), | |
109 m_transform.getBlockSize())) { | |
110 | |
111 m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId); | |
112 return; | |
113 | |
114 } else { | |
115 | |
116 m_message = tr("Feature extraction plugin \"%1\" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead") | |
117 .arg(pluginId) | |
118 .arg(pstep) | |
119 .arg(pblock) | |
120 .arg(m_transform.getStepSize()) | |
121 .arg(m_transform.getBlockSize()); | |
122 } | |
123 | |
124 } else { | |
125 | |
126 m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId); | |
127 return; | |
128 } | |
129 } | |
130 | |
131 if (m_transform.getPluginVersion() != "") { | |
132 QString pv = QString("%1").arg(m_plugin->getPluginVersion()); | |
133 if (pv != m_transform.getPluginVersion()) { | |
134 QString vm = tr("Transform was configured for version %1 of plugin \"%2\", but the plugin being used is version %3") | |
135 .arg(m_transform.getPluginVersion()) | |
136 .arg(pluginId) | |
137 .arg(pv); | |
138 if (m_message != "") { | |
139 m_message = QString("%1; %2").arg(vm).arg(m_message); | |
140 } else { | |
141 m_message = vm; | |
142 } | |
143 } | |
97 } | 144 } |
98 | 145 |
99 Vamp::Plugin::OutputList outputs = m_plugin->getOutputDescriptors(); | 146 Vamp::Plugin::OutputList outputs = m_plugin->getOutputDescriptors(); |
100 | 147 |
101 if (outputs.empty()) { | 148 if (outputs.empty()) { |
102 std::cerr << "FeatureExtractionModelTransformer: Plugin \"" | 149 m_message = tr("Plugin \"%1\" has no outputs").arg(pluginId); |
103 << pluginId.toStdString() << "\" has no outputs" << std::endl; | |
104 return; | 150 return; |
105 } | 151 } |
106 | 152 |
107 for (size_t i = 0; i < outputs.size(); ++i) { | 153 for (size_t i = 0; i < outputs.size(); ++i) { |
108 if (outputName == "" || outputs[i].identifier == outputName.toStdString()) { | 154 if (m_transform.getOutput() == "" || |
155 outputs[i].identifier == m_transform.getOutput().toStdString()) { | |
109 m_outputFeatureNo = i; | 156 m_outputFeatureNo = i; |
110 m_descriptor = new Vamp::Plugin::OutputDescriptor | 157 m_descriptor = new Vamp::Plugin::OutputDescriptor |
111 (outputs[i]); | 158 (outputs[i]); |
112 break; | 159 break; |
113 } | 160 } |
114 } | 161 } |
115 | 162 |
116 if (!m_descriptor) { | 163 if (!m_descriptor) { |
117 std::cerr << "FeatureExtractionModelTransformer: Plugin \"" | 164 m_message = tr("Plugin \"%1\" has no output named \"%2\"") |
118 << pluginId.toStdString() << "\" has no output named \"" | 165 .arg(pluginId) |
119 << outputName.toStdString() << "\"" << std::endl; | 166 .arg(m_transform.getOutput()); |
120 return; | 167 return; |
121 } | 168 } |
122 | 169 |
123 // std::cerr << "FeatureExtractionModelTransformer: output sample type " | 170 // std::cerr << "FeatureExtractionModelTransformer: output sample type " |
124 // << m_descriptor->sampleType << std::endl; | 171 // << m_descriptor->sampleType << std::endl; |
138 minValue = m_descriptor->minValue; | 185 minValue = m_descriptor->minValue; |
139 maxValue = m_descriptor->maxValue; | 186 maxValue = m_descriptor->maxValue; |
140 haveExtents = true; | 187 haveExtents = true; |
141 } | 188 } |
142 | 189 |
143 size_t modelRate = m_input->getSampleRate(); | 190 size_t modelRate = input->getSampleRate(); |
144 size_t modelResolution = 1; | 191 size_t modelResolution = 1; |
145 | 192 |
146 switch (m_descriptor->sampleType) { | 193 switch (m_descriptor->sampleType) { |
147 | 194 |
148 case Vamp::Plugin::OutputDescriptor::VariableSampleRate: | 195 case Vamp::Plugin::OutputDescriptor::VariableSampleRate: |
150 modelResolution = size_t(modelRate / m_descriptor->sampleRate + 0.001); | 197 modelResolution = size_t(modelRate / m_descriptor->sampleRate + 0.001); |
151 } | 198 } |
152 break; | 199 break; |
153 | 200 |
154 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: | 201 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: |
155 modelResolution = m_context.stepSize; | 202 modelResolution = m_transform.getStepSize(); |
156 break; | 203 break; |
157 | 204 |
158 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: | 205 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: |
159 modelRate = size_t(m_descriptor->sampleRate + 0.001); | 206 modelRate = size_t(m_descriptor->sampleRate + 0.001); |
160 break; | 207 break; |
217 } | 264 } |
218 | 265 |
219 m_output = model; | 266 m_output = model; |
220 } | 267 } |
221 | 268 |
222 if (m_output) m_output->setSourceModel(m_input); | 269 if (m_output) m_output->setSourceModel(input); |
223 } | 270 } |
224 | 271 |
225 FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer() | 272 FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer() |
226 { | 273 { |
227 std::cerr << "FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer()" << std::endl; | 274 std::cerr << "FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer()" << std::endl; |
228 delete m_plugin; | 275 delete m_plugin; |
229 delete m_descriptor; | 276 delete m_descriptor; |
230 } | 277 } |
231 | 278 |
232 DenseTimeValueModel * | 279 DenseTimeValueModel * |
233 FeatureExtractionModelTransformer::getInput() | 280 FeatureExtractionModelTransformer::getConformingInput() |
234 { | 281 { |
235 DenseTimeValueModel *dtvm = | 282 DenseTimeValueModel *dtvm = |
236 dynamic_cast<DenseTimeValueModel *>(getInputModel()); | 283 dynamic_cast<DenseTimeValueModel *>(getInputModel()); |
237 if (!dtvm) { | 284 if (!dtvm) { |
238 std::cerr << "FeatureExtractionModelTransformer::getInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl; | 285 std::cerr << "FeatureExtractionModelTransformer::getConformingInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl; |
239 } | 286 } |
240 return dtvm; | 287 return dtvm; |
241 } | 288 } |
242 | 289 |
243 void | 290 void |
244 FeatureExtractionModelTransformer::run() | 291 FeatureExtractionModelTransformer::run() |
245 { | 292 { |
246 DenseTimeValueModel *input = getInput(); | 293 DenseTimeValueModel *input = getConformingInput(); |
247 if (!input) return; | 294 if (!input) return; |
248 | 295 |
249 if (!m_output) return; | 296 if (!m_output) return; |
250 | 297 |
251 while (!input->isReady()) { | 298 while (!input->isReady()) { |
258 */ | 305 */ |
259 std::cerr << "FeatureExtractionModelTransformer::run: Waiting for input model to be ready..." << std::endl; | 306 std::cerr << "FeatureExtractionModelTransformer::run: Waiting for input model to be ready..." << std::endl; |
260 sleep(1); | 307 sleep(1); |
261 } | 308 } |
262 | 309 |
263 size_t sampleRate = m_input->getSampleRate(); | 310 size_t sampleRate = input->getSampleRate(); |
264 | 311 |
265 size_t channelCount = input->getChannelCount(); | 312 size_t channelCount = input->getChannelCount(); |
266 if (m_plugin->getMaxChannelCount() < channelCount) { | 313 if (m_plugin->getMaxChannelCount() < channelCount) { |
267 channelCount = 1; | 314 channelCount = 1; |
268 } | 315 } |
269 | 316 |
270 float **buffers = new float*[channelCount]; | 317 float **buffers = new float*[channelCount]; |
271 for (size_t ch = 0; ch < channelCount; ++ch) { | 318 for (size_t ch = 0; ch < channelCount; ++ch) { |
272 buffers[ch] = new float[m_context.blockSize + 2]; | 319 buffers[ch] = new float[m_transform.getBlockSize() + 2]; |
273 } | 320 } |
321 | |
322 size_t stepSize = m_transform.getStepSize(); | |
323 size_t blockSize = m_transform.getBlockSize(); | |
274 | 324 |
275 bool frequencyDomain = (m_plugin->getInputDomain() == | 325 bool frequencyDomain = (m_plugin->getInputDomain() == |
276 Vamp::Plugin::FrequencyDomain); | 326 Vamp::Plugin::FrequencyDomain); |
277 std::vector<FFTModel *> fftModels; | 327 std::vector<FFTModel *> fftModels; |
278 | 328 |
279 if (frequencyDomain) { | 329 if (frequencyDomain) { |
280 for (size_t ch = 0; ch < channelCount; ++ch) { | 330 for (size_t ch = 0; ch < channelCount; ++ch) { |
281 FFTModel *model = new FFTModel | 331 FFTModel *model = new FFTModel |
282 (getInput(), | 332 (getConformingInput(), |
283 channelCount == 1 ? m_context.channel : ch, | 333 channelCount == 1 ? m_input.getChannel() : ch, |
284 m_context.windowType, | 334 m_transform.getWindowType(), |
285 m_context.blockSize, | 335 blockSize, |
286 m_context.stepSize, | 336 stepSize, |
287 m_context.blockSize, | 337 blockSize, |
288 false, | 338 false, |
289 StorageAdviser::PrecisionCritical); | 339 StorageAdviser::PrecisionCritical); |
290 if (!model->isOK()) { | 340 if (!model->isOK()) { |
291 QMessageBox::critical | 341 QMessageBox::critical |
292 (0, tr("FFT cache failed"), | 342 (0, tr("FFT cache failed"), |
299 model->resume(); | 349 model->resume(); |
300 fftModels.push_back(model); | 350 fftModels.push_back(model); |
301 } | 351 } |
302 } | 352 } |
303 | 353 |
304 long startFrame = m_input->getStartFrame(); | 354 long startFrame = m_input.getModel()->getStartFrame(); |
305 long endFrame = m_input->getEndFrame(); | 355 long endFrame = m_input.getModel()->getEndFrame(); |
306 | 356 |
307 long contextStart = m_context.startFrame; | 357 RealTime contextStartRT = m_transform.getStartTime(); |
308 long contextDuration = m_context.duration; | 358 RealTime contextDurationRT = m_transform.getDuration(); |
359 | |
360 long contextStart = | |
361 RealTime::realTime2Frame(contextStartRT, sampleRate); | |
362 | |
363 long contextDuration = | |
364 RealTime::realTime2Frame(contextDurationRT, sampleRate); | |
309 | 365 |
310 if (contextStart == 0 || contextStart < startFrame) { | 366 if (contextStart == 0 || contextStart < startFrame) { |
311 contextStart = startFrame; | 367 contextStart = startFrame; |
312 } | 368 } |
313 | 369 |
325 setCompletion(0); | 381 setCompletion(0); |
326 | 382 |
327 while (!m_abandoned) { | 383 while (!m_abandoned) { |
328 | 384 |
329 if (frequencyDomain) { | 385 if (frequencyDomain) { |
330 if (blockFrame - int(m_context.blockSize)/2 > | 386 if (blockFrame - int(blockSize)/2 > |
331 contextStart + contextDuration) break; | 387 contextStart + contextDuration) break; |
332 } else { | 388 } else { |
333 if (blockFrame >= | 389 if (blockFrame >= |
334 contextStart + contextDuration) break; | 390 contextStart + contextDuration) break; |
335 } | 391 } |
336 | 392 |
337 // std::cerr << "FeatureExtractionModelTransformer::run: blockFrame " | 393 // std::cerr << "FeatureExtractionModelTransformer::run: blockFrame " |
338 // << blockFrame << ", endFrame " << endFrame << ", blockSize " | 394 // << blockFrame << ", endFrame " << endFrame << ", blockSize " |
339 // << m_context.blockSize << std::endl; | 395 // << blockSize << std::endl; |
340 | 396 |
341 long completion = | 397 long completion = |
342 (((blockFrame - contextStart) / m_context.stepSize) * 99) / | 398 (((blockFrame - contextStart) / stepSize) * 99) / |
343 (contextDuration / m_context.stepSize); | 399 (contextDuration / stepSize); |
344 | 400 |
345 // channelCount is either m_input->channelCount or 1 | 401 // channelCount is either m_input.getModel()->channelCount or 1 |
346 | 402 |
347 for (size_t ch = 0; ch < channelCount; ++ch) { | 403 if (frequencyDomain) { |
348 if (frequencyDomain) { | 404 for (size_t ch = 0; ch < channelCount; ++ch) { |
349 int column = (blockFrame - startFrame) / m_context.stepSize; | 405 int column = (blockFrame - startFrame) / stepSize; |
350 for (size_t i = 0; i <= m_context.blockSize/2; ++i) { | 406 for (size_t i = 0; i <= blockSize/2; ++i) { |
351 fftModels[ch]->getValuesAt | 407 fftModels[ch]->getValuesAt |
352 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); | 408 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); |
353 } | 409 } |
354 } else { | 410 } |
355 getFrames(ch, channelCount, | 411 } else { |
356 blockFrame, m_context.blockSize, buffers[ch]); | 412 getFrames(channelCount, blockFrame, blockSize, buffers); |
357 } | |
358 } | 413 } |
359 | 414 |
360 Vamp::Plugin::FeatureSet features = m_plugin->process | 415 Vamp::Plugin::FeatureSet features = m_plugin->process |
361 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); | 416 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); |
362 | 417 |
369 if (blockFrame == contextStart || completion > prevCompletion) { | 424 if (blockFrame == contextStart || completion > prevCompletion) { |
370 setCompletion(completion); | 425 setCompletion(completion); |
371 prevCompletion = completion; | 426 prevCompletion = completion; |
372 } | 427 } |
373 | 428 |
374 blockFrame += m_context.stepSize; | 429 blockFrame += stepSize; |
375 } | 430 } |
376 | 431 |
377 if (m_abandoned) return; | 432 if (m_abandoned) return; |
378 | 433 |
379 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); | 434 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); |
392 | 447 |
393 setCompletion(100); | 448 setCompletion(100); |
394 } | 449 } |
395 | 450 |
396 void | 451 void |
397 FeatureExtractionModelTransformer::getFrames(int channel, int channelCount, | 452 FeatureExtractionModelTransformer::getFrames(int channelCount, |
398 long startFrame, long size, | 453 long startFrame, long size, |
399 float *buffer) | 454 float **buffers) |
400 { | 455 { |
401 long offset = 0; | 456 long offset = 0; |
402 | 457 |
403 if (startFrame < 0) { | 458 if (startFrame < 0) { |
404 for (int i = 0; i < size && startFrame + i < 0; ++i) { | 459 for (int c = 0; c < channelCount; ++c) { |
405 buffer[i] = 0.0f; | 460 for (int i = 0; i < size && startFrame + i < 0; ++i) { |
461 buffers[c][i] = 0.0f; | |
462 } | |
406 } | 463 } |
407 offset = -startFrame; | 464 offset = -startFrame; |
408 size -= offset; | 465 size -= offset; |
409 if (size <= 0) return; | 466 if (size <= 0) return; |
410 startFrame = 0; | 467 startFrame = 0; |
411 } | 468 } |
412 | 469 |
413 long got = getInput()->getData | 470 DenseTimeValueModel *input = getConformingInput(); |
414 ((channelCount == 1 ? m_context.channel : channel), | 471 if (!input) return; |
415 startFrame, size, buffer + offset); | 472 |
473 long got = 0; | |
474 | |
475 if (channelCount == 1) { | |
476 | |
477 got = input->getData(m_input.getChannel(), startFrame, size, | |
478 buffers[0] + offset); | |
479 | |
480 if (m_input.getChannel() == -1 && input->getChannelCount() > 1) { | |
481 // use mean instead of sum, as plugin input | |
482 float cc = float(input->getChannelCount()); | |
483 for (long i = 0; i < size; ++i) { | |
484 buffers[0][i + offset] /= cc; | |
485 } | |
486 } | |
487 | |
488 } else { | |
489 | |
490 float **writebuf = buffers; | |
491 if (offset > 0) { | |
492 writebuf = new float *[channelCount]; | |
493 for (int i = 0; i < channelCount; ++i) { | |
494 writebuf[i] = buffers[i] + offset; | |
495 } | |
496 } | |
497 | |
498 got = input->getData(0, channelCount-1, startFrame, size, writebuf); | |
499 | |
500 if (writebuf != buffers) delete[] writebuf; | |
501 } | |
416 | 502 |
417 while (got < size) { | 503 while (got < size) { |
418 buffer[offset + got] = 0.0; | 504 for (int c = 0; c < channelCount; ++c) { |
505 buffers[c][got + offset] = 0.0; | |
506 } | |
419 ++got; | 507 ++got; |
420 } | |
421 | |
422 if (m_context.channel == -1 && channelCount == 1 && | |
423 getInput()->getChannelCount() > 1) { | |
424 // use mean instead of sum, as plugin input | |
425 int cc = getInput()->getChannelCount(); | |
426 for (long i = 0; i < size; ++i) { | |
427 buffer[i] /= cc; | |
428 } | |
429 } | 508 } |
430 } | 509 } |
431 | 510 |
432 void | 511 void |
433 FeatureExtractionModelTransformer::addFeature(size_t blockFrame, | 512 FeatureExtractionModelTransformer::addFeature(size_t blockFrame, |
434 const Vamp::Plugin::Feature &feature) | 513 const Vamp::Plugin::Feature &feature) |
435 { | 514 { |
436 size_t inputRate = m_input->getSampleRate(); | 515 size_t inputRate = m_input.getModel()->getSampleRate(); |
437 | 516 |
438 // std::cerr << "FeatureExtractionModelTransformer::addFeature(" | 517 // std::cerr << "FeatureExtractionModelTransformer::addFeature(" |
439 // << blockFrame << ")" << std::endl; | 518 // << blockFrame << ")" << std::endl; |
440 | 519 |
441 int binCount = 1; | 520 int binCount = 1; |
470 } | 549 } |
471 } | 550 } |
472 | 551 |
473 if (binCount == 0) { | 552 if (binCount == 0) { |
474 | 553 |
475 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); | 554 SparseOneDimensionalModel *model = |
555 getConformingOutput<SparseOneDimensionalModel>(); | |
476 if (!model) return; | 556 if (!model) return; |
557 | |
477 model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str())); | 558 model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str())); |
478 | 559 |
479 } else if (binCount == 1) { | 560 } else if (binCount == 1) { |
480 | 561 |
481 float value = 0.0; | 562 float value = 0.0; |
482 if (feature.values.size() > 0) value = feature.values[0]; | 563 if (feature.values.size() > 0) value = feature.values[0]; |
483 | 564 |
484 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); | 565 SparseTimeValueModel *model = |
566 getConformingOutput<SparseTimeValueModel>(); | |
485 if (!model) return; | 567 if (!model) return; |
568 | |
486 model->addPoint(SparseTimeValueModel::Point(frame, value, feature.label.c_str())); | 569 model->addPoint(SparseTimeValueModel::Point(frame, value, feature.label.c_str())); |
487 // std::cerr << "SparseTimeValueModel::addPoint(" << frame << ", " << value << "), " << feature.label.c_str() << std::endl; | 570 // std::cerr << "SparseTimeValueModel::addPoint(" << frame << ", " << value << "), " << feature.label.c_str() << std::endl; |
488 | 571 |
489 } else if (m_descriptor->sampleType == | 572 } else if (m_descriptor->sampleType == |
490 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { | 573 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { |
498 float velocity = 100; | 581 float velocity = 100; |
499 if (feature.values.size() > 2) velocity = feature.values[2]; | 582 if (feature.values.size() > 2) velocity = feature.values[2]; |
500 if (velocity < 0) velocity = 127; | 583 if (velocity < 0) velocity = 127; |
501 if (velocity > 127) velocity = 127; | 584 if (velocity > 127) velocity = 127; |
502 | 585 |
503 NoteModel *model = getOutput<NoteModel>(); | 586 NoteModel *model = getConformingOutput<NoteModel>(); |
504 if (!model) return; | 587 if (!model) return; |
505 | 588 |
506 model->addPoint(NoteModel::Point(frame, pitch, | 589 model->addPoint(NoteModel::Point(frame, pitch, |
507 lrintf(duration), | 590 lrintf(duration), |
508 velocity / 127.f, | 591 velocity / 127.f, |
511 } else { | 594 } else { |
512 | 595 |
513 DenseThreeDimensionalModel::Column values = feature.values; | 596 DenseThreeDimensionalModel::Column values = feature.values; |
514 | 597 |
515 EditableDenseThreeDimensionalModel *model = | 598 EditableDenseThreeDimensionalModel *model = |
516 getOutput<EditableDenseThreeDimensionalModel>(); | 599 getConformingOutput<EditableDenseThreeDimensionalModel>(); |
517 if (!model) return; | 600 if (!model) return; |
518 | 601 |
519 model->setColumn(frame / model->getResolution(), values); | 602 model->setColumn(frame / model->getResolution(), values); |
520 } | 603 } |
521 } | 604 } |
531 // std::cerr << "FeatureExtractionModelTransformer::setCompletion(" | 614 // std::cerr << "FeatureExtractionModelTransformer::setCompletion(" |
532 // << completion << ")" << std::endl; | 615 // << completion << ")" << std::endl; |
533 | 616 |
534 if (binCount == 0) { | 617 if (binCount == 0) { |
535 | 618 |
536 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); | 619 SparseOneDimensionalModel *model = |
620 getConformingOutput<SparseOneDimensionalModel>(); | |
537 if (!model) return; | 621 if (!model) return; |
538 model->setCompletion(completion, m_context.updates); | 622 model->setCompletion(completion, true); //!!!m_context.updates); |
539 | 623 |
540 } else if (binCount == 1) { | 624 } else if (binCount == 1) { |
541 | 625 |
542 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); | 626 SparseTimeValueModel *model = |
627 getConformingOutput<SparseTimeValueModel>(); | |
543 if (!model) return; | 628 if (!model) return; |
544 model->setCompletion(completion, m_context.updates); | 629 model->setCompletion(completion, true); //!!!m_context.updates); |
545 | 630 |
546 } else if (m_descriptor->sampleType == | 631 } else if (m_descriptor->sampleType == |
547 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { | 632 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { |
548 | 633 |
549 NoteModel *model = getOutput<NoteModel>(); | 634 NoteModel *model = |
635 getConformingOutput<NoteModel>(); | |
550 if (!model) return; | 636 if (!model) return; |
551 model->setCompletion(completion, m_context.updates); | 637 model->setCompletion(completion, true); //!!!m_context.updates); |
552 | 638 |
553 } else { | 639 } else { |
554 | 640 |
555 EditableDenseThreeDimensionalModel *model = | 641 EditableDenseThreeDimensionalModel *model = |
556 getOutput<EditableDenseThreeDimensionalModel>(); | 642 getConformingOutput<EditableDenseThreeDimensionalModel>(); |
557 if (!model) return; | 643 if (!model) return; |
558 model->setCompletion(completion, m_context.updates); | 644 model->setCompletion(completion, true); //!!!m_context.updates); |
559 } | 645 } |
560 } | 646 } |
561 | 647 |