diff data/fft/FFTDataServer.cpp @ 273:f1f47660483d

* Fix up and simplify the LayerTreeModel, removing a horrible memory leak * Move phase-unwrapped frequency estimation from SpectrogramLayer to FFTDataServer * Make the spectrum show peak phase-unwrapped frequencies as well (still needs work) * Start adding piano keyboard horizontal scale to spectrum * Debug output for id3 tags
author Chris Cannam
date Tue, 03 Jul 2007 12:46:18 +0000
parents 8bbc9e336475
children 522f82311e4e
line wrap: on
line diff
--- a/data/fft/FFTDataServer.cpp	Mon Jul 02 14:57:01 2007 +0000
+++ b/data/fft/FFTDataServer.cpp	Tue Jul 03 12:46:18 2007 +0000
@@ -1099,6 +1099,43 @@
     }
 }    
 
+bool
+FFTDataServer::estimateStableFrequency(size_t x, size_t y,
+                                       float sampleRate, float &frequency)
+{
+    frequency = (float(y) * sampleRate) / m_fftSize;
+
+    if (x+1 >= m_width || y >= m_height) return false;
+
+    // At frequency f, a phase shift of 2pi (one cycle) happens in 1/f sec.
+    // At hopsize h and sample rate sr, one hop happens in h/sr sec.
+    // At window size w, for bin b, f is b*sr/w.
+    // thus 2pi phase shift happens in w/(b*sr) sec.
+    // We need to know what phase shift we expect from h/sr sec.
+    // -> 2pi * ((h/sr) / (w/(b*sr)))
+    //  = 2pi * ((h * b * sr) / (w * sr))
+    //  = 2pi * (h * b) / w.
+
+    float oldPhase = getPhaseAt(x, y);
+    float newPhase = getPhaseAt(x+1, y);
+
+    float expectedPhase =
+	oldPhase + (2.0 * M_PI * y * m_windowIncrement) / m_fftSize;
+
+    float phaseError = princargf(newPhase - expectedPhase);
+
+//    bool stable = (fabsf(phaseError) < (1.1f * (m_windowIncrement * M_PI) / m_fftSize));
+
+    // The new frequency estimate based on the phase error resulting
+    // from assuming the "native" frequency of this bin
+
+    frequency =
+        (sampleRate * (expectedPhase + phaseError - oldPhase)) /
+        (2 * M_PI * m_windowIncrement);
+
+    return true;
+}
+
 size_t
 FFTDataServer::getFillCompletion() const 
 {