comparison src/Silvet.cpp @ 302:cac0be04c43c livemode

Add output for the templates (probably temporarily)
author Chris Cannam
date Tue, 02 Dec 2014 17:13:10 +0000
parents 00fab71b80ec
children d8468176339d
comparison
equal deleted inserted replaced
301:00fab71b80ec 302:cac0be04c43c
293 d.sampleRate = m_colsPerSec; 293 d.sampleRate = m_colsPerSec;
294 d.hasDuration = false; 294 d.hasDuration = false;
295 m_pitchOutputNo = list.size(); 295 m_pitchOutputNo = list.size();
296 list.push_back(d); 296 list.push_back(d);
297 297
298 d.identifier = "templates";
299 d.name = "Templates";
300 d.description = "Constant-Q spectral templates for the selected instrument pack.";
301 d.unit = "";
302 d.hasFixedBinCount = true;
303 d.binCount = getPack(0).templateHeight;
304 d.binNames.clear();
305 if (m_cq) {
306 char name[50];
307 for (int i = 0; i < getPack(0).templateHeight; ++i) {
308 // We have a 600-bin (10 oct 60-bin CQ) of which the
309 // lowest-frequency 55 bins have been dropped, for a
310 // 545-bin template. The native CQ bins go high->low
311 // frequency though, so these are still the first 545 bins
312 // as reported by getBinFrequency, though in reverse order
313 float freq = m_cq->getBinFrequency
314 (getPack(0).templateHeight - i - 1);
315 sprintf(name, "%.1f Hz", freq);
316 d.binNames.push_back(name);
317 }
318 }
319 d.hasKnownExtents = false;
320 d.isQuantized = false;
321 d.sampleType = OutputDescriptor::FixedSampleRate;
322 d.sampleRate = m_colsPerSec;
323 d.hasDuration = false;
324 m_templateOutputNo = list.size();
325 list.push_back(d);
326
298 return list; 327 return list;
299 } 328 }
300 329
301 std::string 330 std::string
302 Silvet::noteName(int note, int shift, int shiftCount) const 331 Silvet::noteName(int note, int shift, int shiftCount) const
465 } 494 }
466 495
467 Silvet::FeatureSet 496 Silvet::FeatureSet
468 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp) 497 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
469 { 498 {
499 FeatureSet fs;
500
470 if (m_columnCount == 0) { 501 if (m_columnCount == 0) {
471 m_startTime = timestamp; 502 m_startTime = timestamp;
503 insertTemplateFeatures(fs);
472 } 504 }
473 505
474 vector<float> flattened(m_blockSize); 506 vector<float> flattened(m_blockSize);
475 float gain = 1.f; 507 float gain = 1.f;
476 m_flattener->connectInputPort 508 m_flattener->connectInputPort
499 int resamplerLatency = m_resampler->getLatency(); 531 int resamplerLatency = m_resampler->getLatency();
500 532
501 if (hadCount < resamplerLatency) { 533 if (hadCount < resamplerLatency) {
502 int stillToDrop = resamplerLatency - hadCount; 534 int stillToDrop = resamplerLatency - hadCount;
503 if (stillToDrop >= int(data.size())) { 535 if (stillToDrop >= int(data.size())) {
504 return FeatureSet(); 536 return fs;
505 } else { 537 } else {
506 data = vector<double>(data.begin() + stillToDrop, data.end()); 538 data = vector<double>(data.begin() + stillToDrop, data.end());
507 } 539 }
508 } 540 }
509 } 541 }
510 542
511 Grid cqout = m_cq->process(data); 543 Grid cqout = m_cq->process(data);
512 FeatureSet fs = transcribe(cqout); 544 transcribe(cqout, fs);
513 return fs; 545 return fs;
514 } 546 }
515 547
516 Silvet::FeatureSet 548 Silvet::FeatureSet
517 Silvet::getRemainingFeatures() 549 Silvet::getRemainingFeatures()
518 { 550 {
519 Grid cqout = m_cq->getRemainingOutput(); 551 Grid cqout = m_cq->getRemainingOutput();
520 FeatureSet fs = transcribe(cqout); 552 FeatureSet fs;
553 if (m_columnCount == 0) {
554 // process() was never called, but we still want these
555 insertTemplateFeatures(fs);
556 } else {
557 transcribe(cqout, fs);
558 }
521 return fs; 559 return fs;
522 } 560 }
523 561
524 Silvet::FeatureSet 562 void
525 Silvet::transcribe(const Grid &cqout) 563 Silvet::insertTemplateFeatures(FeatureSet &fs)
564 {
565 const InstrumentPack &pack = getPack(m_instrument);
566 for (int i = 0; i < int(pack.templates.size()) * pack.templateNoteCount; ++i) {
567 RealTime timestamp = RealTime::fromSeconds(double(i) / m_colsPerSec);
568 Feature f;
569 char buffer[50];
570 sprintf(buffer, "Note %d", i + 1);
571 f.label = buffer;
572 f.hasTimestamp = true;
573 f.timestamp = timestamp;
574 f.values = pack.templates[i / pack.templateNoteCount]
575 .data[i % pack.templateNoteCount];
576 fs[m_templateOutputNo].push_back(f);
577 }
578 }
579
580 void
581 Silvet::transcribe(const Grid &cqout, Silvet::FeatureSet &fs)
526 { 582 {
527 Grid filtered = preProcess(cqout); 583 Grid filtered = preProcess(cqout);
528 584
529 FeatureSet fs; 585 if (filtered.empty()) return;
530
531 if (filtered.empty()) return fs;
532 586
533 const InstrumentPack &pack(getPack(m_instrument)); 587 const InstrumentPack &pack(getPack(m_instrument));
534 588
535 for (int i = 0; i < (int)filtered.size(); ++i) { 589 for (int i = 0; i < (int)filtered.size(); ++i) {
536 Feature f; 590 Feature f;
632 for (FeatureList::const_iterator fi = noteFeatures.begin(); 686 for (FeatureList::const_iterator fi = noteFeatures.begin();
633 fi != noteFeatures.end(); ++fi) { 687 fi != noteFeatures.end(); ++fi) {
634 fs[m_notesOutputNo].push_back(*fi); 688 fs[m_notesOutputNo].push_back(*fi);
635 } 689 }
636 } 690 }
637
638 return fs;
639 } 691 }
640 692
641 Silvet::Grid 693 Silvet::Grid
642 Silvet::preProcess(const Grid &in) 694 Silvet::preProcess(const Grid &in)
643 { 695 {