comparison src/Silvet.cpp @ 167:416b555df3b2 finetune

More on returning fine tuning (but we're treating different shifts of the same pitch as different notes at the moment which is not right)
author Chris Cannam
date Tue, 20 May 2014 17:49:07 +0100
parents 7979fa40c9f7
children 51bd3d833db8
comparison
equal deleted inserted replaced
166:7979fa40c9f7 167:416b555df3b2
261 261
262 return buf; 262 return buf;
263 } 263 }
264 264
265 float 265 float
266 Silvet::noteFrequency(int note) const 266 Silvet::noteFrequency(int note, int shiftCount) const
267 { 267 {
268 return float(27.5 * pow(2.0, note / 12.0)); 268 float fineNote = float(note) / float(shiftCount);
269 return float(27.5 * pow(2.0, fineNote / 12.0));
269 } 270 }
270 271
271 bool 272 bool
272 Silvet::initialise(size_t channels, size_t stepSize, size_t blockSize) 273 Silvet::initialise(size_t channels, size_t stepSize, size_t blockSize)
273 { 274 {
387 388
388 for (int j = 0; j < iterations; ++j) { 389 for (int j = 0; j < iterations; ++j) {
389 em[i]->iterate(filtered.at(i).data()); 390 em[i]->iterate(filtered.at(i).data());
390 } 391 }
391 } 392 }
393
394 int shiftCount = 1;
395 if (m_hqMode && m_fineTuning) {
396 shiftCount = m_instruments[m_instrument].templateMaxShift * 2 + 1;
397 }
392 398
393 for (int i = 0; i < width; ++i) { 399 for (int i = 0; i < width; ++i) {
394 400
395 if (!em[i]) { 401 if (!em[i]) {
396 noteTrack(map<int, double>()); 402 noteTrack(map<int, double>(), shiftCount);
397 continue; 403 continue;
398 } 404 }
399 405
400 map<int, double> active = postProcess(em[i]->getPitchDistribution(), 406 map<int, double> active = postProcess(em[i]->getPitchDistribution(),
401 em[i]->getShifts(), 407 em[i]->getShifts(),
402 em[i]->getShiftCount(), 408 shiftCount,
403 sums[i]); 409 sums[i]);
404 410
405 delete em[i]; 411 delete em[i];
406 412
407 FeatureList noteFeatures = noteTrack(active); 413 FeatureList noteFeatures = noteTrack(active, shiftCount);
408 414
409 for (FeatureList::const_iterator fi = noteFeatures.begin(); 415 for (FeatureList::const_iterator fi = noteFeatures.begin();
410 fi != noteFeatures.end(); ++fi) { 416 fi != noteFeatures.end(); ++fi) {
411 fs[m_notesOutputNo].push_back(*fi); 417 fs[m_notesOutputNo].push_back(*fi);
412 } 418 }
510 for (int j = 0; j < processingNotes; ++j) { 516 for (int j = 0; j < processingNotes; ++j) {
511 517
512 double strength = filtered[j]; 518 double strength = filtered[j];
513 if (strength < threshold) continue; 519 if (strength < threshold) continue;
514 520
515 // convert note number j to a pitch value p. If we are not using fine tuning or 521 // convert note number j to a pitch value p. If we are not
516 522 // using fine tuning, p is the same as j; otherwise p is j *
517 strengths.insert(ValueIndexMap::value_type(strength, j)); 523 // shiftCount + preferred shift
524
525 int p = j;
526
527 if (m_hqMode && m_fineTuning && shiftCount > 1) {
528 float bestShiftValue = 0.f;
529 int bestShift = 0;
530 for (int f = 0; f < shiftCount; ++f) {
531 if (f == 0 || shifts[f][j] > bestShiftValue) {
532 bestShiftValue = shifts[f][j];
533 bestShift = f;
534 }
535 }
536 //!!! I think our shift array per note is actually upside down, check this
537 p = j * shiftCount + bestShift;
538 }
539
540 strengths.insert(ValueIndexMap::value_type(strength, p));
518 } 541 }
519 542
520 map<int, double> active; 543 map<int, double> active;
521 ValueIndexMap::const_iterator si = strengths.end(); 544 ValueIndexMap::const_iterator si = strengths.end();
522 while (int(active.size()) < polyphony && si != strengths.begin()) { 545 while (int(active.size()) < polyphony && si != strengths.begin()) {
528 551
529 return active; 552 return active;
530 } 553 }
531 554
532 Vamp::Plugin::FeatureList 555 Vamp::Plugin::FeatureList
533 Silvet::noteTrack(const map<int, double> &active) 556 Silvet::noteTrack(const map<int, double> &active, int shiftCount)
534 { 557 {
535 // Minimum duration pruning, and conversion to notes. We can only 558 // Minimum duration pruning, and conversion to notes. We can only
536 // report notes that have just ended (i.e. that are absent in the 559 // report notes that have just ended (i.e. that are absent in the
537 // latest active set but present in the last set in the piano 560 // latest active set but present in the last set in the piano
538 // roll) -- any notes that ended earlier will have been reported 561 // roll) -- any notes that ended earlier will have been reported
600 nf.timestamp = RealTime::fromSeconds 623 nf.timestamp = RealTime::fromSeconds
601 (columnDuration * (start - postFilterLatency) + 0.02); 624 (columnDuration * (start - postFilterLatency) + 0.02);
602 nf.hasDuration = true; 625 nf.hasDuration = true;
603 nf.duration = RealTime::fromSeconds 626 nf.duration = RealTime::fromSeconds
604 (columnDuration * duration); 627 (columnDuration * duration);
605 nf.values.push_back(noteFrequency(note)); 628 nf.values.push_back(noteFrequency(note, shiftCount));
606 nf.values.push_back(velocity); 629 nf.values.push_back(velocity);
607 nf.label = noteName(note); 630 nf.label = noteName(note);
608 noteFeatures.push_back(nf); 631 noteFeatures.push_back(nf);
609 } 632 }
610 633