我的频率错误,我不明白为什么我得到了错误的值。因为我按照指令计算后跟stackoverflow。 我用的是FFT http://introcs.cs.princeton.edu/java/97data/FFT.java.html 和复杂的 http://introcs.cs.princeton.edu/java/97data/Complex.java.html
audioRec.startRecording();
audioRec.read(bufferByte, 0,bufferSize);
for(int i=0;i<bufferSize;i++){
bufferDouble[i]=(double)bufferByte[i];
}
Complex[] fftArray = new Complex[bufferSize];
for(int i=0;i<bufferSize;i++){
fftArray[i]=new Complex(bufferDouble[i],0);
}
FFT.fft(fftArray);
double[] magnitude=new double[bufferSize];
for(int i=0;i<bufferSize;i++){
magnitude[i] = Math.sqrt((fftArray[i].re()*fftArray[i].re()) + (fftArray[i].im()*fftArray[i].im()));
}
double max = 0.0;
int index = -1;
for(int j=0;j<bufferSize;j++){
if(max < magnitude[j]){
max = magnitude[j];
index = j;
}
}
final int peak=index * sampleRate/bufferSize;
Log.v(TAG2, "Peak Frequency = " + index * sampleRate/bufferSize);
handler.post(new Runnable() {
public void run() {
textView.append("---"+peak+"---");
}
});
我得到的价值如21000,18976,40222,30283等...... 请帮我..... 谢谢..
答案 0 :(得分:2)
您的源代码几乎没问题。唯一的问题是你在整个频谱中搜索峰值,即从0到Fs / 2到Fs。
对于任何实值输入信号(你有),Fs / 2和Fs之间的频谱(=采样频率)是0和Fs / 2之间频谱的精确镜像(我发现this nice background explanation) 。因此,对于每个频率,存在两个具有 几乎 相同幅度的峰值。我写'差不多'是因为由于机器精度有限,它们不一定 完全 相同。因此,您可以随机找到频谱上半部分的峰值,其中包含低于奈奎斯特频率(= Fs / 2)的频率,或频谱高于奈奎斯特频率的频谱的后半部分。
如果您想自己纠正错误,请在此处阅读。否则继续:
只需替换
for(int j=0;j<bufferSize;j++){
与
for(int j=0;j<=bufferSize/2;j++){
在您提供的源代码中。
P.S。:通常情况下,最好将窗口函数应用于分析缓冲区(例如汉明窗口),但对于峰值拾取的应用,它不会对结果产生太大影响。