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