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 }