annotate VampTestPlugin.cpp @ 26:89e7c9a834d3

Update arch flags
author Chris Cannam
date Mon, 15 Jun 2015 17:22:56 +0100
parents 867364fe9bf6
children c5c40824800a
rev   line source
Chris@0 1
Chris@0 2
Chris@0 3 #include "VampTestPlugin.h"
Chris@0 4
Chris@22 5 #include <vamp-sdk/FFT.h>
Chris@22 6
Chris@19 7 #include <iostream>
Chris@3 8 #include <sstream>
Chris@18 9 #include <cmath>
Chris@3 10
Chris@19 11 using namespace std;
Chris@3 12
Chris@3 13 using Vamp::RealTime;
Chris@0 14
Chris@20 15 VampTestPlugin::VampTestPlugin(float inputSampleRate, bool freq) :
Chris@3 16 Plugin(inputSampleRate),
Chris@20 17 m_frequencyDomain(freq),
Chris@17 18 m_produceOutput(true),
Chris@3 19 m_n(0),
Chris@18 20 m_channels(1),
Chris@3 21 m_stepSize(0),
Chris@3 22 m_blockSize(0)
Chris@0 23 {
Chris@3 24 for (int i = 0; i < 10; ++i) {
Chris@3 25 m_instants.push_back(RealTime::fromSeconds(1.5 * i));
Chris@3 26 }
Chris@0 27 }
Chris@0 28
Chris@0 29 VampTestPlugin::~VampTestPlugin()
Chris@0 30 {
Chris@0 31 }
Chris@0 32
Chris@0 33 string
Chris@0 34 VampTestPlugin::getIdentifier() const
Chris@0 35 {
Chris@20 36 if (m_frequencyDomain) {
Chris@20 37 return "vamp-test-plugin-freq";
Chris@20 38 } else {
Chris@20 39 return "vamp-test-plugin";
Chris@20 40 }
Chris@0 41 }
Chris@0 42
Chris@0 43 string
Chris@0 44 VampTestPlugin::getName() const
Chris@0 45 {
Chris@20 46 if (m_frequencyDomain) {
Chris@20 47 return "Vamp Test Plugin (Frequency-Domain Input)";
Chris@20 48 } else {
Chris@20 49 return "Vamp Test Plugin";
Chris@20 50 }
Chris@0 51 }
Chris@0 52
Chris@0 53 string
Chris@0 54 VampTestPlugin::getDescription() const
Chris@0 55 {
Chris@0 56 return "Test plugin for hosts handling various output types";
Chris@0 57 }
Chris@0 58
Chris@0 59 string
Chris@0 60 VampTestPlugin::getMaker() const
Chris@0 61 {
Chris@0 62 return "Chris Cannam";
Chris@0 63 }
Chris@0 64
Chris@0 65 int
Chris@0 66 VampTestPlugin::getPluginVersion() const
Chris@0 67 {
Chris@20 68 return 3;
Chris@0 69 }
Chris@0 70
Chris@0 71 string
Chris@0 72 VampTestPlugin::getCopyright() const
Chris@0 73 {
Chris@0 74 return "BSD";
Chris@0 75 }
Chris@0 76
Chris@0 77 VampTestPlugin::InputDomain
Chris@0 78 VampTestPlugin::getInputDomain() const
Chris@0 79 {
Chris@20 80 return m_frequencyDomain ? FrequencyDomain : TimeDomain;
Chris@0 81 }
Chris@0 82
Chris@0 83 size_t
Chris@0 84 VampTestPlugin::getPreferredBlockSize() const
Chris@0 85 {
Chris@0 86 return 0;
Chris@0 87 }
Chris@0 88
Chris@0 89 size_t
Chris@0 90 VampTestPlugin::getPreferredStepSize() const
Chris@0 91 {
Chris@0 92 return 0;
Chris@0 93 }
Chris@0 94
Chris@0 95 size_t
Chris@0 96 VampTestPlugin::getMinChannelCount() const
Chris@0 97 {
Chris@0 98 return 1;
Chris@0 99 }
Chris@0 100
Chris@0 101 size_t
Chris@0 102 VampTestPlugin::getMaxChannelCount() const
Chris@0 103 {
Chris@18 104 return 10;
Chris@0 105 }
Chris@0 106
Chris@0 107 VampTestPlugin::ParameterList
Chris@0 108 VampTestPlugin::getParameterDescriptors() const
Chris@0 109 {
Chris@0 110 ParameterList list;
Chris@17 111
Chris@17 112 // Provide one parameter, and make it so that we can easily tell
Chris@17 113 // whether it has been changed
Chris@17 114 ParameterDescriptor d;
Chris@17 115 d.identifier = "produce_output";
Chris@17 116 d.name = "Produce some output";
Chris@17 117 d.description = "Whether to produce any output. If this parameter is switched off, the plugin will produce no output. This is intended for basic testing of whether a host's parameter setting logic is functioning.";
Chris@17 118 d.unit = "";
Chris@17 119 d.minValue = 0;
Chris@17 120 d.maxValue = 1;
Chris@17 121 d.defaultValue = 1;
Chris@17 122 d.isQuantized = true;
Chris@17 123 d.quantizeStep = 1;
Chris@17 124 list.push_back(d);
Chris@17 125
Chris@0 126 return list;
Chris@0 127 }
Chris@0 128
Chris@0 129 float
Chris@0 130 VampTestPlugin::getParameter(string identifier) const
Chris@0 131 {
Chris@17 132 if (identifier == "produce_output") {
Chris@17 133 return m_produceOutput ? 1.f : 0.f;
Chris@17 134 }
Chris@0 135 return 0;
Chris@0 136 }
Chris@0 137
Chris@0 138 void
Chris@0 139 VampTestPlugin::setParameter(string identifier, float value)
Chris@0 140 {
Chris@17 141 if (identifier == "produce_output") {
Chris@17 142 m_produceOutput = (value > 0.5);
Chris@17 143 }
Chris@0 144 }
Chris@0 145
Chris@0 146 VampTestPlugin::ProgramList
Chris@0 147 VampTestPlugin::getPrograms() const
Chris@0 148 {
Chris@0 149 ProgramList list;
Chris@0 150 return list;
Chris@0 151 }
Chris@0 152
Chris@0 153 string
Chris@0 154 VampTestPlugin::getCurrentProgram() const
Chris@0 155 {
Chris@0 156 return ""; // no programs
Chris@0 157 }
Chris@0 158
Chris@0 159 void
Chris@23 160 VampTestPlugin::selectProgram(string)
Chris@0 161 {
Chris@0 162 }
Chris@0 163
Chris@0 164 VampTestPlugin::OutputList
Chris@0 165 VampTestPlugin::getOutputDescriptors() const
Chris@0 166 {
Chris@0 167 OutputList list;
Chris@0 168
Chris@7 169 int n = 0;
Chris@7 170
Chris@0 171 OutputDescriptor d;
Chris@1 172
Chris@1 173 d.identifier = "instants";
Chris@1 174 d.name = "Instants";
Chris@2 175 d.description = "Single time points without values";
Chris@1 176 d.unit = "";
Chris@1 177 d.hasFixedBinCount = true;
Chris@1 178 d.binCount = 0;
Chris@1 179 d.hasKnownExtents = false;
Chris@1 180 d.isQuantized = false;
Chris@1 181 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@1 182 d.hasDuration = false;
Chris@7 183 m_outputNumbers[d.identifier] = n++;
Chris@1 184 list.push_back(d);
Chris@1 185
Chris@1 186 d.identifier = "curve-oss";
Chris@1 187 d.name = "Curve: OneSamplePerStep";
Chris@2 188 d.description = "A time series with one value per process block";
Chris@0 189 d.unit = "";
Chris@0 190 d.hasFixedBinCount = true;
Chris@0 191 d.binCount = 1;
Chris@0 192 d.hasKnownExtents = false;
Chris@0 193 d.isQuantized = false;
Chris@0 194 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@0 195 d.hasDuration = false;
Chris@7 196 m_outputNumbers[d.identifier] = n++;
Chris@0 197 list.push_back(d);
Chris@0 198
Chris@1 199 d.identifier = "curve-fsr";
Chris@1 200 d.name = "Curve: FixedSampleRate";
Chris@2 201 d.description = "A time series with equally-spaced values (independent of process step size)";
Chris@1 202 d.unit = "";
Chris@1 203 d.hasFixedBinCount = true;
Chris@1 204 d.binCount = 1;
Chris@1 205 d.hasKnownExtents = false;
Chris@1 206 d.isQuantized = false;
Chris@1 207 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 208 d.sampleRate = 2.5;
Chris@1 209 d.hasDuration = false;
Chris@7 210 m_outputNumbers[d.identifier] = n++;
Chris@1 211 list.push_back(d);
Chris@1 212
Chris@7 213 d.identifier = "curve-fsr-timed";
Chris@7 214 d.name = "Curve: FixedSampleRate/Timed";
Chris@7 215 d.description = "A time series with a fixed sample rate (independent of process step size) but with timestamps on features";
Chris@7 216 d.unit = "";
Chris@7 217 d.hasFixedBinCount = true;
Chris@7 218 d.binCount = 1;
Chris@7 219 d.hasKnownExtents = false;
Chris@7 220 d.isQuantized = false;
Chris@7 221 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 222 d.sampleRate = 2.5;
Chris@7 223 d.hasDuration = false;
Chris@7 224 m_outputNumbers[d.identifier] = n++;
Chris@7 225 list.push_back(d);
Chris@7 226
Chris@1 227 d.identifier = "curve-vsr";
Chris@1 228 d.name = "Curve: VariableSampleRate";
Chris@2 229 d.description = "A variably-spaced series of values";
Chris@1 230 d.unit = "";
Chris@1 231 d.hasFixedBinCount = true;
Chris@1 232 d.binCount = 1;
Chris@1 233 d.hasKnownExtents = false;
Chris@1 234 d.isQuantized = false;
Chris@1 235 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@2 236 d.sampleRate = 0;
Chris@1 237 d.hasDuration = false;
Chris@7 238 m_outputNumbers[d.identifier] = n++;
Chris@1 239 list.push_back(d);
Chris@1 240
Chris@2 241 d.identifier = "grid-oss";
Chris@2 242 d.name = "Grid: OneSamplePerStep";
Chris@2 243 d.description = "A fixed-height grid of values with one column per process block";
Chris@2 244 d.unit = "";
Chris@2 245 d.hasFixedBinCount = true;
Chris@4 246 d.binCount = 10;
Chris@2 247 d.hasKnownExtents = false;
Chris@2 248 d.isQuantized = false;
Chris@4 249 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@2 250 d.sampleRate = 0;
Chris@2 251 d.hasDuration = false;
Chris@7 252 m_outputNumbers[d.identifier] = n++;
Chris@2 253 list.push_back(d);
Chris@2 254
Chris@2 255 d.identifier = "grid-fsr";
Chris@2 256 d.name = "Grid: FixedSampleRate";
Chris@2 257 d.description = "A fixed-height grid of values with equally-spaced columns (independent of process step size)";
Chris@2 258 d.unit = "";
Chris@2 259 d.hasFixedBinCount = true;
Chris@4 260 d.binCount = 10;
Chris@2 261 d.hasKnownExtents = false;
Chris@2 262 d.isQuantized = false;
Chris@4 263 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 264 d.sampleRate = 2.5;
Chris@2 265 d.hasDuration = false;
Chris@7 266 m_outputNumbers[d.identifier] = n++;
Chris@2 267 list.push_back(d);
Chris@2 268
Chris@5 269 d.identifier = "notes-regions";
Chris@5 270 d.name = "Notes or Regions";
Chris@5 271 d.description = "Variably-spaced features with one value and duration";
Chris@5 272 d.unit = "";
Chris@5 273 d.hasFixedBinCount = true;
Chris@5 274 d.binCount = 1;
Chris@5 275 d.hasKnownExtents = false;
Chris@5 276 d.isQuantized = false;
Chris@5 277 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@5 278 d.sampleRate = 0;
Chris@5 279 d.hasDuration = true;
Chris@7 280 m_outputNumbers[d.identifier] = n++;
Chris@5 281 list.push_back(d);
Chris@2 282
Chris@19 283 d.identifier = "input-summary";
Chris@19 284 d.name = "Data derived from inputs";
Chris@22 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.)";
Chris@18 286 d.unit = "";
Chris@18 287 d.hasFixedBinCount = true;
Chris@18 288 d.binCount = m_channels;
Chris@18 289 d.hasKnownExtents = false;
Chris@18 290 d.isQuantized = false;
Chris@18 291 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@18 292 d.hasDuration = false;
Chris@18 293 m_outputNumbers[d.identifier] = n++;
Chris@18 294 list.push_back(d);
Chris@18 295
Chris@20 296 d.identifier = "input-timestamp";
Chris@20 297 d.name = "Input timestamp";
Chris@21 298 d.description = "One-sample-per-step features with one value, containing the time in sample frames converted from the timestamp of the corresponding process input block.";
Chris@21 299 d.unit = "samples";
Chris@20 300 d.hasFixedBinCount = true;
Chris@20 301 d.binCount = 1;
Chris@20 302 d.hasKnownExtents = false;
Chris@20 303 d.isQuantized = false;
Chris@20 304 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@20 305 d.hasDuration = false;
Chris@20 306 m_outputNumbers[d.identifier] = n++;
Chris@20 307 list.push_back(d);
Chris@20 308
Chris@0 309 return list;
Chris@0 310 }
Chris@0 311
Chris@0 312 bool
Chris@0 313 VampTestPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize)
Chris@0 314 {
Chris@0 315 if (channels < getMinChannelCount() ||
Chris@0 316 channels > getMaxChannelCount()) return false;
Chris@0 317
Chris@18 318 m_channels = channels;
Chris@3 319 m_stepSize = stepSize;
Chris@3 320 m_blockSize = blockSize;
Chris@0 321
Chris@0 322 return true;
Chris@0 323 }
Chris@0 324
Chris@0 325 void
Chris@0 326 VampTestPlugin::reset()
Chris@0 327 {
Chris@3 328 m_n = 0;
Chris@3 329 }
Chris@3 330
Chris@3 331 static Vamp::Plugin::Feature
Chris@3 332 instant(RealTime r, int i, int n)
Chris@3 333 {
Chris@19 334 stringstream s;
Chris@3 335 Vamp::Plugin::Feature f;
Chris@3 336 f.hasTimestamp = true;
Chris@3 337 f.timestamp = r;
Chris@3 338 f.hasDuration = false;
Chris@3 339 s << i+1 << " of " << n << " at " << r.toText();
Chris@3 340 f.label = s.str();
Chris@3 341 return f;
Chris@3 342 }
Chris@3 343
Chris@3 344 static Vamp::Plugin::Feature
Chris@3 345 untimedCurveValue(RealTime r, int i, int n)
Chris@3 346 {
Chris@19 347 stringstream s;
Chris@3 348 Vamp::Plugin::Feature f;
Chris@3 349 f.hasTimestamp = false;
Chris@3 350 f.hasDuration = false;
Chris@3 351 float v = float(i) / float(n);
Chris@3 352 f.values.push_back(v);
Chris@3 353 s << i+1 << " of " << n << ": " << v << " at " << r.toText();
Chris@3 354 f.label = s.str();
Chris@3 355 return f;
Chris@0 356 }
Chris@0 357
Chris@4 358 static Vamp::Plugin::Feature
Chris@4 359 timedCurveValue(RealTime r, int i, int n)
Chris@4 360 {
Chris@19 361 stringstream s;
Chris@4 362 Vamp::Plugin::Feature f;
Chris@4 363 f.hasTimestamp = true;
Chris@4 364 f.timestamp = r;
Chris@4 365 f.hasDuration = false;
Chris@4 366 float v = float(i) / float(n);
Chris@4 367 f.values.push_back(v);
Chris@4 368 s << i+1 << " of " << n << ": " << v << " at " << r.toText();
Chris@4 369 f.label = s.str();
Chris@4 370 return f;
Chris@4 371 }
Chris@4 372
Chris@4 373 static Vamp::Plugin::Feature
Chris@7 374 snappedCurveValue(RealTime r, RealTime sn, int i, int n)
Chris@7 375 {
Chris@19 376 stringstream s;
Chris@7 377 Vamp::Plugin::Feature f;
Chris@7 378 f.hasTimestamp = true;
Chris@7 379 f.timestamp = r;
Chris@7 380 f.hasDuration = false;
Chris@7 381 float v = float(i) / float(n);
Chris@7 382 f.values.push_back(v);
Chris@7 383 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " snap to " << sn.toText();
Chris@7 384 f.label = s.str();
Chris@7 385 return f;
Chris@7 386 }
Chris@7 387
Chris@7 388 static Vamp::Plugin::Feature
Chris@4 389 gridColumn(RealTime r, int i, int n)
Chris@4 390 {
Chris@19 391 stringstream s;
Chris@4 392 Vamp::Plugin::Feature f;
Chris@4 393 f.hasTimestamp = false;
Chris@4 394 f.hasDuration = false;
Chris@4 395 for (int j = 0; j < 10; ++j) {
Chris@4 396 float v = float(j + i + 2) / float(n + 10);
Chris@4 397 f.values.push_back(v);
Chris@4 398 }
Chris@4 399 s << i+1 << " of " << n << " at " << r.toText();
Chris@4 400 f.label = s.str();
Chris@4 401 return f;
Chris@4 402 }
Chris@4 403
Chris@5 404 static Vamp::Plugin::Feature
Chris@5 405 noteOrRegion(RealTime r, RealTime d, int i, int n)
Chris@5 406 {
Chris@19 407 stringstream s;
Chris@5 408 Vamp::Plugin::Feature f;
Chris@5 409 f.hasTimestamp = true;
Chris@5 410 f.timestamp = r;
Chris@5 411 f.hasDuration = true;
Chris@5 412 f.duration = d;
Chris@5 413 float v = float(i) / float(n);
Chris@5 414 f.values.push_back(v);
Chris@5 415 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " dur. " << d.toText();
Chris@5 416 f.label = s.str();
Chris@5 417 return f;
Chris@5 418 }
Chris@5 419
Chris@7 420 static
Chris@7 421 float snap(float x, float r)
Chris@7 422 {
Chris@7 423 int n = int(x / r + 0.5);
Chris@7 424 return n * r;
Chris@7 425 }
Chris@7 426
Chris@5 427 Vamp::Plugin::FeatureSet
Chris@5 428 VampTestPlugin::featuresFrom(RealTime timestamp, bool final)
Chris@0 429 {
Chris@3 430 FeatureSet fs;
Chris@3 431
Chris@3 432 RealTime endTime = timestamp + RealTime::frame2RealTime
Chris@3 433 (m_stepSize, m_inputSampleRate);
Chris@3 434
Chris@3 435 for (int i = 0; i < (int)m_instants.size(); ++i) {
Chris@5 436
Chris@5 437 if (m_instants[i] >= timestamp && (final || m_instants[i] < endTime)) {
Chris@7 438 fs[m_outputNumbers["instants"]]
Chris@7 439 .push_back(instant(m_instants[i], i, m_instants.size()));
Chris@3 440 }
Chris@4 441
Chris@4 442 RealTime variCurveTime = m_instants[i] / 2;
Chris@5 443 if (variCurveTime >= timestamp && (final || variCurveTime < endTime)) {
Chris@7 444 fs[m_outputNumbers["curve-vsr"]]
Chris@7 445 .push_back(timedCurveValue(variCurveTime, i, m_instants.size()));
Chris@4 446 }
Chris@5 447
Chris@5 448 RealTime noteTime = (m_instants[i] + m_instants[i]) / 3;
Chris@5 449 RealTime noteDuration = RealTime::fromSeconds((i % 2 == 0) ? 1.75 : 0.5);
Chris@5 450
Chris@5 451 if (noteTime >= timestamp && (final || noteTime < endTime)) {
Chris@7 452 fs[m_outputNumbers["notes-regions"]]
Chris@7 453 .push_back(noteOrRegion(noteTime, noteDuration, i, m_instants.size()));
Chris@5 454 }
Chris@3 455 }
Chris@3 456
Chris@5 457 if (!final) {
Chris@3 458
Chris@5 459 if (m_n < 20) {
Chris@7 460 fs[m_outputNumbers["curve-oss"]]
Chris@7 461 .push_back(untimedCurveValue(timestamp, m_n, 20));
Chris@5 462 }
Chris@3 463
Chris@5 464 if (m_n < 5) {
Chris@7 465 fs[m_outputNumbers["curve-fsr"]]
Chris@8 466 .push_back(untimedCurveValue(RealTime::fromSeconds(m_n / 2.5), m_n, 10));
Chris@6 467
Chris@7 468 float s = (m_n / 4) * 2;
Chris@7 469 if ((m_n % 4) > 0) {
Chris@7 470 s += float((m_n % 4) - 1) / 6.0;
Chris@7 471 }
Chris@7 472 fs[m_outputNumbers["curve-fsr-timed"]]
Chris@7 473 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@8 474 RealTime::fromSeconds(snap(s, 0.4)),
Chris@7 475 m_n, 10));
Chris@5 476 }
Chris@5 477
Chris@5 478 if (m_n < 20) {
Chris@7 479 fs[m_outputNumbers["grid-oss"]]
Chris@7 480 .push_back(gridColumn(timestamp, m_n, 20));
Chris@5 481 }
Chris@5 482
Chris@5 483 } else {
Chris@5 484
Chris@5 485 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) {
Chris@7 486 fs[m_outputNumbers["curve-fsr"]]
Chris@8 487 .push_back(untimedCurveValue(RealTime::fromSeconds(i / 2.5), i, 10));
Chris@7 488
Chris@7 489 float s = (i / 4) * 2;
Chris@7 490 if ((i % 4) > 0) {
Chris@7 491 s += float((i % 4) - 1) / 6.0;
Chris@7 492 }
Chris@7 493 fs[m_outputNumbers["curve-fsr-timed"]]
Chris@7 494 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@8 495 RealTime::fromSeconds(snap(s, 0.4)),
Chris@7 496 i, 10));
Chris@5 497 }
Chris@5 498
Chris@8 499 for (int i = 0; i < 10; ++i) {
Chris@7 500 fs[m_outputNumbers["grid-fsr"]]
Chris@9 501 .push_back(gridColumn(RealTime::fromSeconds(i / 2.5), i, 10));
Chris@5 502 }
Chris@4 503 }
Chris@4 504
Chris@3 505 m_lastTime = endTime;
Chris@3 506 m_n = m_n + 1;
Chris@3 507 return fs;
Chris@5 508 }
Chris@5 509
Chris@5 510 VampTestPlugin::FeatureSet
Chris@5 511 VampTestPlugin::process(const float *const *inputBuffers, RealTime timestamp)
Chris@5 512 {
Chris@17 513 if (!m_produceOutput) return FeatureSet();
Chris@5 514 FeatureSet fs = featuresFrom(timestamp, false);
Chris@22 515
Chris@22 516 Feature f;
Chris@22 517 float eps = 1e-6f;
Chris@18 518
Chris@18 519 for (int c = 0; c < m_channels; ++c) {
Chris@22 520 if (!m_frequencyDomain) {
Chris@22 521 // first value plus number of non-zero values
Chris@22 522 float sum = inputBuffers[c][0];
Chris@22 523 for (int i = 0; i < m_blockSize; ++i) {
Chris@22 524 if (fabsf(inputBuffers[c][i]) >= eps) sum += 1;
Chris@22 525 }
Chris@22 526 f.values.push_back(sum);
Chris@22 527 } else {
Chris@22 528 // If we're in frequency-domain mode, we convert back to
Chris@22 529 // time-domain to calculate the input-summary feature
Chris@22 530 // output. That should help the caller check that
Chris@22 531 // time-frequency conversion has gone more or less OK,
Chris@22 532 // though they'll still have to bear in mind windowing and
Chris@22 533 // FFT shift (i.e. phase shift which puts the first
Chris@22 534 // element in the middle of the frame)
Chris@22 535 vector<double> ri(m_blockSize, 0.0);
Chris@22 536 vector<double> ii(m_blockSize, 0.0);
Chris@22 537 vector<double> ro(m_blockSize, 0.0);
Chris@22 538 vector<double> io(m_blockSize, 0.0);
Chris@22 539 for (int i = 0; i <= m_blockSize/2; ++i) {
Chris@22 540 ri[i] = inputBuffers[c][i*2];
Chris@22 541 ii[i] = inputBuffers[c][i*2 + 1];
Chris@22 542 if (i > 0) ri[m_blockSize-i] = ri[i];
Chris@22 543 if (i > 0) ii[m_blockSize-i] = -ii[i];
Chris@22 544 }
Chris@22 545 Vamp::FFT::inverse(m_blockSize, &ri[0], &ii[0], &ro[0], &io[0]);
Chris@22 546 float sum = 0;
Chris@22 547 for (int i = 0; i < m_blockSize; ++i) {
Chris@24 548 if (fabs(ro[i]) >= eps) sum += 1;
Chris@22 549 }
Chris@22 550 sum += ro[0];
Chris@22 551 f.values.push_back(sum);
Chris@22 552 }
Chris@18 553 }
Chris@22 554
Chris@19 555 fs[m_outputNumbers["input-summary"]].push_back(f);
Chris@20 556
Chris@20 557 f.values.clear();
Chris@22 558 float frame = RealTime::realTime2Frame(timestamp, m_inputSampleRate);
Chris@22 559 f.values.push_back(frame);
Chris@20 560 fs[m_outputNumbers["input-timestamp"]].push_back(f);
Chris@18 561
Chris@5 562 return fs;
Chris@0 563 }
Chris@0 564
Chris@0 565 VampTestPlugin::FeatureSet
Chris@0 566 VampTestPlugin::getRemainingFeatures()
Chris@0 567 {
Chris@17 568 if (!m_produceOutput) return FeatureSet();
Chris@5 569 FeatureSet fs = featuresFrom(m_lastTime, true);
Chris@3 570 return fs;
Chris@0 571 }
Chris@0 572