Mercurial > hg > vamp-test-plugin
comparison VampTestPlugin.cpp @ 22:d7f18dca3f48
Convert freq back to time domain for the input summary output
author | Chris Cannam |
---|---|
date | Wed, 14 Jan 2015 17:33:52 +0000 |
parents | 8984ab4a0213 |
children | 42e71acaba8e |
comparison
equal
deleted
inserted
replaced
21:8984ab4a0213 | 22:d7f18dca3f48 |
---|---|
1 | 1 |
2 | 2 |
3 #include "VampTestPlugin.h" | 3 #include "VampTestPlugin.h" |
4 | |
5 #include <vamp-sdk/FFT.h> | |
4 | 6 |
5 #include <iostream> | 7 #include <iostream> |
6 #include <sstream> | 8 #include <sstream> |
7 #include <cmath> | 9 #include <cmath> |
8 | 10 |
278 m_outputNumbers[d.identifier] = n++; | 280 m_outputNumbers[d.identifier] = n++; |
279 list.push_back(d); | 281 list.push_back(d); |
280 | 282 |
281 d.identifier = "input-summary"; | 283 d.identifier = "input-summary"; |
282 d.name = "Data derived from inputs"; | 284 d.name = "Data derived from inputs"; |
283 d.description = "One-sample-per-step features with n values, where n is the number of input channels. Each feature contains, for each input channel, the first sample value on that channel plus the total number of non-zero samples on that channel"; | 285 d.description = "One-sample-per-step features with n values, where n is the number of input channels. Each feature contains, for each input channel, the first sample value on that channel plus the total number of non-zero samples on that channel. (\"Non-zero\" is determined by comparison against a magnitude threshold which is actually 1e-6 rather than exactly zero.)"; |
284 d.unit = ""; | 286 d.unit = ""; |
285 d.hasFixedBinCount = true; | 287 d.hasFixedBinCount = true; |
286 d.binCount = m_channels; | 288 d.binCount = m_channels; |
287 d.hasKnownExtents = false; | 289 d.hasKnownExtents = false; |
288 d.isQuantized = false; | 290 d.isQuantized = false; |
508 VampTestPlugin::FeatureSet | 510 VampTestPlugin::FeatureSet |
509 VampTestPlugin::process(const float *const *inputBuffers, RealTime timestamp) | 511 VampTestPlugin::process(const float *const *inputBuffers, RealTime timestamp) |
510 { | 512 { |
511 if (!m_produceOutput) return FeatureSet(); | 513 if (!m_produceOutput) return FeatureSet(); |
512 FeatureSet fs = featuresFrom(timestamp, false); | 514 FeatureSet fs = featuresFrom(timestamp, false); |
513 | 515 |
514 Feature f; | 516 Feature f; |
517 float eps = 1e-6f; | |
518 | |
515 for (int c = 0; c < m_channels; ++c) { | 519 for (int c = 0; c < m_channels; ++c) { |
516 // first value plus number of non-zero values | 520 if (!m_frequencyDomain) { |
517 float sum = inputBuffers[c][0]; | 521 // first value plus number of non-zero values |
518 for (int i = 0; i < m_blockSize; ++i) { | 522 float sum = inputBuffers[c][0]; |
519 if (inputBuffers[c][i] != 0.f) sum += 1; | 523 for (int i = 0; i < m_blockSize; ++i) { |
520 } | 524 if (fabsf(inputBuffers[c][i]) >= eps) sum += 1; |
521 f.values.push_back(sum); | 525 } |
522 } | 526 f.values.push_back(sum); |
527 } else { | |
528 // If we're in frequency-domain mode, we convert back to | |
529 // time-domain to calculate the input-summary feature | |
530 // output. That should help the caller check that | |
531 // time-frequency conversion has gone more or less OK, | |
532 // though they'll still have to bear in mind windowing and | |
533 // FFT shift (i.e. phase shift which puts the first | |
534 // element in the middle of the frame) | |
535 vector<double> ri(m_blockSize, 0.0); | |
536 vector<double> ii(m_blockSize, 0.0); | |
537 vector<double> ro(m_blockSize, 0.0); | |
538 vector<double> io(m_blockSize, 0.0); | |
539 for (int i = 0; i <= m_blockSize/2; ++i) { | |
540 ri[i] = inputBuffers[c][i*2]; | |
541 ii[i] = inputBuffers[c][i*2 + 1]; | |
542 if (i > 0) ri[m_blockSize-i] = ri[i]; | |
543 if (i > 0) ii[m_blockSize-i] = -ii[i]; | |
544 } | |
545 Vamp::FFT::inverse(m_blockSize, &ri[0], &ii[0], &ro[0], &io[0]); | |
546 float sum = 0; | |
547 for (int i = 0; i < m_blockSize; ++i) { | |
548 if (fabsf(ro[i]) >= eps) sum += 1; | |
549 } | |
550 sum += ro[0]; | |
551 f.values.push_back(sum); | |
552 } | |
553 } | |
554 | |
523 fs[m_outputNumbers["input-summary"]].push_back(f); | 555 fs[m_outputNumbers["input-summary"]].push_back(f); |
524 | 556 |
525 f.values.clear(); | 557 f.values.clear(); |
526 f.values.push_back(RealTime::realTime2Frame(timestamp, m_inputSampleRate)); | 558 float frame = RealTime::realTime2Frame(timestamp, m_inputSampleRate); |
559 f.values.push_back(frame); | |
527 fs[m_outputNumbers["input-timestamp"]].push_back(f); | 560 fs[m_outputNumbers["input-timestamp"]].push_back(f); |
528 | 561 |
529 return fs; | 562 return fs; |
530 } | 563 } |
531 | 564 |