Mercurial > hg > silvet
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 { |