Mercurial > hg > vamp-test-plugin
comparison VampTestPlugin.cpp @ 7:1bff4a80852c
Map output names to numbers; add timed FixedSampleRate output
| author | Chris Cannam | 
|---|---|
| date | Wed, 27 Mar 2013 11:07:09 +0000 | 
| parents | 9b4ce965db35 | 
| children | 8c3a61d37984 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 6:9b4ce965db35 | 7:1bff4a80852c | 
|---|---|
| 128 VampTestPlugin::OutputList | 128 VampTestPlugin::OutputList | 
| 129 VampTestPlugin::getOutputDescriptors() const | 129 VampTestPlugin::getOutputDescriptors() const | 
| 130 { | 130 { | 
| 131 OutputList list; | 131 OutputList list; | 
| 132 | 132 | 
| 133 int n = 0; | |
| 134 | |
| 133 OutputDescriptor d; | 135 OutputDescriptor d; | 
| 134 | 136 | 
| 135 // 0 -> instants | |
| 136 d.identifier = "instants"; | 137 d.identifier = "instants"; | 
| 137 d.name = "Instants"; | 138 d.name = "Instants"; | 
| 138 d.description = "Single time points without values"; | 139 d.description = "Single time points without values"; | 
| 139 d.unit = ""; | 140 d.unit = ""; | 
| 140 d.hasFixedBinCount = true; | 141 d.hasFixedBinCount = true; | 
| 141 d.binCount = 0; | 142 d.binCount = 0; | 
| 142 d.hasKnownExtents = false; | 143 d.hasKnownExtents = false; | 
| 143 d.isQuantized = false; | 144 d.isQuantized = false; | 
| 144 d.sampleType = OutputDescriptor::VariableSampleRate; | 145 d.sampleType = OutputDescriptor::VariableSampleRate; | 
| 145 d.hasDuration = false; | 146 d.hasDuration = false; | 
| 146 list.push_back(d); | 147 m_outputNumbers[d.identifier] = n++; | 
| 147 | 148 list.push_back(d); | 
| 148 // 1 -> curve-oss | 149 | 
| 149 d.identifier = "curve-oss"; | 150 d.identifier = "curve-oss"; | 
| 150 d.name = "Curve: OneSamplePerStep"; | 151 d.name = "Curve: OneSamplePerStep"; | 
| 151 d.description = "A time series with one value per process block"; | 152 d.description = "A time series with one value per process block"; | 
| 152 d.unit = ""; | 153 d.unit = ""; | 
| 153 d.hasFixedBinCount = true; | 154 d.hasFixedBinCount = true; | 
| 154 d.binCount = 1; | 155 d.binCount = 1; | 
| 155 d.hasKnownExtents = false; | 156 d.hasKnownExtents = false; | 
| 156 d.isQuantized = false; | 157 d.isQuantized = false; | 
| 157 d.sampleType = OutputDescriptor::OneSamplePerStep; | 158 d.sampleType = OutputDescriptor::OneSamplePerStep; | 
| 158 d.hasDuration = false; | 159 d.hasDuration = false; | 
| 159 list.push_back(d); | 160 m_outputNumbers[d.identifier] = n++; | 
| 160 | 161 list.push_back(d); | 
| 161 // 2 -> curve-fsr | 162 | 
| 162 d.identifier = "curve-fsr"; | 163 d.identifier = "curve-fsr"; | 
| 163 d.name = "Curve: FixedSampleRate"; | 164 d.name = "Curve: FixedSampleRate"; | 
| 164 d.description = "A time series with equally-spaced values (independent of process step size)"; | 165 d.description = "A time series with equally-spaced values (independent of process step size)"; | 
| 165 d.unit = ""; | 166 d.unit = ""; | 
| 166 d.hasFixedBinCount = true; | 167 d.hasFixedBinCount = true; | 
| 168 d.hasKnownExtents = false; | 169 d.hasKnownExtents = false; | 
| 169 d.isQuantized = false; | 170 d.isQuantized = false; | 
| 170 d.sampleType = OutputDescriptor::FixedSampleRate; | 171 d.sampleType = OutputDescriptor::FixedSampleRate; | 
| 171 d.sampleRate = 2; | 172 d.sampleRate = 2; | 
| 172 d.hasDuration = false; | 173 d.hasDuration = false; | 
| 173 list.push_back(d); | 174 m_outputNumbers[d.identifier] = n++; | 
| 174 | 175 list.push_back(d); | 
| 175 // 3 -> curve-vsr | 176 | 
| 177 d.identifier = "curve-fsr-timed"; | |
| 178 d.name = "Curve: FixedSampleRate/Timed"; | |
| 179 d.description = "A time series with a fixed sample rate (independent of process step size) but with timestamps on features"; | |
| 180 d.unit = ""; | |
| 181 d.hasFixedBinCount = true; | |
| 182 d.binCount = 1; | |
| 183 d.hasKnownExtents = false; | |
| 184 d.isQuantized = false; | |
| 185 d.sampleType = OutputDescriptor::FixedSampleRate; | |
| 186 d.sampleRate = 2; | |
| 187 d.hasDuration = false; | |
| 188 m_outputNumbers[d.identifier] = n++; | |
| 189 list.push_back(d); | |
| 190 | |
| 176 d.identifier = "curve-vsr"; | 191 d.identifier = "curve-vsr"; | 
| 177 d.name = "Curve: VariableSampleRate"; | 192 d.name = "Curve: VariableSampleRate"; | 
| 178 d.description = "A variably-spaced series of values"; | 193 d.description = "A variably-spaced series of values"; | 
| 179 d.unit = ""; | 194 d.unit = ""; | 
| 180 d.hasFixedBinCount = true; | 195 d.hasFixedBinCount = true; | 
| 182 d.hasKnownExtents = false; | 197 d.hasKnownExtents = false; | 
| 183 d.isQuantized = false; | 198 d.isQuantized = false; | 
| 184 d.sampleType = OutputDescriptor::VariableSampleRate; | 199 d.sampleType = OutputDescriptor::VariableSampleRate; | 
| 185 d.sampleRate = 0; | 200 d.sampleRate = 0; | 
| 186 d.hasDuration = false; | 201 d.hasDuration = false; | 
| 187 list.push_back(d); | 202 m_outputNumbers[d.identifier] = n++; | 
| 188 | 203 list.push_back(d); | 
| 189 // 4 -> grid-oss | 204 | 
| 190 d.identifier = "grid-oss"; | 205 d.identifier = "grid-oss"; | 
| 191 d.name = "Grid: OneSamplePerStep"; | 206 d.name = "Grid: OneSamplePerStep"; | 
| 192 d.description = "A fixed-height grid of values with one column per process block"; | 207 d.description = "A fixed-height grid of values with one column per process block"; | 
| 193 d.unit = ""; | 208 d.unit = ""; | 
| 194 d.hasFixedBinCount = true; | 209 d.hasFixedBinCount = true; | 
| 196 d.hasKnownExtents = false; | 211 d.hasKnownExtents = false; | 
| 197 d.isQuantized = false; | 212 d.isQuantized = false; | 
| 198 d.sampleType = OutputDescriptor::OneSamplePerStep; | 213 d.sampleType = OutputDescriptor::OneSamplePerStep; | 
| 199 d.sampleRate = 0; | 214 d.sampleRate = 0; | 
| 200 d.hasDuration = false; | 215 d.hasDuration = false; | 
| 201 list.push_back(d); | 216 m_outputNumbers[d.identifier] = n++; | 
| 202 | 217 list.push_back(d); | 
| 203 // 5 -> grid-fsr | 218 | 
| 204 d.identifier = "grid-fsr"; | 219 d.identifier = "grid-fsr"; | 
| 205 d.name = "Grid: FixedSampleRate"; | 220 d.name = "Grid: FixedSampleRate"; | 
| 206 d.description = "A fixed-height grid of values with equally-spaced columns (independent of process step size)"; | 221 d.description = "A fixed-height grid of values with equally-spaced columns (independent of process step size)"; | 
| 207 d.unit = ""; | 222 d.unit = ""; | 
| 208 d.hasFixedBinCount = true; | 223 d.hasFixedBinCount = true; | 
| 210 d.hasKnownExtents = false; | 225 d.hasKnownExtents = false; | 
| 211 d.isQuantized = false; | 226 d.isQuantized = false; | 
| 212 d.sampleType = OutputDescriptor::FixedSampleRate; | 227 d.sampleType = OutputDescriptor::FixedSampleRate; | 
| 213 d.sampleRate = 2; | 228 d.sampleRate = 2; | 
| 214 d.hasDuration = false; | 229 d.hasDuration = false; | 
| 215 list.push_back(d); | 230 m_outputNumbers[d.identifier] = n++; | 
| 216 | 231 list.push_back(d); | 
| 217 // 6 -> notes | 232 | 
| 218 d.identifier = "notes-regions"; | 233 d.identifier = "notes-regions"; | 
| 219 d.name = "Notes or Regions"; | 234 d.name = "Notes or Regions"; | 
| 220 d.description = "Variably-spaced features with one value and duration"; | 235 d.description = "Variably-spaced features with one value and duration"; | 
| 221 d.unit = ""; | 236 d.unit = ""; | 
| 222 d.hasFixedBinCount = true; | 237 d.hasFixedBinCount = true; | 
| 224 d.hasKnownExtents = false; | 239 d.hasKnownExtents = false; | 
| 225 d.isQuantized = false; | 240 d.isQuantized = false; | 
| 226 d.sampleType = OutputDescriptor::VariableSampleRate; | 241 d.sampleType = OutputDescriptor::VariableSampleRate; | 
| 227 d.sampleRate = 0; | 242 d.sampleRate = 0; | 
| 228 d.hasDuration = true; | 243 d.hasDuration = true; | 
| 244 m_outputNumbers[d.identifier] = n++; | |
| 229 list.push_back(d); | 245 list.push_back(d); | 
| 230 | 246 | 
| 231 return list; | 247 return list; | 
| 232 } | 248 } | 
| 233 | 249 | 
| 285 f.timestamp = r; | 301 f.timestamp = r; | 
| 286 f.hasDuration = false; | 302 f.hasDuration = false; | 
| 287 float v = float(i) / float(n); | 303 float v = float(i) / float(n); | 
| 288 f.values.push_back(v); | 304 f.values.push_back(v); | 
| 289 s << i+1 << " of " << n << ": " << v << " at " << r.toText(); | 305 s << i+1 << " of " << n << ": " << v << " at " << r.toText(); | 
| 306 f.label = s.str(); | |
| 307 return f; | |
| 308 } | |
| 309 | |
| 310 static Vamp::Plugin::Feature | |
| 311 snappedCurveValue(RealTime r, RealTime sn, int i, int n) | |
| 312 { | |
| 313 std::stringstream s; | |
| 314 Vamp::Plugin::Feature f; | |
| 315 f.hasTimestamp = true; | |
| 316 f.timestamp = r; | |
| 317 f.hasDuration = false; | |
| 318 float v = float(i) / float(n); | |
| 319 f.values.push_back(v); | |
| 320 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " snap to " << sn.toText(); | |
| 290 f.label = s.str(); | 321 f.label = s.str(); | 
| 291 return f; | 322 return f; | 
| 292 } | 323 } | 
| 293 | 324 | 
| 294 static Vamp::Plugin::Feature | 325 static Vamp::Plugin::Feature | 
| 321 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " dur. " << d.toText(); | 352 s << i+1 << " of " << n << ": " << v << " at " << r.toText() << " dur. " << d.toText(); | 
| 322 f.label = s.str(); | 353 f.label = s.str(); | 
| 323 return f; | 354 return f; | 
| 324 } | 355 } | 
| 325 | 356 | 
| 357 static | |
| 358 float snap(float x, float r) | |
| 359 { | |
| 360 int n = int(x / r + 0.5); | |
| 361 return n * r; | |
| 362 } | |
| 363 | |
| 326 Vamp::Plugin::FeatureSet | 364 Vamp::Plugin::FeatureSet | 
| 327 VampTestPlugin::featuresFrom(RealTime timestamp, bool final) | 365 VampTestPlugin::featuresFrom(RealTime timestamp, bool final) | 
| 328 { | 366 { | 
| 329 FeatureSet fs; | 367 FeatureSet fs; | 
| 330 | 368 | 
| 332 (m_stepSize, m_inputSampleRate); | 370 (m_stepSize, m_inputSampleRate); | 
| 333 | 371 | 
| 334 for (int i = 0; i < (int)m_instants.size(); ++i) { | 372 for (int i = 0; i < (int)m_instants.size(); ++i) { | 
| 335 | 373 | 
| 336 if (m_instants[i] >= timestamp && (final || m_instants[i] < endTime)) { | 374 if (m_instants[i] >= timestamp && (final || m_instants[i] < endTime)) { | 
| 337 // instants output | 375 fs[m_outputNumbers["instants"]] | 
| 338 fs[0].push_back(instant(m_instants[i], i, m_instants.size())); | 376 .push_back(instant(m_instants[i], i, m_instants.size())); | 
| 339 } | 377 } | 
| 340 | 378 | 
| 341 RealTime variCurveTime = m_instants[i] / 2; | 379 RealTime variCurveTime = m_instants[i] / 2; | 
| 342 if (variCurveTime >= timestamp && (final || variCurveTime < endTime)) { | 380 if (variCurveTime >= timestamp && (final || variCurveTime < endTime)) { | 
| 343 // curve-vsr output | 381 fs[m_outputNumbers["curve-vsr"]] | 
| 344 fs[3].push_back(timedCurveValue(variCurveTime, i, m_instants.size())); | 382 .push_back(timedCurveValue(variCurveTime, i, m_instants.size())); | 
| 345 } | 383 } | 
| 346 | 384 | 
| 347 RealTime noteTime = (m_instants[i] + m_instants[i]) / 3; | 385 RealTime noteTime = (m_instants[i] + m_instants[i]) / 3; | 
| 348 RealTime noteDuration = RealTime::fromSeconds((i % 2 == 0) ? 1.75 : 0.5); | 386 RealTime noteDuration = RealTime::fromSeconds((i % 2 == 0) ? 1.75 : 0.5); | 
| 349 | 387 | 
| 350 if (noteTime >= timestamp && (final || noteTime < endTime)) { | 388 if (noteTime >= timestamp && (final || noteTime < endTime)) { | 
| 351 // notes-regions output | 389 fs[m_outputNumbers["notes-regions"]] | 
| 352 fs[6].push_back(noteOrRegion(noteTime, noteDuration, i, m_instants.size())); | 390 .push_back(noteOrRegion(noteTime, noteDuration, i, m_instants.size())); | 
| 353 } | 391 } | 
| 354 } | 392 } | 
| 355 | 393 | 
| 356 if (!final) { | 394 if (!final) { | 
| 357 | 395 | 
| 358 if (m_n < 20) { | 396 if (m_n < 20) { | 
| 359 // curve-oss output | 397 fs[m_outputNumbers["curve-oss"]] | 
| 360 fs[1].push_back(untimedCurveValue(timestamp, m_n, 20)); | 398 .push_back(untimedCurveValue(timestamp, m_n, 20)); | 
| 361 } | 399 } | 
| 362 | 400 | 
| 363 if (m_n < 5) { | 401 if (m_n < 5) { | 
| 364 // curve-fsr output | 402 fs[m_outputNumbers["curve-fsr"]] | 
| 365 fs[2].push_back(untimedCurveValue(RealTime::fromSeconds(m_n / 2.0), m_n, 10)); | 403 .push_back(untimedCurveValue(RealTime::fromSeconds(m_n / 2.0), m_n, 10)); | 
| 366 | 404 | 
| 367 //!!! we should also have a FixedSampleRate output for | 405 float s = (m_n / 4) * 2; | 
| 368 //!!! features *with* timestamps, because the host is | 406 if ((m_n % 4) > 0) { | 
| 369 //!!! supposed to read them but round them | 407 s += float((m_n % 4) - 1) / 6.0; | 
| 408 } | |
| 409 fs[m_outputNumbers["curve-fsr-timed"]] | |
| 410 .push_back(snappedCurveValue(RealTime::fromSeconds(s), | |
| 411 RealTime::fromSeconds(snap(s, 0.5)), | |
| 412 m_n, 10)); | |
| 370 } | 413 } | 
| 371 | 414 | 
| 372 if (m_n < 20) { | 415 if (m_n < 20) { | 
| 373 // grid-oss output | 416 fs[m_outputNumbers["grid-oss"]] | 
| 374 fs[4].push_back(gridColumn(timestamp, m_n, 20)); | 417 .push_back(gridColumn(timestamp, m_n, 20)); | 
| 375 } | 418 } | 
| 376 | 419 | 
| 377 } else { | 420 } else { | 
| 378 | 421 | 
| 379 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) { | 422 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) { | 
| 380 // curve-fsr output | 423 fs[m_outputNumbers["curve-fsr"]] | 
| 381 fs[2].push_back(untimedCurveValue(RealTime::fromSeconds(i / 2.0), i, 10)); | 424 .push_back(untimedCurveValue(RealTime::fromSeconds(i / 2.0), i, 10)); | 
| 425 | |
| 426 float s = (i / 4) * 2; | |
| 427 if ((i % 4) > 0) { | |
| 428 s += float((i % 4) - 1) / 6.0; | |
| 429 } | |
| 430 fs[m_outputNumbers["curve-fsr-timed"]] | |
| 431 .push_back(snappedCurveValue(RealTime::fromSeconds(s), | |
| 432 RealTime::fromSeconds(snap(s, 0.5)), | |
| 433 i, 10)); | |
| 382 } | 434 } | 
| 383 | 435 | 
| 384 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) { | 436 for (int i = (m_n > 5 ? 5 : m_n); i < 10; ++i) { | 
| 385 // grid-fsr output | 437 fs[m_outputNumbers["grid-fsr"]] | 
| 386 fs[5].push_back(gridColumn(RealTime::fromSeconds(i / 2.0), i, 10)); | 438 .push_back(gridColumn(RealTime::fromSeconds(i / 2.0), i, 10)); | 
| 387 } | 439 } | 
| 388 } | 440 } | 
| 389 | 441 | 
| 390 m_lastTime = endTime; | 442 m_lastTime = endTime; | 
| 391 m_n = m_n + 1; | 443 m_n = m_n + 1; | 
