2014-02-18 89 views
6

我收到错误的频率,我不明白为什么我出现错误的值。因为我按照指令进行了计算,接着是计算器。 我已经使用FFT从 http://introcs.cs.princeton.edu/java/97data/FFT.java.html 和复杂的 http://introcs.cs.princeton.edu/java/97data/Complex.java.html使用FFT计算频率中的错误值

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 ...... 请帮我..... 谢谢你..

+2

您应该尝试使用已知合成正弦曲线运行干净的数据。你似乎没有看到数量,所以你的结果可能只是噪音。如果你使用窗口函数,这并不明显。 –

+0

什么是您的采样率和缓冲区大小?你的输入信号是什么样的? – hotpaw2

+0

@克里斯,因为我是新来的DSP,请在编程详解... – Pandian

回答

2

你的源代码几乎没有问题。唯一的问题是您要搜索整个频谱的峰值,即从0到Fs/2到Fs。对于任何实数输入信号(您有),Fs/2和Fs(=采样频率)之间的频谱是0到Fs/2(我找到this nice background explanation)之间的频谱的精确反射镜。因此,对于每个频率存在两个峰值,其幅度几乎相同。我正在写'几乎',因为由于机器精度有限,他们不一定是正好相同。因此,您可以在频谱的前半部分随机找到峰值,该峰值包含低于奈奎斯特频率(= Fs/2)的频率,或者在频谱高于奈奎斯特频率的频谱的后半部分。

如果您想自己纠正错误,请停止阅读此处。否则继续:

只是

for(int j=0;j<=bufferSize/2;j++){ 

在你提供的源代码替换

for(int j=0;j<bufferSize;j++){ 

P.S:通常情况下,最好是到窗口函数适用于分析缓冲液(例如汉明窗),但你的颠峰应用采摘它不会改变结果感到非常。

+0

抱歉的延迟.... 我已经放弃了FFT零棒和零交叉。请参阅此[链接](https://github.com/gast-lib/gast-lib/blob/master/library/src/root/gast/audio/processing/ZeroCrossing.java)。 它在频率检测方面似乎没有太大的区别。如果您有任何建议,请与我分享。谢谢 – Pandian

+0

我会看看链接。同时,你可以接受我的答案,因为很可能你的alg的错误值也是通过镜像谱搜索得到的。其他读者可能会感兴趣。 –

+0

实际上,这种粗略的零交叉分析只适用于谐波相对于基波非常低的情况,并且只有在良好的S/N无线电以及仅分析单声道信号的情况下。在所有其他情况下,估计会变得或多或少。 –