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;