我正在做一个从录音机返回基频的Android项目。 我用FFT类来计算频率:
http://introcs.cs.princeton.edu/java/97data/FFT.java
和Complex Array来自:
http://introcs.cs.princeton.edu/java/97data/Complex.java.html
这是我计算频率的代码:
public double calculateFFT(byte[] signal)
{
final int mNumberOfFFTPoints =1024;
double mMaxFFTSample;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
double[] absSignal = new double[mNumberOfFFTPoints/2];
for(int i = 0; i < mNumberOfFFTPoints; i++){
temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
complexSignal[i] = new Complex(temp,0.0);
}
y = FFT.fft(complexSignal);
mMaxFFTSample = 0.0;
int mPeakPos = 0;
for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
{
absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));
if(absSignal[i] > mMaxFFTSample)
{
mMaxFFTSample = absSignal[i];
mPeakPos = i;
}
}
return ((1.0 * sampleRate) / (1.0 * mNumberOfFFTPoints)) * mPeakPos;
}
其中sampleRate = 44100且mNumberOfFFTPoints = 1024。从这段代码中我读了很多值,但是我 想要得到唯一的基频,所以只有价值。你能帮我理解这个算法吗?
答案 0 :(得分:1)
通常,音乐或语音的基频检测非常重要。话虽如此,根据您的来源,您可以简化问题。
例如,如果您的来源是一个人唱一个音符,录音中没有音乐或其他背景声音,修改后的峰值探测器可能会给出合理的结果。
下图显示了持有B-flat-3(Bb3)音符的女高音的频谱。 Bb3的基频是233赫兹,但女高音实际上是一个236赫兹的基音(最左边和最高峰)。
下图显示了持有F4音符的女高音的频谱。 F4的基频是349赫兹,但女高音实际上是在演唱一个360赫兹的基音(最左边的峰值)。
然而,上图还显示了基频检测的挑战之一。在这种情况下,最高峰不是基波,而是714 Hz的一次谐波。您修改后的峰值检测器必须与这些情况相抗衡。
其他可能性是倒谱分析和自相关 见这些参考文献: Fundamental frequency detection /// Speech Signal Analysis
的FFT,图表和音频数据