comparison 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
comparison
equal deleted inserted replaced
272:8bbc9e336475 273:f1f47660483d
1097 // std::cerr << "FFTDataServer::fillColumn(" << x << "): calling resume" << std::endl; 1097 // std::cerr << "FFTDataServer::fillColumn(" << x << "): calling resume" << std::endl;
1098 // resume(); 1098 // resume();
1099 } 1099 }
1100 } 1100 }
1101 1101
1102 bool
1103 FFTDataServer::estimateStableFrequency(size_t x, size_t y,
1104 float sampleRate, float &frequency)
1105 {
1106 frequency = (float(y) * sampleRate) / m_fftSize;
1107
1108 if (x+1 >= m_width || y >= m_height) return false;
1109
1110 // At frequency f, a phase shift of 2pi (one cycle) happens in 1/f sec.
1111 // At hopsize h and sample rate sr, one hop happens in h/sr sec.
1112 // At window size w, for bin b, f is b*sr/w.
1113 // thus 2pi phase shift happens in w/(b*sr) sec.
1114 // We need to know what phase shift we expect from h/sr sec.
1115 // -> 2pi * ((h/sr) / (w/(b*sr)))
1116 // = 2pi * ((h * b * sr) / (w * sr))
1117 // = 2pi * (h * b) / w.
1118
1119 float oldPhase = getPhaseAt(x, y);
1120 float newPhase = getPhaseAt(x+1, y);
1121
1122 float expectedPhase =
1123 oldPhase + (2.0 * M_PI * y * m_windowIncrement) / m_fftSize;
1124
1125 float phaseError = princargf(newPhase - expectedPhase);
1126
1127 // bool stable = (fabsf(phaseError) < (1.1f * (m_windowIncrement * M_PI) / m_fftSize));
1128
1129 // The new frequency estimate based on the phase error resulting
1130 // from assuming the "native" frequency of this bin
1131
1132 frequency =
1133 (sampleRate * (expectedPhase + phaseError - oldPhase)) /
1134 (2 * M_PI * m_windowIncrement);
1135
1136 return true;
1137 }
1138
1102 size_t 1139 size_t
1103 FFTDataServer::getFillCompletion() const 1140 FFTDataServer::getFillCompletion() const
1104 { 1141 {
1105 if (m_fillThread) return m_fillThread->getCompletion(); 1142 if (m_fillThread) return m_fillThread->getCompletion();
1106 else return 100; 1143 else return 100;