Mercurial > hg > svcore
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 {