Mercurial > hg > svcore
comparison data/model/FFTModel.cpp @ 1038:cc27f35aa75c cxx11
Introducing the signed 64-bit frame index type, and fixing build failures from inclusion of -Wconversion with -Werror. Not finished yet.
author | Chris Cannam |
---|---|
date | Tue, 03 Mar 2015 15:18:24 +0000 |
parents | a8aed8a85e09 |
children | a1cd5abcb38b |
comparison
equal
deleted
inserted
replaced
1037:bf0e5944289b | 1038:cc27f35aa75c |
---|---|
210 if (!isOK()) return false; | 210 if (!isOK()) return false; |
211 | 211 |
212 int sampleRate = m_server->getModel()->getSampleRate(); | 212 int sampleRate = m_server->getModel()->getSampleRate(); |
213 | 213 |
214 int fftSize = m_server->getFFTSize() >> m_yshift; | 214 int fftSize = m_server->getFFTSize() >> m_yshift; |
215 frequency = (float(y) * sampleRate) / fftSize; | 215 frequency = float((double(y) * sampleRate) / fftSize); |
216 | 216 |
217 if (x+1 >= getWidth()) return false; | 217 if (x+1 >= getWidth()) return false; |
218 | 218 |
219 // At frequency f, a phase shift of 2pi (one cycle) happens in 1/f sec. | 219 // At frequency f, a phase shift of 2pi (one cycle) happens in 1/f sec. |
220 // At hopsize h and sample rate sr, one hop happens in h/sr sec. | 220 // At hopsize h and sample rate sr, one hop happens in h/sr sec. |
223 // We need to know what phase shift we expect from h/sr sec. | 223 // We need to know what phase shift we expect from h/sr sec. |
224 // -> 2pi * ((h/sr) / (w/(b*sr))) | 224 // -> 2pi * ((h/sr) / (w/(b*sr))) |
225 // = 2pi * ((h * b * sr) / (w * sr)) | 225 // = 2pi * ((h * b * sr) / (w * sr)) |
226 // = 2pi * (h * b) / w. | 226 // = 2pi * (h * b) / w. |
227 | 227 |
228 float oldPhase = getPhaseAt(x, y); | 228 double oldPhase = getPhaseAt(x, y); |
229 float newPhase = getPhaseAt(x+1, y); | 229 double newPhase = getPhaseAt(x+1, y); |
230 | 230 |
231 int incr = getResolution(); | 231 int incr = getResolution(); |
232 | 232 |
233 float expectedPhase = oldPhase + (2.0 * M_PI * y * incr) / fftSize; | 233 double expectedPhase = oldPhase + (2.0 * M_PI * y * incr) / fftSize; |
234 | 234 |
235 float phaseError = princargf(newPhase - expectedPhase); | 235 double phaseError = princarg(newPhase - expectedPhase); |
236 | 236 |
237 // bool stable = (fabsf(phaseError) < (1.1f * (m_windowIncrement * M_PI) / m_fftSize)); | 237 // bool stable = (fabsf(phaseError) < (1.1f * (m_windowIncrement * M_PI) / m_fftSize)); |
238 | 238 |
239 // The new frequency estimate based on the phase error resulting | 239 // The new frequency estimate based on the phase error resulting |
240 // from assuming the "native" frequency of this bin | 240 // from assuming the "native" frequency of this bin |
241 | 241 |
242 frequency = | 242 frequency = |
243 (sampleRate * (expectedPhase + phaseError - oldPhase)) / | 243 float((sampleRate * (expectedPhase + phaseError - oldPhase)) / |
244 (2 * M_PI * incr); | 244 (2 * M_PI * incr)); |
245 | 245 |
246 return true; | 246 return true; |
247 } | 247 } |
248 | 248 |
249 FFTModel::PeakLocationSet | 249 FFTModel::PeakLocationSet |
282 | 282 |
283 Column values = getColumn(x); | 283 Column values = getColumn(x); |
284 | 284 |
285 float mean = 0.f; | 285 float mean = 0.f; |
286 for (int i = 0; i < values.size(); ++i) mean += values[i]; | 286 for (int i = 0; i < values.size(); ++i) mean += values[i]; |
287 if (values.size() >0) mean /= values.size(); | 287 if (values.size() > 0) mean = mean / float(values.size()); |
288 | 288 |
289 // For peak picking we use a moving median window, picking the | 289 // For peak picking we use a moving median window, picking the |
290 // highest value within each continuous region of values that | 290 // highest value within each continuous region of values that |
291 // exceed the median. For pitch adaptivity, we adjust the window | 291 // exceed the median. For pitch adaptivity, we adjust the window |
292 // size to a roughly constant pitch range (about four tones). | 292 // size to a roughly constant pitch range (about four tones). |
293 | 293 |
322 | 322 |
323 while ((int)window.size() > medianWinSize) { | 323 while ((int)window.size() > medianWinSize) { |
324 window.pop_front(); | 324 window.pop_front(); |
325 } | 325 } |
326 | 326 |
327 int actualSize = window.size(); | 327 int actualSize = int(window.size()); |
328 | 328 |
329 if (type == MajorPitchAdaptivePeaks) { | 329 if (type == MajorPitchAdaptivePeaks) { |
330 if (ymax + halfWin < values.size()) binmax = ymax + halfWin; | 330 if (ymax + halfWin < values.size()) binmax = ymax + halfWin; |
331 else binmax = values.size()-1; | 331 else binmax = values.size()-1; |
332 } | 332 } |
333 | 333 |
334 std::deque<float> sorted(window); | 334 std::deque<float> sorted(window); |
335 std::sort(sorted.begin(), sorted.end()); | 335 std::sort(sorted.begin(), sorted.end()); |
336 float median = sorted[int(sorted.size() * dist)]; | 336 float median = sorted[int(float(sorted.size()) * dist)]; |
337 | 337 |
338 int centrebin = 0; | 338 int centrebin = 0; |
339 if (bin > actualSize/2) centrebin = bin - actualSize/2; | 339 if (bin > actualSize/2) centrebin = bin - actualSize/2; |
340 | 340 |
341 while (centrebin > prevcentre || bin == binmin) { | 341 while (centrebin > prevcentre || bin == binmin) { |
379 percentile = 0.5; | 379 percentile = 0.5; |
380 if (type == MajorPeaks) return 10; | 380 if (type == MajorPeaks) return 10; |
381 if (bin == 0) return 3; | 381 if (bin == 0) return 3; |
382 | 382 |
383 int fftSize = m_server->getFFTSize() >> m_yshift; | 383 int fftSize = m_server->getFFTSize() >> m_yshift; |
384 float binfreq = (float(sampleRate) * bin) / fftSize; | 384 double binfreq = (double(sampleRate) * bin) / fftSize; |
385 float hifreq = Pitch::getFrequencyForPitch(73, 0, binfreq); | 385 double hifreq = Pitch::getFrequencyForPitch(73, 0, binfreq); |
386 | 386 |
387 int hibin = lrintf((hifreq * fftSize) / sampleRate); | 387 int hibin = int(lrint((hifreq * fftSize) / sampleRate)); |
388 int medianWinSize = hibin - bin; | 388 int medianWinSize = hibin - bin; |
389 if (medianWinSize < 3) medianWinSize = 3; | 389 if (medianWinSize < 3) medianWinSize = 3; |
390 | 390 |
391 percentile = 0.5 + (binfreq / sampleRate); | 391 percentile = 0.5f + float(binfreq / sampleRate); |
392 | 392 |
393 return medianWinSize; | 393 return medianWinSize; |
394 } | 394 } |
395 | 395 |
396 FFTModel::PeakSet | 396 FFTModel::PeakSet |
419 } | 419 } |
420 | 420 |
421 int phaseIndex = 0; | 421 int phaseIndex = 0; |
422 for (PeakLocationSet::iterator i = locations.begin(); | 422 for (PeakLocationSet::iterator i = locations.begin(); |
423 i != locations.end(); ++i) { | 423 i != locations.end(); ++i) { |
424 float oldPhase = phases[phaseIndex]; | 424 double oldPhase = phases[phaseIndex]; |
425 float newPhase = getPhaseAt(x+1, *i); | 425 double newPhase = getPhaseAt(x+1, *i); |
426 float expectedPhase = oldPhase + (2.0 * M_PI * *i * incr) / fftSize; | 426 double expectedPhase = oldPhase + (2.0 * M_PI * *i * incr) / fftSize; |
427 float phaseError = princargf(newPhase - expectedPhase); | 427 double phaseError = princarg(newPhase - expectedPhase); |
428 float frequency = | 428 double frequency = |
429 (sampleRate * (expectedPhase + phaseError - oldPhase)) | 429 (sampleRate * (expectedPhase + phaseError - oldPhase)) |
430 / (2 * M_PI * incr); | 430 / (2 * M_PI * incr); |
431 // bool stable = (fabsf(phaseError) < (1.1f * (incr * M_PI) / fftSize)); | 431 // bool stable = (fabsf(phaseError) < (1.1f * (incr * M_PI) / fftSize)); |
432 // if (stable) | 432 // if (stable) |
433 peaks[*i] = frequency; | 433 peaks[*i] = float(frequency); |
434 ++phaseIndex; | 434 ++phaseIndex; |
435 } | 435 } |
436 | 436 |
437 return peaks; | 437 return peaks; |
438 } | 438 } |