annotate VampTestPlugin.cpp @ 33:60d48ba79ca1

Slightly different pattern
author Chris Cannam
date Wed, 14 Sep 2016 17:14:32 +0100
parents 4834aa2b49a6
children b35d5b2abf84
rev   line source
Chris@31 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@31 2 /*
Chris@31 3 Vamp Test Plugin
Chris@31 4 Copyright (c) 2013-2016 Queen Mary, University of London
Chris@0 5
Chris@31 6 Permission is hereby granted, free of charge, to any person
Chris@31 7 obtaining a copy of this software and associated documentation
Chris@31 8 files (the "Software"), to deal in the Software without
Chris@31 9 restriction, including without limitation the rights to use, copy,
Chris@31 10 modify, merge, publish, distribute, sublicense, and/or sell copies
Chris@31 11 of the Software, and to permit persons to whom the Software is
Chris@31 12 furnished to do so, subject to the following conditions:
Chris@31 13
Chris@31 14 The above copyright notice and this permission notice shall be
Chris@31 15 included in all copies or substantial portions of the Software.
Chris@31 16
Chris@31 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@31 18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@31 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@31 20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
Chris@31 21 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@31 22 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@31 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@31 24
Chris@31 25 Except as contained in this notice, the names of the Centre for
Chris@31 26 Digital Music and Queen Mary, University of London shall not be
Chris@31 27 used in advertising or otherwise to promote the sale, use or other
Chris@31 28 dealings in this Software without prior written authorization.
Chris@31 29 */
Chris@0 30
Chris@0 31 #include "VampTestPlugin.h"
Chris@0 32
Chris@22 33 #include <vamp-sdk/FFT.h>
Chris@22 34
Chris@19 35 #include <iostream>
Chris@3 36 #include <sstream>
Chris@18 37 #include <cmath>
Chris@3 38
Chris@19 39 using namespace std;
Chris@3 40
Chris@3 41 using Vamp::RealTime;
Chris@0 42
Chris@20 43 VampTestPlugin::VampTestPlugin(float inputSampleRate, bool freq) :
Chris@3 44 Plugin(inputSampleRate),
Chris@20 45 m_frequencyDomain(freq),
Chris@17 46 m_produceOutput(true),
Chris@3 47 m_n(0),
Chris@18 48 m_channels(1),
Chris@3 49 m_stepSize(0),
Chris@3 50 m_blockSize(0)
Chris@0 51 {
Chris@3 52 for (int i = 0; i < 10; ++i) {
Chris@31 53 m_instants.push_back(RealTime::fromSeconds(1.5 * i));
Chris@3 54 }
Chris@0 55 }
Chris@0 56
Chris@0 57 VampTestPlugin::~VampTestPlugin()
Chris@0 58 {
Chris@0 59 }
Chris@0 60
Chris@0 61 string
Chris@0 62 VampTestPlugin::getIdentifier() const
Chris@0 63 {
Chris@20 64 if (m_frequencyDomain) {
Chris@31 65 return "vamp-test-plugin-freq";
Chris@20 66 } else {
Chris@31 67 return "vamp-test-plugin";
Chris@20 68 }
Chris@0 69 }
Chris@0 70
Chris@0 71 string
Chris@0 72 VampTestPlugin::getName() const
Chris@0 73 {
Chris@20 74 if (m_frequencyDomain) {
Chris@31 75 return "Vamp Test Plugin (Frequency-Domain Input)";
Chris@20 76 } else {
Chris@31 77 return "Vamp Test Plugin";
Chris@20 78 }
Chris@0 79 }
Chris@0 80
Chris@0 81 string
Chris@0 82 VampTestPlugin::getDescription() const
Chris@0 83 {
Chris@0 84 return "Test plugin for hosts handling various output types";
Chris@0 85 }
Chris@0 86
Chris@0 87 string
Chris@0 88 VampTestPlugin::getMaker() const
Chris@0 89 {
Chris@0 90 return "Chris Cannam";
Chris@0 91 }
Chris@0 92
Chris@0 93 int
Chris@0 94 VampTestPlugin::getPluginVersion() const
Chris@0 95 {
Chris@20 96 return 3;
Chris@0 97 }
Chris@0 98
Chris@0 99 string
Chris@0 100 VampTestPlugin::getCopyright() const
Chris@0 101 {
Chris@0 102 return "BSD";
Chris@0 103 }
Chris@0 104
Chris@0 105 VampTestPlugin::InputDomain
Chris@0 106 VampTestPlugin::getInputDomain() const
Chris@0 107 {
Chris@20 108 return m_frequencyDomain ? FrequencyDomain : TimeDomain;
Chris@0 109 }
Chris@0 110
Chris@0 111 size_t
Chris@0 112 VampTestPlugin::getPreferredBlockSize() const
Chris@0 113 {
Chris@0 114 return 0;
Chris@0 115 }
Chris@0 116
Chris@0 117 size_t
Chris@0 118 VampTestPlugin::getPreferredStepSize() const
Chris@0 119 {
Chris@0 120 return 0;
Chris@0 121 }
Chris@0 122
Chris@0 123 size_t
Chris@0 124 VampTestPlugin::getMinChannelCount() const
Chris@0 125 {
Chris@0 126 return 1;
Chris@0 127 }
Chris@0 128
Chris@0 129 size_t
Chris@0 130 VampTestPlugin::getMaxChannelCount() const
Chris@0 131 {
Chris@18 132 return 10;
Chris@0 133 }
Chris@0 134
Chris@0 135 VampTestPlugin::ParameterList
Chris@0 136 VampTestPlugin::getParameterDescriptors() const
Chris@0 137 {
Chris@0 138 ParameterList list;
Chris@17 139
Chris@17 140 // Provide one parameter, and make it so that we can easily tell
Chris@17 141 // whether it has been changed
Chris@17 142 ParameterDescriptor d;
Chris@17 143 d.identifier = "produce_output";
Chris@17 144 d.name = "Produce some output";
Chris@17 145 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 146 d.unit = "";
Chris@17 147 d.minValue = 0;
Chris@17 148 d.maxValue = 1;
Chris@17 149 d.defaultValue = 1;
Chris@17 150 d.isQuantized = true;
Chris@17 151 d.quantizeStep = 1;
Chris@17 152 list.push_back(d);
Chris@17 153
Chris@0 154 return list;
Chris@0 155 }
Chris@0 156
Chris@0 157 float
Chris@0 158 VampTestPlugin::getParameter(string identifier) const
Chris@0 159 {
Chris@17 160 if (identifier == "produce_output") {
Chris@31 161 return m_produceOutput ? 1.f : 0.f;
Chris@17 162 }
Chris@0 163 return 0;
Chris@0 164 }
Chris@0 165
Chris@0 166 void
Chris@0 167 VampTestPlugin::setParameter(string identifier, float value)
Chris@0 168 {
Chris@17 169 if (identifier == "produce_output") {
Chris@31 170 m_produceOutput = (value > 0.5);
Chris@17 171 }
Chris@0 172 }
Chris@0 173
Chris@0 174 VampTestPlugin::ProgramList
Chris@0 175 VampTestPlugin::getPrograms() const
Chris@0 176 {
Chris@0 177 ProgramList list;
Chris@0 178 return list;
Chris@0 179 }
Chris@0 180
Chris@0 181 string
Chris@0 182 VampTestPlugin::getCurrentProgram() const
Chris@0 183 {
Chris@0 184 return ""; // no programs
Chris@0 185 }
Chris@0 186
Chris@0 187 void
Chris@23 188 VampTestPlugin::selectProgram(string)
Chris@0 189 {
Chris@0 190 }
Chris@0 191
Chris@0 192 VampTestPlugin::OutputList
Chris@0 193 VampTestPlugin::getOutputDescriptors() const
Chris@0 194 {
Chris@0 195 OutputList list;
Chris@0 196
Chris@7 197 int n = 0;
Chris@7 198
Chris@0 199 OutputDescriptor d;
Chris@1 200
Chris@1 201 d.identifier = "instants";
Chris@1 202 d.name = "Instants";
Chris@2 203 d.description = "Single time points without values";
Chris@1 204 d.unit = "";
Chris@1 205 d.hasFixedBinCount = true;
Chris@1 206 d.binCount = 0;
Chris@1 207 d.hasKnownExtents = false;
Chris@1 208 d.isQuantized = false;
Chris@1 209 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@1 210 d.hasDuration = false;
Chris@7 211 m_outputNumbers[d.identifier] = n++;
Chris@1 212 list.push_back(d);
Chris@1 213
Chris@1 214 d.identifier = "curve-oss";
Chris@1 215 d.name = "Curve: OneSamplePerStep";
Chris@2 216 d.description = "A time series with one value per process block";
Chris@0 217 d.unit = "";
Chris@0 218 d.hasFixedBinCount = true;
Chris@0 219 d.binCount = 1;
Chris@0 220 d.hasKnownExtents = false;
Chris@0 221 d.isQuantized = false;
Chris@0 222 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@0 223 d.hasDuration = false;
Chris@7 224 m_outputNumbers[d.identifier] = n++;
Chris@0 225 list.push_back(d);
Chris@0 226
Chris@1 227 d.identifier = "curve-fsr";
Chris@1 228 d.name = "Curve: FixedSampleRate";
Chris@2 229 d.description = "A time series with equally-spaced values (independent of process step size)";
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::FixedSampleRate;
Chris@8 236 d.sampleRate = 2.5;
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@7 241 d.identifier = "curve-fsr-timed";
Chris@7 242 d.name = "Curve: FixedSampleRate/Timed";
Chris@7 243 d.description = "A time series with a fixed sample rate (independent of process step size) but with timestamps on features";
Chris@7 244 d.unit = "";
Chris@7 245 d.hasFixedBinCount = true;
Chris@7 246 d.binCount = 1;
Chris@7 247 d.hasKnownExtents = false;
Chris@7 248 d.isQuantized = false;
Chris@7 249 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 250 d.sampleRate = 2.5;
Chris@7 251 d.hasDuration = false;
Chris@7 252 m_outputNumbers[d.identifier] = n++;
Chris@7 253 list.push_back(d);
Chris@7 254
Chris@32 255 d.identifier = "curve-fsr-mixed";
Chris@32 256 d.name = "Curve: FixedSampleRate/Mixed";
Chris@32 257 d.description = "A time series with a fixed sample rate (independent of process step size) and with timestamps on some features";
Chris@32 258 d.unit = "";
Chris@32 259 d.hasFixedBinCount = true;
Chris@32 260 d.binCount = 1;
Chris@32 261 d.hasKnownExtents = false;
Chris@32 262 d.isQuantized = false;
Chris@32 263 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@32 264 d.sampleRate = 2.5;
Chris@32 265 d.hasDuration = false;
Chris@32 266 m_outputNumbers[d.identifier] = n++;
Chris@32 267 list.push_back(d);
Chris@32 268
Chris@1 269 d.identifier = "curve-vsr";
Chris@1 270 d.name = "Curve: VariableSampleRate";
Chris@2 271 d.description = "A variably-spaced series of values";
Chris@1 272 d.unit = "";
Chris@1 273 d.hasFixedBinCount = true;
Chris@1 274 d.binCount = 1;
Chris@1 275 d.hasKnownExtents = false;
Chris@1 276 d.isQuantized = false;
Chris@1 277 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@2 278 d.sampleRate = 0;
Chris@1 279 d.hasDuration = false;
Chris@7 280 m_outputNumbers[d.identifier] = n++;
Chris@1 281 list.push_back(d);
Chris@1 282
Chris@2 283 d.identifier = "grid-oss";
Chris@2 284 d.name = "Grid: OneSamplePerStep";
Chris@2 285 d.description = "A fixed-height grid of values with one column per process block";
Chris@2 286 d.unit = "";
Chris@2 287 d.hasFixedBinCount = true;
Chris@4 288 d.binCount = 10;
Chris@2 289 d.hasKnownExtents = false;
Chris@2 290 d.isQuantized = false;
Chris@4 291 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@2 292 d.sampleRate = 0;
Chris@2 293 d.hasDuration = false;
Chris@7 294 m_outputNumbers[d.identifier] = n++;
Chris@2 295 list.push_back(d);
Chris@2 296
Chris@2 297 d.identifier = "grid-fsr";
Chris@2 298 d.name = "Grid: FixedSampleRate";
Chris@2 299 d.description = "A fixed-height grid of values with equally-spaced columns (independent of process step size)";
Chris@2 300 d.unit = "";
Chris@2 301 d.hasFixedBinCount = true;
Chris@4 302 d.binCount = 10;
Chris@2 303 d.hasKnownExtents = false;
Chris@2 304 d.isQuantized = false;
Chris@4 305 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 306 d.sampleRate = 2.5;
Chris@2 307 d.hasDuration = false;
Chris@7 308 m_outputNumbers[d.identifier] = n++;
Chris@2 309 list.push_back(d);
Chris@2 310
Chris@5 311 d.identifier = "notes-regions";
Chris@5 312 d.name = "Notes or Regions";
Chris@5 313 d.description = "Variably-spaced features with one value and duration";
Chris@5 314 d.unit = "";
Chris@5 315 d.hasFixedBinCount = true;
Chris@5 316 d.binCount = 1;
Chris@5 317 d.hasKnownExtents = false;
Chris@5 318 d.isQuantized = false;
Chris@5 319 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@5 320 d.sampleRate = 0;
Chris@5 321 d.hasDuration = true;
Chris@7 322 m_outputNumbers[d.identifier] = n++;
Chris@5 323 list.push_back(d);
Chris@2 324
Chris@19 325 d.identifier = "input-summary";
Chris@19 326 d.name = "Data derived from inputs";
Chris@22 327 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 328 d.unit = "";
Chris@18 329 d.hasFixedBinCount = true;
Chris@18 330 d.binCount = m_channels;
Chris@18 331 d.hasKnownExtents = false;
Chris@18 332 d.isQuantized = false;
Chris@18 333 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@18 334 d.hasDuration = false;
Chris@18 335 m_outputNumbers[d.identifier] = n++;
Chris@18 336 list.push_back(d);
Chris@18 337
Chris@20 338 d.identifier = "input-timestamp";
Chris@20 339 d.name = "Input timestamp";
Chris@21 340 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 341 d.unit = "samples";
Chris@20 342 d.hasFixedBinCount = true;
Chris@20 343 d.binCount = 1;
Chris@20 344 d.hasKnownExtents = false;
Chris@20 345 d.isQuantized = false;
Chris@20 346 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@20 347 d.hasDuration = false;
Chris@20 348 m_outputNumbers[d.identifier] = n++;
Chris@20 349 list.push_back(d);
Chris@20 350
Chris@0 351 return list;
Chris@0 352 }
Chris@0 353
Chris@0 354 bool
Chris@0 355 VampTestPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize)
Chris@0 356 {
Chris@0 357 if (channels < getMinChannelCount() ||
Chris@31 358 channels > getMaxChannelCount()) return false;
Chris@0 359
Chris@18 360 m_channels = channels;
Chris@3 361 m_stepSize = stepSize;
Chris@3 362 m_blockSize = blockSize;
Chris@0 363
Chris@0 364 return true;
Chris@0 365 }
Chris@0 366
Chris@0 367 void
Chris@0 368 VampTestPlugin::reset()
Chris@0 369 {
Chris@3 370 m_n = 0;
Chris@3 371 }
Chris@3 372
Chris@3 373 static Vamp::Plugin::Feature
Chris@3 374 instant(RealTime r, int i, int n)
Chris@3 375 {
Chris@19 376 stringstream s;
Chris@3 377 Vamp::Plugin::Feature f;
Chris@3 378 f.hasTimestamp = true;
Chris@3 379 f.timestamp = r;
Chris@3 380 f.hasDuration = false;
Chris@3 381 s << i+1 << " of " << n << " at " << r.toText();
Chris@3 382 f.label = s.str();
Chris@3 383 return f;
Chris@3 384 }
Chris@3 385
Chris@3 386 static Vamp::Plugin::Feature
Chris@3 387 untimedCurveValue(RealTime r, int i, int n)
Chris@3 388 {
Chris@19 389 stringstream s;
Chris@3 390 Vamp::Plugin::Feature f;
Chris@3 391 f.hasTimestamp = false;
Chris@3 392 f.hasDuration = false;
Chris@3 393 float v = float(i) / float(n);
Chris@3 394 f.values.push_back(v);
Chris@3 395 s << i+1 << " of " << n << ": " << v << " at " << r.toText();
Chris@3 396 f.label = s.str();
Chris@3 397 return f;
Chris@0 398 }
Chris@0 399
Chris@4 400 static Vamp::Plugin::Feature
Chris@4 401 timedCurveValue(RealTime r, int i, int n)
Chris@4 402 {
Chris@19 403 stringstream s;
Chris@4 404 Vamp::Plugin::Feature f;
Chris@4 405 f.hasTimestamp = true;
Chris@4 406 f.timestamp = r;
Chris@4 407 f.hasDuration = false;
Chris@4 408 float v = float(i) / float(n);
Chris@4 409 f.values.push_back(v);
Chris@4 410 s << i+1 << " of " << n << ": " << v << " at " << r.toText();
Chris@4 411 f.label = s.str();
Chris@4 412 return f;
Chris@4 413 }
Chris@4 414
Chris@4 415 static Vamp::Plugin::Feature
Chris@7 416 snappedCurveValue(RealTime r, RealTime sn, int i, int n)
Chris@7 417 {
Chris@19 418 stringstream s;
Chris@7 419 Vamp::Plugin::Feature f;
Chris@7 420 f.hasTimestamp = true;
Chris@7 421 f.timestamp = r;
Chris@7 422 f.hasDuration = false;
Chris@7 423 float v = float(i) / float(n);
Chris@7 424 f.values.push_back(v);
Chris@7 425 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " snap to " << sn.toText();
Chris@7 426 f.label = s.str();
Chris@7 427 return f;
Chris@7 428 }
Chris@7 429
Chris@7 430 static Vamp::Plugin::Feature
Chris@4 431 gridColumn(RealTime r, int i, int n)
Chris@4 432 {
Chris@19 433 stringstream s;
Chris@4 434 Vamp::Plugin::Feature f;
Chris@4 435 f.hasTimestamp = false;
Chris@4 436 f.hasDuration = false;
Chris@4 437 for (int j = 0; j < 10; ++j) {
Chris@31 438 float v = float(j + i + 2) / float(n + 10);
Chris@31 439 f.values.push_back(v);
Chris@4 440 }
Chris@4 441 s << i+1 << " of " << n << " at " << r.toText();
Chris@4 442 f.label = s.str();
Chris@4 443 return f;
Chris@4 444 }
Chris@4 445
Chris@5 446 static Vamp::Plugin::Feature
Chris@5 447 noteOrRegion(RealTime r, RealTime d, int i, int n)
Chris@5 448 {
Chris@19 449 stringstream s;
Chris@5 450 Vamp::Plugin::Feature f;
Chris@5 451 f.hasTimestamp = true;
Chris@5 452 f.timestamp = r;
Chris@5 453 f.hasDuration = true;
Chris@5 454 f.duration = d;
Chris@5 455 float v = float(i) / float(n);
Chris@5 456 f.values.push_back(v);
Chris@5 457 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " dur. " << d.toText();
Chris@5 458 f.label = s.str();
Chris@5 459 return f;
Chris@5 460 }
Chris@5 461
Chris@7 462 static
Chris@7 463 float snap(float x, float r)
Chris@7 464 {
Chris@7 465 int n = int(x / r + 0.5);
Chris@7 466 return n * r;
Chris@7 467 }
Chris@7 468
Chris@5 469 Vamp::Plugin::FeatureSet
Chris@5 470 VampTestPlugin::featuresFrom(RealTime timestamp, bool final)
Chris@0 471 {
Chris@3 472 FeatureSet fs;
Chris@3 473
Chris@3 474 RealTime endTime = timestamp + RealTime::frame2RealTime
Chris@31 475 (m_stepSize, m_inputSampleRate);
Chris@3 476
Chris@3 477 for (int i = 0; i < (int)m_instants.size(); ++i) {
Chris@5 478
Chris@31 479 if (m_instants[i] >= timestamp && (final || m_instants[i] < endTime)) {
Chris@31 480 fs[m_outputNumbers["instants"]]
Chris@31 481 .push_back(instant(m_instants[i], i, m_instants.size()));
Chris@31 482 }
Chris@4 483
Chris@31 484 RealTime variCurveTime = m_instants[i] / 2;
Chris@31 485 if (variCurveTime >= timestamp && (final || variCurveTime < endTime)) {
Chris@31 486 fs[m_outputNumbers["curve-vsr"]]
Chris@31 487 .push_back(timedCurveValue(variCurveTime, i, m_instants.size()));
Chris@31 488 }
Chris@5 489
Chris@31 490 RealTime noteTime = (m_instants[i] + m_instants[i]) / 3;
Chris@31 491 RealTime noteDuration = RealTime::fromSeconds((i % 2 == 0) ? 1.75 : 0.5);
Chris@5 492
Chris@31 493 if (noteTime >= timestamp && (final || noteTime < endTime)) {
Chris@31 494 fs[m_outputNumbers["notes-regions"]]
Chris@31 495 .push_back(noteOrRegion(noteTime, noteDuration, i, m_instants.size()));
Chris@31 496 }
Chris@3 497 }
Chris@3 498
Chris@5 499 if (!final) {
Chris@3 500
Chris@31 501 if (m_n < 20) {
Chris@31 502 fs[m_outputNumbers["curve-oss"]]
Chris@31 503 .push_back(untimedCurveValue(timestamp, m_n, 20));
Chris@31 504 }
Chris@3 505
Chris@31 506 if (m_n < 5) {
Chris@31 507 fs[m_outputNumbers["curve-fsr"]]
Chris@31 508 .push_back(untimedCurveValue(RealTime::fromSeconds(m_n / 2.5), m_n, 10));
Chris@6 509
Chris@31 510 float s = (m_n / 4) * 2;
Chris@31 511 if ((m_n % 4) > 0) {
Chris@31 512 s += float((m_n % 4) - 1) / 6.0;
Chris@31 513 }
Chris@31 514 fs[m_outputNumbers["curve-fsr-timed"]]
Chris@31 515 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@31 516 RealTime::fromSeconds(snap(s, 0.4)),
Chris@31 517 m_n, 10));
Chris@31 518 }
Chris@5 519
Chris@31 520 if (m_n < 20) {
Chris@31 521 fs[m_outputNumbers["grid-oss"]]
Chris@31 522 .push_back(gridColumn(timestamp, m_n, 20));
Chris@31 523 }
Chris@5 524
Chris@5 525 } else {
Chris@5 526
Chris@31 527 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) {
Chris@31 528 fs[m_outputNumbers["curve-fsr"]]
Chris@31 529 .push_back(untimedCurveValue(RealTime::fromSeconds(i / 2.5), i, 10));
Chris@7 530
Chris@31 531 float s = (i / 4) * 2;
Chris@31 532 if ((i % 4) > 0) {
Chris@31 533 s += float((i % 4) - 1) / 6.0;
Chris@31 534 }
Chris@31 535 fs[m_outputNumbers["curve-fsr-timed"]]
Chris@31 536 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@31 537 RealTime::fromSeconds(snap(s, 0.4)),
Chris@31 538 i, 10));
Chris@31 539 }
Chris@32 540
Chris@32 541 for (int i = 0; i < 10; ++i) {
Chris@32 542 static std::vector<float> times {
Chris@33 543 2.4, 2.9, 3.14, 3.5, 4.0, 4.4, 3.9, 4.4, 4.8, 5
Chris@32 544 };
Chris@32 545 float s = times[i];
Chris@32 546 float sn = snap(s, 0.4) + 1e-5; // to avoid printing e.g. 2.799
Chris@33 547 if (i == 4 || i == 5 || i == 8) {
Chris@32 548 fs[m_outputNumbers["curve-fsr-mixed"]]
Chris@32 549 .push_back(untimedCurveValue(RealTime::fromSeconds(s),
Chris@32 550 i, 10));
Chris@32 551 } else {
Chris@32 552 fs[m_outputNumbers["curve-fsr-mixed"]]
Chris@32 553 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@32 554 RealTime::fromSeconds(sn),
Chris@32 555 i, 10));
Chris@32 556 }
Chris@32 557 }
Chris@31 558
Chris@31 559 for (int i = 0; i < 10; ++i) {
Chris@31 560 fs[m_outputNumbers["grid-fsr"]]
Chris@31 561 .push_back(gridColumn(RealTime::fromSeconds(i / 2.5), i, 10));
Chris@31 562 }
Chris@4 563 }
Chris@4 564
Chris@3 565 m_lastTime = endTime;
Chris@3 566 m_n = m_n + 1;
Chris@3 567 return fs;
Chris@5 568 }
Chris@5 569
Chris@5 570 VampTestPlugin::FeatureSet
Chris@5 571 VampTestPlugin::process(const float *const *inputBuffers, RealTime timestamp)
Chris@5 572 {
Chris@17 573 if (!m_produceOutput) return FeatureSet();
Chris@5 574 FeatureSet fs = featuresFrom(timestamp, false);
Chris@22 575
Chris@22 576 Feature f;
Chris@22 577 float eps = 1e-6f;
Chris@18 578
Chris@18 579 for (int c = 0; c < m_channels; ++c) {
Chris@31 580 if (!m_frequencyDomain) {
Chris@31 581 // first value plus number of non-zero values
Chris@31 582 float sum = inputBuffers[c][0];
Chris@31 583 for (int i = 0; i < m_blockSize; ++i) {
Chris@31 584 if (fabsf(inputBuffers[c][i]) >= eps) sum += 1;
Chris@31 585 }
Chris@31 586 f.values.push_back(sum);
Chris@31 587 } else {
Chris@31 588 // If we're in frequency-domain mode, we convert back to
Chris@31 589 // time-domain to calculate the input-summary feature
Chris@31 590 // output. That should help the caller check that
Chris@31 591 // time-frequency conversion has gone more or less OK,
Chris@31 592 // though they'll still have to bear in mind windowing and
Chris@31 593 // FFT shift (i.e. phase shift which puts the first
Chris@31 594 // element in the middle of the frame)
Chris@31 595 vector<double> ri(m_blockSize, 0.0);
Chris@31 596 vector<double> ii(m_blockSize, 0.0);
Chris@31 597 vector<double> ro(m_blockSize, 0.0);
Chris@31 598 vector<double> io(m_blockSize, 0.0);
Chris@31 599 for (int i = 0; i <= m_blockSize/2; ++i) {
Chris@31 600 ri[i] = inputBuffers[c][i*2];
Chris@31 601 ii[i] = inputBuffers[c][i*2 + 1];
Chris@31 602 if (i > 0) ri[m_blockSize-i] = ri[i];
Chris@31 603 if (i > 0) ii[m_blockSize-i] = -ii[i];
Chris@31 604 }
Chris@31 605 Vamp::FFT::inverse(m_blockSize, &ri[0], &ii[0], &ro[0], &io[0]);
Chris@31 606 float sum = 0;
Chris@31 607 for (int i = 0; i < m_blockSize; ++i) {
Chris@31 608 if (fabs(ro[i]) >= eps) sum += 1;
Chris@31 609 }
Chris@31 610 sum += ro[0];
Chris@31 611 f.values.push_back(sum);
Chris@31 612 }
Chris@18 613 }
Chris@22 614
Chris@19 615 fs[m_outputNumbers["input-summary"]].push_back(f);
Chris@20 616
Chris@20 617 f.values.clear();
Chris@22 618 float frame = RealTime::realTime2Frame(timestamp, m_inputSampleRate);
Chris@22 619 f.values.push_back(frame);
Chris@20 620 fs[m_outputNumbers["input-timestamp"]].push_back(f);
Chris@18 621
Chris@5 622 return fs;
Chris@0 623 }
Chris@0 624
Chris@0 625 VampTestPlugin::FeatureSet
Chris@0 626 VampTestPlugin::getRemainingFeatures()
Chris@0 627 {
Chris@17 628 if (!m_produceOutput) return FeatureSet();
Chris@5 629 FeatureSet fs = featuresFrom(m_lastTime, true);
Chris@3 630 return fs;
Chris@0 631 }
Chris@0 632