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