Contour<float> DioF0Estimator::estimate(const Signal &signal, double msFramePeriod) { int decimationRatio = qMax(1, qMin(12, (int)(signal.samplingFrequency() / decimatedFs))); int decimatedLength = 1 + signal.size() / decimationRatio; fft = new Fft(Fft::suitableLength(decimatedLength), Fft::Real); Spectrum decimatedSpectrum(createDecimatedSpectrum(signal, decimationRatio)); Contour<float> result(estimate(decimatedSpectrum, signal.size(), signal.samplingFrequency(), msFramePeriod)); delete fft; return result; }
DioF0Estimator::Spectrum DioF0Estimator::createDecimatedSpectrum(const Signal &signal, int decimationRatio) { int decimatedLength = 1 + signal.size() / decimationRatio; int fftLength = fft->fftLength; double *decimatedWave = new double[fftLength]; Decimator::decimate(signal, decimationRatio, decimatedWave, decimatedLength); double mean = 0.0; for(int i = 0; i < decimatedLength; i++) { mean += decimatedWave[i]; } mean /= decimatedLength; for(int i = 0; i < decimatedLength; i++) { decimatedWave[i] -= mean; } for(int i = decimatedLength; i < fftLength; i++) { decimatedWave[i] = 0.0; } fft->execute(Fft::Forward, decimatedWave); return Spectrum(decimatedWave, decimatedLength, fftLength, (double)signal.samplingFrequency() / decimationRatio); }