Mercurial > hg > svcore
comparison transform/FeatureExtractionPluginTransform.cpp @ 70:d26c85099215
* Support latest changes to Vamp API (value names for parameters, FFT
alignment, value -> bin terminology change)
author | Chris Cannam |
---|---|
date | Wed, 05 Apr 2006 16:52:30 +0000 |
parents | 57a78e7e4ad3 |
children | 9bbc57e8bf43 |
comparison
equal
deleted
inserted
replaced
69:57a78e7e4ad3 | 70:d26c85099215 |
---|---|
99 } | 99 } |
100 | 100 |
101 std::cerr << "FeatureExtractionPluginTransform: output sample type " | 101 std::cerr << "FeatureExtractionPluginTransform: output sample type " |
102 << m_descriptor->sampleType << std::endl; | 102 << m_descriptor->sampleType << std::endl; |
103 | 103 |
104 int valueCount = 1; | 104 int binCount = 1; |
105 float minValue = 0.0, maxValue = 0.0; | 105 float minValue = 0.0, maxValue = 0.0; |
106 | 106 |
107 if (m_descriptor->hasFixedValueCount) { | 107 if (m_descriptor->hasFixedBinCount) { |
108 valueCount = m_descriptor->valueCount; | 108 binCount = m_descriptor->binCount; |
109 } | 109 } |
110 | 110 |
111 if (valueCount > 0 && m_descriptor->hasKnownExtents) { | 111 if (binCount > 0 && m_descriptor->hasKnownExtents) { |
112 minValue = m_descriptor->minValue; | 112 minValue = m_descriptor->minValue; |
113 maxValue = m_descriptor->maxValue; | 113 maxValue = m_descriptor->maxValue; |
114 } | 114 } |
115 | 115 |
116 size_t modelRate = m_input->getSampleRate(); | 116 size_t modelRate = m_input->getSampleRate(); |
131 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: | 131 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: |
132 modelRate = m_descriptor->sampleRate; | 132 modelRate = m_descriptor->sampleRate; |
133 break; | 133 break; |
134 } | 134 } |
135 | 135 |
136 if (valueCount == 0) { | 136 if (binCount == 0) { |
137 | 137 |
138 m_output = new SparseOneDimensionalModel(modelRate, modelResolution, | 138 m_output = new SparseOneDimensionalModel(modelRate, modelResolution, |
139 false); | 139 false); |
140 | 140 |
141 } else if (valueCount == 1 || | 141 } else if (binCount == 1 || |
142 | 142 |
143 // We don't have a sparse 3D model | 143 // We don't have a sparse 3D model |
144 m_descriptor->sampleType == | 144 m_descriptor->sampleType == |
145 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { | 145 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { |
146 | 146 |
151 m_output = model; | 151 m_output = model; |
152 | 152 |
153 } else { | 153 } else { |
154 | 154 |
155 m_output = new DenseThreeDimensionalModel(modelRate, modelResolution, | 155 m_output = new DenseThreeDimensionalModel(modelRate, modelResolution, |
156 valueCount, false); | 156 binCount, false); |
157 | 157 |
158 if (!m_descriptor->valueNames.empty()) { | 158 if (!m_descriptor->binNames.empty()) { |
159 std::vector<QString> names; | 159 std::vector<QString> names; |
160 for (size_t i = 0; i < m_descriptor->valueNames.size(); ++i) { | 160 for (size_t i = 0; i < m_descriptor->binNames.size(); ++i) { |
161 names.push_back(m_descriptor->valueNames[i].c_str()); | 161 names.push_back(m_descriptor->binNames[i].c_str()); |
162 } | 162 } |
163 (dynamic_cast<DenseThreeDimensionalModel *>(m_output)) | 163 (dynamic_cast<DenseThreeDimensionalModel *>(m_output)) |
164 ->setBinNames(names); | 164 ->setBinNames(names); |
165 } | 165 } |
166 } | 166 } |
231 if (!fftPlan) { | 231 if (!fftPlan) { |
232 std::cerr << "ERROR: FeatureExtractionPluginTransform::run(): fftw_plan failed! Results will be garbage" << std::endl; | 232 std::cerr << "ERROR: FeatureExtractionPluginTransform::run(): fftw_plan failed! Results will be garbage" << std::endl; |
233 } | 233 } |
234 } | 234 } |
235 | 235 |
236 size_t startFrame = m_input->getStartFrame(); | 236 long startFrame = m_input->getStartFrame(); |
237 size_t endFrame = m_input->getEndFrame(); | 237 long endFrame = m_input->getEndFrame(); |
238 size_t blockFrame = startFrame; | 238 long blockFrame = startFrame; |
239 | 239 |
240 size_t prevCompletion = 0; | 240 long prevCompletion = 0; |
241 | 241 |
242 while (blockFrame < endFrame) { | 242 while (1) { |
243 | |
244 if (fftPlan) { | |
245 if (blockFrame - m_blockSize/2 > endFrame) break; | |
246 } else { | |
247 if (blockFrame >= endFrame) break; | |
248 } | |
243 | 249 |
244 // std::cerr << "FeatureExtractionPluginTransform::run: blockFrame " | 250 // std::cerr << "FeatureExtractionPluginTransform::run: blockFrame " |
245 // << blockFrame << std::endl; | 251 // << blockFrame << std::endl; |
246 | 252 |
247 size_t completion = | 253 long completion = |
248 (((blockFrame - startFrame) / m_stepSize) * 99) / | 254 (((blockFrame - startFrame) / m_stepSize) * 99) / |
249 ( (endFrame - startFrame) / m_stepSize); | 255 ( (endFrame - startFrame) / m_stepSize); |
250 | 256 |
251 // channelCount is either m_input->channelCount or 1 | 257 // channelCount is either m_input->channelCount or 1 |
252 | 258 |
253 size_t got = 0; | 259 for (int ch = 0; ch < channelCount; ++ch) { |
254 | 260 if (fftPlan) { |
255 if (channelCount == 1) { | 261 getFrames(ch, channelCount, |
256 got = input->getValues | 262 blockFrame - m_blockSize/2, m_blockSize, buffers[ch]); |
257 (m_channel, blockFrame, blockFrame + m_blockSize, buffers[0]); | 263 } else { |
258 while (got < m_blockSize) { | 264 getFrames(ch, channelCount, |
259 buffers[0][got++] = 0.0; | 265 blockFrame, m_blockSize, buffers[ch]); |
260 } | 266 } |
261 } else { | 267 } |
262 for (size_t ch = 0; ch < channelCount; ++ch) { | 268 |
263 got = input->getValues | |
264 (ch, blockFrame, blockFrame + m_blockSize, buffers[ch]); | |
265 while (got < m_blockSize) { | |
266 buffers[ch][got++] = 0.0; | |
267 } | |
268 } | |
269 } | |
270 | |
271 if (fftPlan) { | 269 if (fftPlan) { |
272 for (size_t ch = 0; ch < channelCount; ++ch) { | 270 for (int ch = 0; ch < channelCount; ++ch) { |
273 for (size_t i = 0; i < m_blockSize; ++i) { | 271 for (int i = 0; i < m_blockSize; ++i) { |
274 fftInput[i] = buffers[ch][i]; | 272 fftInput[i] = buffers[ch][i]; |
275 } | 273 } |
276 windower.cut(fftInput); | 274 windower.cut(fftInput); |
277 for (size_t i = 0; i < m_blockSize/2; ++i) { | 275 for (int i = 0; i < m_blockSize/2; ++i) { |
278 double temp = fftInput[i]; | 276 double temp = fftInput[i]; |
279 fftInput[i] = fftInput[i + m_blockSize/2]; | 277 fftInput[i] = fftInput[i + m_blockSize/2]; |
280 fftInput[i + m_blockSize/2] = temp; | 278 fftInput[i + m_blockSize/2] = temp; |
281 } | 279 } |
282 fftw_execute(fftPlan); | 280 fftw_execute(fftPlan); |
283 for (size_t i = 0; i < m_blockSize/2; ++i) { | 281 for (int i = 0; i < m_blockSize/2; ++i) { |
284 buffers[ch][i*2] = fftOutput[i][0]; | 282 buffers[ch][i*2] = fftOutput[i][0]; |
285 buffers[ch][i*2 + 1] = fftOutput[i][1]; | 283 buffers[ch][i*2 + 1] = fftOutput[i][1]; |
286 } | 284 } |
287 } | 285 } |
288 } | 286 } |
319 } | 317 } |
320 | 318 |
321 setCompletion(100); | 319 setCompletion(100); |
322 } | 320 } |
323 | 321 |
322 void | |
323 FeatureExtractionPluginTransform::getFrames(int channel, int channelCount, | |
324 long startFrame, long size, | |
325 float *buffer) | |
326 { | |
327 long offset = 0; | |
328 | |
329 if (startFrame < 0) { | |
330 for (int i = 0; i < size && startFrame + i < 0; ++i) { | |
331 buffer[i] = 0.0f; | |
332 } | |
333 offset = -startFrame; | |
334 size -= offset; | |
335 if (size <= 0) return; | |
336 startFrame = 0; | |
337 } | |
338 | |
339 size_t got = getInput()->getValues | |
340 ((channelCount == 1 ? m_channel : channel), | |
341 startFrame, startFrame + size, buffer + offset); | |
342 | |
343 while (got < size) { | |
344 buffer[offset + got] = 0.0; | |
345 ++got; | |
346 } | |
347 } | |
324 | 348 |
325 void | 349 void |
326 FeatureExtractionPluginTransform::addFeature(size_t blockFrame, | 350 FeatureExtractionPluginTransform::addFeature(size_t blockFrame, |
327 const Vamp::Plugin::Feature &feature) | 351 const Vamp::Plugin::Feature &feature) |
328 { | 352 { |
329 size_t inputRate = m_input->getSampleRate(); | 353 size_t inputRate = m_input->getSampleRate(); |
330 | 354 |
331 // std::cerr << "FeatureExtractionPluginTransform::addFeature(" | 355 // std::cerr << "FeatureExtractionPluginTransform::addFeature(" |
332 // << blockFrame << ")" << std::endl; | 356 // << blockFrame << ")" << std::endl; |
333 | 357 |
334 int valueCount = 1; | 358 int binCount = 1; |
335 if (m_descriptor->hasFixedValueCount) { | 359 if (m_descriptor->hasFixedBinCount) { |
336 valueCount = m_descriptor->valueCount; | 360 binCount = m_descriptor->binCount; |
337 } | 361 } |
338 | 362 |
339 size_t frame = blockFrame; | 363 size_t frame = blockFrame; |
340 | 364 |
341 if (m_descriptor->sampleType == | 365 if (m_descriptor->sampleType == |
361 } else { | 385 } else { |
362 frame = m_output->getEndFrame() + 1; | 386 frame = m_output->getEndFrame() + 1; |
363 } | 387 } |
364 } | 388 } |
365 | 389 |
366 if (valueCount == 0) { | 390 if (binCount == 0) { |
367 | 391 |
368 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); | 392 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); |
369 if (!model) return; | 393 if (!model) return; |
370 model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str())); | 394 model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str())); |
371 | 395 |
372 } else if (valueCount == 1 || | 396 } else if (binCount == 1 || |
373 m_descriptor->sampleType == | 397 m_descriptor->sampleType == |
374 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { | 398 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { |
375 | 399 |
376 float value = 0.0; | 400 float value = 0.0; |
377 if (feature.values.size() > 0) value = feature.values[0]; | 401 if (feature.values.size() > 0) value = feature.values[0]; |
392 } | 416 } |
393 | 417 |
394 void | 418 void |
395 FeatureExtractionPluginTransform::setCompletion(int completion) | 419 FeatureExtractionPluginTransform::setCompletion(int completion) |
396 { | 420 { |
397 int valueCount = 1; | 421 int binCount = 1; |
398 if (m_descriptor->hasFixedValueCount) { | 422 if (m_descriptor->hasFixedBinCount) { |
399 valueCount = m_descriptor->valueCount; | 423 binCount = m_descriptor->binCount; |
400 } | 424 } |
401 | 425 |
402 if (valueCount == 0) { | 426 if (binCount == 0) { |
403 | 427 |
404 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); | 428 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); |
405 if (!model) return; | 429 if (!model) return; |
406 model->setCompletion(completion); | 430 model->setCompletion(completion); |
407 | 431 |
408 } else if (valueCount == 1 || | 432 } else if (binCount == 1 || |
409 m_descriptor->sampleType == | 433 m_descriptor->sampleType == |
410 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { | 434 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { |
411 | 435 |
412 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); | 436 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); |
413 if (!model) return; | 437 if (!model) return; |