changeset 16:2c6460fb1fcf

Fine frequency search
author Chris Cannam
date Thu, 05 Feb 2015 08:54:52 +0000
parents 994f5294996d
children 0147406654d8
files chroma-compare-plugin/TuningDifference.cpp chroma-compare-plugin/TuningDifference.h
diffstat 2 files changed, 51 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/chroma-compare-plugin/TuningDifference.cpp	Thu Feb 05 08:38:59 2015 +0000
+++ b/chroma-compare-plugin/TuningDifference.cpp	Thu Feb 05 08:54:52 2015 +0000
@@ -263,9 +263,11 @@
 TuningDifference::TFeature
 TuningDifference::computeFeatureFromTotals(const TFeature &totals) const
 {
+    if (m_frameCount == 0) return totals;
+    
     TFeature feature(m_bpo);
     double sum = 0.0;
-    
+
     for (int i = 0; i < m_bpo; ++i) {
 	double value = totals[i] / m_frameCount;
 	feature[i] += value;
@@ -300,6 +302,8 @@
     Chromagram chromagram(paramsForTuningFrequency(hz));
 
     TFeature totals(m_bpo, 0.0);
+
+    cerr << "computeFeatureFromSignal: hz = " << hz << ", frame count = " << m_frameCount << endl;
     
     for (int i = 0; i < m_frameCount; ++i) {
 	Signal::const_iterator first = signal.begin() + i * m_blockSize;
@@ -372,6 +376,46 @@
     return best;
 }
 
+double
+TuningDifference::findFineFrequency(int coarseCents, double coarseScore)
+{
+    int coarseResolution = 1200 / m_bpo;
+    int searchDistance = coarseResolution/2 - 1;
+
+    double bestScore = coarseScore;
+    double bestHz = frequencyForCentsAbove440(coarseCents);
+
+    cerr << "corresponding coarse Hz " << bestHz << " scores " << coarseScore << endl;
+    cerr << "searchDistance = " << searchDistance << endl;
+    
+    for (int sign = -1; sign <= 1; sign += 2) {
+	for (int offset = 1; offset <= searchDistance; ++offset) {
+
+	    int fineCents = coarseCents + sign * offset;
+
+	    cerr << "trying with fineCents = " << fineCents << "..." << endl;
+	    
+	    double fineHz = frequencyForCentsAbove440(fineCents);
+	    TFeature fineFeature = computeFeatureFromSignal(m_other, fineHz);
+	    double fineScore = featureDistance(fineFeature);
+
+	    cerr << "fine offset = " << offset << ", cents = " << fineCents
+		 << ", Hz = " << fineHz << ", score " << fineScore
+		 << " (best score so far " << bestScore << ")" << endl;
+	    
+	    if (fineScore < bestScore) {
+		cerr << "is good!" << endl;
+		bestScore = fineScore;
+		bestHz = fineScore;
+	    } else {
+		break;
+	    }
+	}
+    }
+
+    return bestHz;
+}
+
 TuningDifference::FeatureSet
 TuningDifference::getRemainingFeatures()
 {
@@ -393,7 +437,7 @@
    
     int rotation = findBestRotation(otherFeature);
 
-    int coarseCents = -(rotation * 100) / (m_bpo / 12);
+    int coarseCents = -(rotation * 1200) / m_bpo;
 
     cerr << "rotation " << rotation << " -> cents " << coarseCents << endl;
 
@@ -407,6 +451,10 @@
     f.values.clear();
     for (auto v: coarseFeature) f.values.push_back(v);
     fs[m_outputs["rotfeature"]].push_back(f);
+
+    double fineHz = findFineFrequency(coarseCents, coarseScore);
+
+    cerr << "overall best Hz = " << fineHz << endl;
     
     return fs;
 }
--- a/chroma-compare-plugin/TuningDifference.h	Thu Feb 05 08:38:59 2015 +0000
+++ b/chroma-compare-plugin/TuningDifference.h	Thu Feb 05 08:54:52 2015 +0000
@@ -64,6 +64,7 @@
     TFeature computeFeatureFromSignal(const Signal &signal, double hz) const;
     double featureDistance(const TFeature &other, int rotation = 0) const;
     int findBestRotation(const TFeature &other) const;
+    double findFineFrequency(int coarseCents, double coarseScore);
 
     mutable std::map<string, int> m_outputs;
 };