annotate VampTestPlugin.cpp @ 17:ac7f544c7b20

Give the plugin a parameter
author Chris Cannam
date Tue, 25 Nov 2014 12:00:52 +0000
parents 33a799b77949
children 014cce47e998
rev   line source
Chris@0 1
Chris@0 2
Chris@0 3 #include "VampTestPlugin.h"
Chris@0 4
Chris@3 5 #include <sstream>
Chris@3 6
Chris@3 7 using std::stringstream;
Chris@3 8
Chris@3 9 using Vamp::RealTime;
Chris@0 10
Chris@0 11 VampTestPlugin::VampTestPlugin(float inputSampleRate) :
Chris@3 12 Plugin(inputSampleRate),
Chris@17 13 m_produceOutput(true),
Chris@3 14 m_n(0),
Chris@3 15 m_stepSize(0),
Chris@3 16 m_blockSize(0)
Chris@0 17 {
Chris@3 18 for (int i = 0; i < 10; ++i) {
Chris@3 19 m_instants.push_back(RealTime::fromSeconds(1.5 * i));
Chris@3 20 }
Chris@0 21 }
Chris@0 22
Chris@0 23 VampTestPlugin::~VampTestPlugin()
Chris@0 24 {
Chris@0 25 }
Chris@0 26
Chris@0 27 string
Chris@0 28 VampTestPlugin::getIdentifier() const
Chris@0 29 {
Chris@0 30 return "vamp-test-plugin";
Chris@0 31 }
Chris@0 32
Chris@0 33 string
Chris@0 34 VampTestPlugin::getName() const
Chris@0 35 {
Chris@0 36 return "Vamp Test Plugin";
Chris@0 37 }
Chris@0 38
Chris@0 39 string
Chris@0 40 VampTestPlugin::getDescription() const
Chris@0 41 {
Chris@0 42 return "Test plugin for hosts handling various output types";
Chris@0 43 }
Chris@0 44
Chris@0 45 string
Chris@0 46 VampTestPlugin::getMaker() const
Chris@0 47 {
Chris@0 48 return "Chris Cannam";
Chris@0 49 }
Chris@0 50
Chris@0 51 int
Chris@0 52 VampTestPlugin::getPluginVersion() const
Chris@0 53 {
Chris@17 54 return 2;
Chris@0 55 }
Chris@0 56
Chris@0 57 string
Chris@0 58 VampTestPlugin::getCopyright() const
Chris@0 59 {
Chris@0 60 return "BSD";
Chris@0 61 }
Chris@0 62
Chris@0 63 VampTestPlugin::InputDomain
Chris@0 64 VampTestPlugin::getInputDomain() const
Chris@0 65 {
Chris@0 66 return TimeDomain;
Chris@0 67 }
Chris@0 68
Chris@0 69 size_t
Chris@0 70 VampTestPlugin::getPreferredBlockSize() const
Chris@0 71 {
Chris@0 72 return 0;
Chris@0 73 }
Chris@0 74
Chris@0 75 size_t
Chris@0 76 VampTestPlugin::getPreferredStepSize() const
Chris@0 77 {
Chris@0 78 return 0;
Chris@0 79 }
Chris@0 80
Chris@0 81 size_t
Chris@0 82 VampTestPlugin::getMinChannelCount() const
Chris@0 83 {
Chris@0 84 return 1;
Chris@0 85 }
Chris@0 86
Chris@0 87 size_t
Chris@0 88 VampTestPlugin::getMaxChannelCount() const
Chris@0 89 {
Chris@0 90 return 1;
Chris@0 91 }
Chris@0 92
Chris@0 93 VampTestPlugin::ParameterList
Chris@0 94 VampTestPlugin::getParameterDescriptors() const
Chris@0 95 {
Chris@0 96 ParameterList list;
Chris@17 97
Chris@17 98 // Provide one parameter, and make it so that we can easily tell
Chris@17 99 // whether it has been changed
Chris@17 100 ParameterDescriptor d;
Chris@17 101 d.identifier = "produce_output";
Chris@17 102 d.name = "Produce some output";
Chris@17 103 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 104 d.unit = "";
Chris@17 105 d.minValue = 0;
Chris@17 106 d.maxValue = 1;
Chris@17 107 d.defaultValue = 1;
Chris@17 108 d.isQuantized = true;
Chris@17 109 d.quantizeStep = 1;
Chris@17 110 list.push_back(d);
Chris@17 111
Chris@0 112 return list;
Chris@0 113 }
Chris@0 114
Chris@0 115 float
Chris@0 116 VampTestPlugin::getParameter(string identifier) const
Chris@0 117 {
Chris@17 118 if (identifier == "produce_output") {
Chris@17 119 return m_produceOutput ? 1.f : 0.f;
Chris@17 120 }
Chris@0 121 return 0;
Chris@0 122 }
Chris@0 123
Chris@0 124 void
Chris@0 125 VampTestPlugin::setParameter(string identifier, float value)
Chris@0 126 {
Chris@17 127 if (identifier == "produce_output") {
Chris@17 128 m_produceOutput = (value > 0.5);
Chris@17 129 }
Chris@0 130 }
Chris@0 131
Chris@0 132 VampTestPlugin::ProgramList
Chris@0 133 VampTestPlugin::getPrograms() const
Chris@0 134 {
Chris@0 135 ProgramList list;
Chris@0 136 return list;
Chris@0 137 }
Chris@0 138
Chris@0 139 string
Chris@0 140 VampTestPlugin::getCurrentProgram() const
Chris@0 141 {
Chris@0 142 return ""; // no programs
Chris@0 143 }
Chris@0 144
Chris@0 145 void
Chris@0 146 VampTestPlugin::selectProgram(string name)
Chris@0 147 {
Chris@0 148 }
Chris@0 149
Chris@0 150 VampTestPlugin::OutputList
Chris@0 151 VampTestPlugin::getOutputDescriptors() const
Chris@0 152 {
Chris@0 153 OutputList list;
Chris@0 154
Chris@7 155 int n = 0;
Chris@7 156
Chris@0 157 OutputDescriptor d;
Chris@1 158
Chris@1 159 d.identifier = "instants";
Chris@1 160 d.name = "Instants";
Chris@2 161 d.description = "Single time points without values";
Chris@1 162 d.unit = "";
Chris@1 163 d.hasFixedBinCount = true;
Chris@1 164 d.binCount = 0;
Chris@1 165 d.hasKnownExtents = false;
Chris@1 166 d.isQuantized = false;
Chris@1 167 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@1 168 d.hasDuration = false;
Chris@7 169 m_outputNumbers[d.identifier] = n++;
Chris@1 170 list.push_back(d);
Chris@1 171
Chris@1 172 d.identifier = "curve-oss";
Chris@1 173 d.name = "Curve: OneSamplePerStep";
Chris@2 174 d.description = "A time series with one value per process block";
Chris@0 175 d.unit = "";
Chris@0 176 d.hasFixedBinCount = true;
Chris@0 177 d.binCount = 1;
Chris@0 178 d.hasKnownExtents = false;
Chris@0 179 d.isQuantized = false;
Chris@0 180 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@0 181 d.hasDuration = false;
Chris@7 182 m_outputNumbers[d.identifier] = n++;
Chris@0 183 list.push_back(d);
Chris@0 184
Chris@1 185 d.identifier = "curve-fsr";
Chris@1 186 d.name = "Curve: FixedSampleRate";
Chris@2 187 d.description = "A time series with equally-spaced values (independent of process step size)";
Chris@1 188 d.unit = "";
Chris@1 189 d.hasFixedBinCount = true;
Chris@1 190 d.binCount = 1;
Chris@1 191 d.hasKnownExtents = false;
Chris@1 192 d.isQuantized = false;
Chris@1 193 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 194 d.sampleRate = 2.5;
Chris@1 195 d.hasDuration = false;
Chris@7 196 m_outputNumbers[d.identifier] = n++;
Chris@1 197 list.push_back(d);
Chris@1 198
Chris@7 199 d.identifier = "curve-fsr-timed";
Chris@7 200 d.name = "Curve: FixedSampleRate/Timed";
Chris@7 201 d.description = "A time series with a fixed sample rate (independent of process step size) but with timestamps on features";
Chris@7 202 d.unit = "";
Chris@7 203 d.hasFixedBinCount = true;
Chris@7 204 d.binCount = 1;
Chris@7 205 d.hasKnownExtents = false;
Chris@7 206 d.isQuantized = false;
Chris@7 207 d.sampleType = OutputDescriptor::FixedSampleRate;
Chris@8 208 d.sampleRate = 2.5;
Chris@7 209 d.hasDuration = false;
Chris@7 210 m_outputNumbers[d.identifier] = n++;
Chris@7 211 list.push_back(d);
Chris@7 212
Chris@1 213 d.identifier = "curve-vsr";
Chris@1 214 d.name = "Curve: VariableSampleRate";
Chris@2 215 d.description = "A variably-spaced series of values";
Chris@1 216 d.unit = "";
Chris@1 217 d.hasFixedBinCount = true;
Chris@1 218 d.binCount = 1;
Chris@1 219 d.hasKnownExtents = false;
Chris@1 220 d.isQuantized = false;
Chris@1 221 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@2 222 d.sampleRate = 0;
Chris@1 223 d.hasDuration = false;
Chris@7 224 m_outputNumbers[d.identifier] = n++;
Chris@1 225 list.push_back(d);
Chris@1 226
Chris@2 227 d.identifier = "grid-oss";
Chris@2 228 d.name = "Grid: OneSamplePerStep";
Chris@2 229 d.description = "A fixed-height grid of values with one column per process block";
Chris@2 230 d.unit = "";
Chris@2 231 d.hasFixedBinCount = true;
Chris@4 232 d.binCount = 10;
Chris@2 233 d.hasKnownExtents = false;
Chris@2 234 d.isQuantized = false;
Chris@4 235 d.sampleType = OutputDescriptor::OneSamplePerStep;
Chris@2 236 d.sampleRate = 0;
Chris@2 237 d.hasDuration = false;
Chris@7 238 m_outputNumbers[d.identifier] = n++;
Chris@2 239 list.push_back(d);
Chris@2 240
Chris@2 241 d.identifier = "grid-fsr";
Chris@2 242 d.name = "Grid: FixedSampleRate";
Chris@2 243 d.description = "A fixed-height grid of values with equally-spaced columns (independent of process step size)";
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::FixedSampleRate;
Chris@8 250 d.sampleRate = 2.5;
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@5 255 d.identifier = "notes-regions";
Chris@5 256 d.name = "Notes or Regions";
Chris@5 257 d.description = "Variably-spaced features with one value and duration";
Chris@5 258 d.unit = "";
Chris@5 259 d.hasFixedBinCount = true;
Chris@5 260 d.binCount = 1;
Chris@5 261 d.hasKnownExtents = false;
Chris@5 262 d.isQuantized = false;
Chris@5 263 d.sampleType = OutputDescriptor::VariableSampleRate;
Chris@5 264 d.sampleRate = 0;
Chris@5 265 d.hasDuration = true;
Chris@7 266 m_outputNumbers[d.identifier] = n++;
Chris@5 267 list.push_back(d);
Chris@2 268
Chris@0 269 return list;
Chris@0 270 }
Chris@0 271
Chris@0 272 bool
Chris@0 273 VampTestPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize)
Chris@0 274 {
Chris@0 275 if (channels < getMinChannelCount() ||
Chris@0 276 channels > getMaxChannelCount()) return false;
Chris@0 277
Chris@3 278 m_stepSize = stepSize;
Chris@3 279 m_blockSize = blockSize;
Chris@0 280
Chris@0 281 return true;
Chris@0 282 }
Chris@0 283
Chris@0 284 void
Chris@0 285 VampTestPlugin::reset()
Chris@0 286 {
Chris@3 287 m_n = 0;
Chris@3 288 }
Chris@3 289
Chris@3 290 static Vamp::Plugin::Feature
Chris@3 291 instant(RealTime r, int i, int n)
Chris@3 292 {
Chris@3 293 std::stringstream s;
Chris@3 294 Vamp::Plugin::Feature f;
Chris@3 295 f.hasTimestamp = true;
Chris@3 296 f.timestamp = r;
Chris@3 297 f.hasDuration = false;
Chris@3 298 s << i+1 << " of " << n << " at " << r.toText();
Chris@3 299 f.label = s.str();
Chris@3 300 return f;
Chris@3 301 }
Chris@3 302
Chris@3 303 static Vamp::Plugin::Feature
Chris@3 304 untimedCurveValue(RealTime r, int i, int n)
Chris@3 305 {
Chris@3 306 std::stringstream s;
Chris@3 307 Vamp::Plugin::Feature f;
Chris@3 308 f.hasTimestamp = false;
Chris@3 309 f.hasDuration = false;
Chris@3 310 float v = float(i) / float(n);
Chris@3 311 f.values.push_back(v);
Chris@3 312 s << i+1 << " of " << n << ": " << v << " at " << r.toText();
Chris@3 313 f.label = s.str();
Chris@3 314 return f;
Chris@0 315 }
Chris@0 316
Chris@4 317 static Vamp::Plugin::Feature
Chris@4 318 timedCurveValue(RealTime r, int i, int n)
Chris@4 319 {
Chris@4 320 std::stringstream s;
Chris@4 321 Vamp::Plugin::Feature f;
Chris@4 322 f.hasTimestamp = true;
Chris@4 323 f.timestamp = r;
Chris@4 324 f.hasDuration = false;
Chris@4 325 float v = float(i) / float(n);
Chris@4 326 f.values.push_back(v);
Chris@4 327 s << i+1 << " of " << n << ": " << v << " at " << r.toText();
Chris@4 328 f.label = s.str();
Chris@4 329 return f;
Chris@4 330 }
Chris@4 331
Chris@4 332 static Vamp::Plugin::Feature
Chris@7 333 snappedCurveValue(RealTime r, RealTime sn, int i, int n)
Chris@7 334 {
Chris@7 335 std::stringstream s;
Chris@7 336 Vamp::Plugin::Feature f;
Chris@7 337 f.hasTimestamp = true;
Chris@7 338 f.timestamp = r;
Chris@7 339 f.hasDuration = false;
Chris@7 340 float v = float(i) / float(n);
Chris@7 341 f.values.push_back(v);
Chris@7 342 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " snap to " << sn.toText();
Chris@7 343 f.label = s.str();
Chris@7 344 return f;
Chris@7 345 }
Chris@7 346
Chris@7 347 static Vamp::Plugin::Feature
Chris@4 348 gridColumn(RealTime r, int i, int n)
Chris@4 349 {
Chris@4 350 std::stringstream s;
Chris@4 351 Vamp::Plugin::Feature f;
Chris@4 352 f.hasTimestamp = false;
Chris@4 353 f.hasDuration = false;
Chris@4 354 for (int j = 0; j < 10; ++j) {
Chris@4 355 float v = float(j + i + 2) / float(n + 10);
Chris@4 356 f.values.push_back(v);
Chris@4 357 }
Chris@4 358 s << i+1 << " of " << n << " at " << r.toText();
Chris@4 359 f.label = s.str();
Chris@4 360 return f;
Chris@4 361 }
Chris@4 362
Chris@5 363 static Vamp::Plugin::Feature
Chris@5 364 noteOrRegion(RealTime r, RealTime d, int i, int n)
Chris@5 365 {
Chris@5 366 std::stringstream s;
Chris@5 367 Vamp::Plugin::Feature f;
Chris@5 368 f.hasTimestamp = true;
Chris@5 369 f.timestamp = r;
Chris@5 370 f.hasDuration = true;
Chris@5 371 f.duration = d;
Chris@5 372 float v = float(i) / float(n);
Chris@5 373 f.values.push_back(v);
Chris@5 374 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " dur. " << d.toText();
Chris@5 375 f.label = s.str();
Chris@5 376 return f;
Chris@5 377 }
Chris@5 378
Chris@7 379 static
Chris@7 380 float snap(float x, float r)
Chris@7 381 {
Chris@7 382 int n = int(x / r + 0.5);
Chris@7 383 return n * r;
Chris@7 384 }
Chris@7 385
Chris@5 386 Vamp::Plugin::FeatureSet
Chris@5 387 VampTestPlugin::featuresFrom(RealTime timestamp, bool final)
Chris@0 388 {
Chris@3 389 FeatureSet fs;
Chris@3 390
Chris@3 391 RealTime endTime = timestamp + RealTime::frame2RealTime
Chris@3 392 (m_stepSize, m_inputSampleRate);
Chris@3 393
Chris@3 394 for (int i = 0; i < (int)m_instants.size(); ++i) {
Chris@5 395
Chris@5 396 if (m_instants[i] >= timestamp && (final || m_instants[i] < endTime)) {
Chris@7 397 fs[m_outputNumbers["instants"]]
Chris@7 398 .push_back(instant(m_instants[i], i, m_instants.size()));
Chris@3 399 }
Chris@4 400
Chris@4 401 RealTime variCurveTime = m_instants[i] / 2;
Chris@5 402 if (variCurveTime >= timestamp && (final || variCurveTime < endTime)) {
Chris@7 403 fs[m_outputNumbers["curve-vsr"]]
Chris@7 404 .push_back(timedCurveValue(variCurveTime, i, m_instants.size()));
Chris@4 405 }
Chris@5 406
Chris@5 407 RealTime noteTime = (m_instants[i] + m_instants[i]) / 3;
Chris@5 408 RealTime noteDuration = RealTime::fromSeconds((i % 2 == 0) ? 1.75 : 0.5);
Chris@5 409
Chris@5 410 if (noteTime >= timestamp && (final || noteTime < endTime)) {
Chris@7 411 fs[m_outputNumbers["notes-regions"]]
Chris@7 412 .push_back(noteOrRegion(noteTime, noteDuration, i, m_instants.size()));
Chris@5 413 }
Chris@3 414 }
Chris@3 415
Chris@5 416 if (!final) {
Chris@3 417
Chris@5 418 if (m_n < 20) {
Chris@7 419 fs[m_outputNumbers["curve-oss"]]
Chris@7 420 .push_back(untimedCurveValue(timestamp, m_n, 20));
Chris@5 421 }
Chris@3 422
Chris@5 423 if (m_n < 5) {
Chris@7 424 fs[m_outputNumbers["curve-fsr"]]
Chris@8 425 .push_back(untimedCurveValue(RealTime::fromSeconds(m_n / 2.5), m_n, 10));
Chris@6 426
Chris@7 427 float s = (m_n / 4) * 2;
Chris@7 428 if ((m_n % 4) > 0) {
Chris@7 429 s += float((m_n % 4) - 1) / 6.0;
Chris@7 430 }
Chris@7 431 fs[m_outputNumbers["curve-fsr-timed"]]
Chris@7 432 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@8 433 RealTime::fromSeconds(snap(s, 0.4)),
Chris@7 434 m_n, 10));
Chris@5 435 }
Chris@5 436
Chris@5 437 if (m_n < 20) {
Chris@7 438 fs[m_outputNumbers["grid-oss"]]
Chris@7 439 .push_back(gridColumn(timestamp, m_n, 20));
Chris@5 440 }
Chris@5 441
Chris@5 442 } else {
Chris@5 443
Chris@5 444 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) {
Chris@7 445 fs[m_outputNumbers["curve-fsr"]]
Chris@8 446 .push_back(untimedCurveValue(RealTime::fromSeconds(i / 2.5), i, 10));
Chris@7 447
Chris@7 448 float s = (i / 4) * 2;
Chris@7 449 if ((i % 4) > 0) {
Chris@7 450 s += float((i % 4) - 1) / 6.0;
Chris@7 451 }
Chris@7 452 fs[m_outputNumbers["curve-fsr-timed"]]
Chris@7 453 .push_back(snappedCurveValue(RealTime::fromSeconds(s),
Chris@8 454 RealTime::fromSeconds(snap(s, 0.4)),
Chris@7 455 i, 10));
Chris@5 456 }
Chris@5 457
Chris@8 458 for (int i = 0; i < 10; ++i) {
Chris@7 459 fs[m_outputNumbers["grid-fsr"]]
Chris@9 460 .push_back(gridColumn(RealTime::fromSeconds(i / 2.5), i, 10));
Chris@5 461 }
Chris@4 462 }
Chris@4 463
Chris@3 464 m_lastTime = endTime;
Chris@3 465 m_n = m_n + 1;
Chris@3 466 return fs;
Chris@5 467 }
Chris@5 468
Chris@5 469 VampTestPlugin::FeatureSet
Chris@5 470 VampTestPlugin::process(const float *const *inputBuffers, RealTime timestamp)
Chris@5 471 {
Chris@17 472 if (!m_produceOutput) return FeatureSet();
Chris@5 473 FeatureSet fs = featuresFrom(timestamp, false);
Chris@5 474 return fs;
Chris@0 475 }
Chris@0 476
Chris@0 477 VampTestPlugin::FeatureSet
Chris@0 478 VampTestPlugin::getRemainingFeatures()
Chris@0 479 {
Chris@17 480 if (!m_produceOutput) return FeatureSet();
Chris@5 481 FeatureSet fs = featuresFrom(m_lastTime, true);
Chris@3 482 return fs;
Chris@0 483 }
Chris@0 484