Mercurial > hg > tuning-difference
comparison chroma-compare-plugin/TuningDifference.cpp @ 16:2c6460fb1fcf
Fine frequency search
author | Chris Cannam |
---|---|
date | Thu, 05 Feb 2015 08:54:52 +0000 |
parents | 994f5294996d |
children | 0147406654d8 |
comparison
equal
deleted
inserted
replaced
15:994f5294996d | 16:2c6460fb1fcf |
---|---|
261 } | 261 } |
262 | 262 |
263 TuningDifference::TFeature | 263 TuningDifference::TFeature |
264 TuningDifference::computeFeatureFromTotals(const TFeature &totals) const | 264 TuningDifference::computeFeatureFromTotals(const TFeature &totals) const |
265 { | 265 { |
266 if (m_frameCount == 0) return totals; | |
267 | |
266 TFeature feature(m_bpo); | 268 TFeature feature(m_bpo); |
267 double sum = 0.0; | 269 double sum = 0.0; |
268 | 270 |
269 for (int i = 0; i < m_bpo; ++i) { | 271 for (int i = 0; i < m_bpo; ++i) { |
270 double value = totals[i] / m_frameCount; | 272 double value = totals[i] / m_frameCount; |
271 feature[i] += value; | 273 feature[i] += value; |
272 sum += value; | 274 sum += value; |
273 } | 275 } |
298 TuningDifference::computeFeatureFromSignal(const Signal &signal, double hz) const | 300 TuningDifference::computeFeatureFromSignal(const Signal &signal, double hz) const |
299 { | 301 { |
300 Chromagram chromagram(paramsForTuningFrequency(hz)); | 302 Chromagram chromagram(paramsForTuningFrequency(hz)); |
301 | 303 |
302 TFeature totals(m_bpo, 0.0); | 304 TFeature totals(m_bpo, 0.0); |
305 | |
306 cerr << "computeFeatureFromSignal: hz = " << hz << ", frame count = " << m_frameCount << endl; | |
303 | 307 |
304 for (int i = 0; i < m_frameCount; ++i) { | 308 for (int i = 0; i < m_frameCount; ++i) { |
305 Signal::const_iterator first = signal.begin() + i * m_blockSize; | 309 Signal::const_iterator first = signal.begin() + i * m_blockSize; |
306 Signal::const_iterator last = first + m_blockSize; | 310 Signal::const_iterator last = first + m_blockSize; |
307 if (last > signal.end()) last = signal.end(); | 311 if (last > signal.end()) last = signal.end(); |
370 | 374 |
371 cerr << "best is " << best << endl; | 375 cerr << "best is " << best << endl; |
372 return best; | 376 return best; |
373 } | 377 } |
374 | 378 |
379 double | |
380 TuningDifference::findFineFrequency(int coarseCents, double coarseScore) | |
381 { | |
382 int coarseResolution = 1200 / m_bpo; | |
383 int searchDistance = coarseResolution/2 - 1; | |
384 | |
385 double bestScore = coarseScore; | |
386 double bestHz = frequencyForCentsAbove440(coarseCents); | |
387 | |
388 cerr << "corresponding coarse Hz " << bestHz << " scores " << coarseScore << endl; | |
389 cerr << "searchDistance = " << searchDistance << endl; | |
390 | |
391 for (int sign = -1; sign <= 1; sign += 2) { | |
392 for (int offset = 1; offset <= searchDistance; ++offset) { | |
393 | |
394 int fineCents = coarseCents + sign * offset; | |
395 | |
396 cerr << "trying with fineCents = " << fineCents << "..." << endl; | |
397 | |
398 double fineHz = frequencyForCentsAbove440(fineCents); | |
399 TFeature fineFeature = computeFeatureFromSignal(m_other, fineHz); | |
400 double fineScore = featureDistance(fineFeature); | |
401 | |
402 cerr << "fine offset = " << offset << ", cents = " << fineCents | |
403 << ", Hz = " << fineHz << ", score " << fineScore | |
404 << " (best score so far " << bestScore << ")" << endl; | |
405 | |
406 if (fineScore < bestScore) { | |
407 cerr << "is good!" << endl; | |
408 bestScore = fineScore; | |
409 bestHz = fineScore; | |
410 } else { | |
411 break; | |
412 } | |
413 } | |
414 } | |
415 | |
416 return bestHz; | |
417 } | |
418 | |
375 TuningDifference::FeatureSet | 419 TuningDifference::FeatureSet |
376 TuningDifference::getRemainingFeatures() | 420 TuningDifference::getRemainingFeatures() |
377 { | 421 { |
378 FeatureSet fs; | 422 FeatureSet fs; |
379 if (m_frameCount == 0) return fs; | 423 if (m_frameCount == 0) return fs; |
391 for (auto v: otherFeature) f.values.push_back(v); | 435 for (auto v: otherFeature) f.values.push_back(v); |
392 fs[m_outputs["otherfeature"]].push_back(f); | 436 fs[m_outputs["otherfeature"]].push_back(f); |
393 | 437 |
394 int rotation = findBestRotation(otherFeature); | 438 int rotation = findBestRotation(otherFeature); |
395 | 439 |
396 int coarseCents = -(rotation * 100) / (m_bpo / 12); | 440 int coarseCents = -(rotation * 1200) / m_bpo; |
397 | 441 |
398 cerr << "rotation " << rotation << " -> cents " << coarseCents << endl; | 442 cerr << "rotation " << rotation << " -> cents " << coarseCents << endl; |
399 | 443 |
400 double coarseHz = frequencyForCentsAbove440(coarseCents); | 444 double coarseHz = frequencyForCentsAbove440(coarseCents); |
401 | 445 |
405 cerr << "corresponding Hz " << coarseHz << " scores " << coarseScore << endl; | 449 cerr << "corresponding Hz " << coarseHz << " scores " << coarseScore << endl; |
406 | 450 |
407 f.values.clear(); | 451 f.values.clear(); |
408 for (auto v: coarseFeature) f.values.push_back(v); | 452 for (auto v: coarseFeature) f.values.push_back(v); |
409 fs[m_outputs["rotfeature"]].push_back(f); | 453 fs[m_outputs["rotfeature"]].push_back(f); |
454 | |
455 double fineHz = findFineFrequency(coarseCents, coarseScore); | |
456 | |
457 cerr << "overall best Hz = " << fineHz << endl; | |
410 | 458 |
411 return fs; | 459 return fs; |
412 } | 460 } |
413 | 461 |