Java 用FFT计算频率时的错误值

Java 用FFT计算频率时的错误值,java,audio,signal-processing,fft,Java,Audio,Signal Processing,Fft,我得到了错误的频率,我不明白为什么我得到了错误的值。因为我已经按照stackoverflow后面的说明进行了计算。 我用的是FFT 复杂的 audioRec.startRecording(); audioRec.read(缓冲字节,0,缓冲大小); 对于(inti=0;i来说,您的源代码几乎没有问题。唯一的问题是,您要在整个频谱中搜索峰值,即从0到Fs/2到Fs 对于任何实值输入信号(您有),Fs/2和Fs(=采样频率)之间的频谱是0和Fs/2之间频谱的精确镜像(我发现)。因此,对于每个频率,

我得到了错误的频率,我不明白为什么我得到了错误的值。因为我已经按照stackoverflow后面的说明进行了计算。 我用的是FFT 复杂的

audioRec.startRecording();
audioRec.read(缓冲字节,0,缓冲大小);

对于(inti=0;i来说,您的源代码几乎没有问题。唯一的问题是,您要在整个频谱中搜索峰值,即从0到Fs/2到Fs

对于任何实值输入信号(您有),Fs/2和Fs(=采样频率)之间的频谱是0和Fs/2之间频谱的精确镜像(我发现)。因此,对于每个频率,都存在两个振幅几乎相同的峰值。我之所以写“几乎”,是因为由于机器精度有限,它们不一定完全相同。因此,你可以在频谱的前半部分随机找到峰值,其中包含低于奈奎斯特频率的频率(=Fs/2)或在频谱的后半部分,频率高于奈奎斯特频率

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

替换

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

用于(int j=0;j你应该试着用已知的合成正弦波在干净的数据上运行。你似乎不看幅度,所以你的结果可能只是噪声。如果你使用的是窗口函数,这并不明显。你的采样率和缓冲区大小是什么?你的输入信号是什么样子?@chris因为我是dsp新手,请在pr中解释编程…放下麦克风,用计算出的可配置频率的正弦波进行实验,直到得到正确的结果。当你可以恢复时,显示幅度,并注意检测到的幅度如何随频率变化,即使输入是恒定的…要解决这一问题,请阅读窗口函数。@ChrisStratton是计算正弦波的方法。'缓冲区大小=4096;样本大小=44100;用于(int i=0;我为延迟担心…我已放弃FFT并坚持过零。请参考此。频率检测方面似乎没有重大差异。如果您有任何建议,请与我分享。谢谢。我将查看链接。同时,您可以接受我的回答,因为很可能是由于s导致的alg值错误通过镜像频谱进行搜索。其他读者可能会感兴趣。事实上,这种粗略的过零分析只有在谐波与基波相比非常低的情况下才有效,并且只有在良好的S/N无线电条件下,并且只有在分析单声道信号的情况下才有效。在所有其他情况下,估计值或多或少会变差。谢谢太多了。我试过了,但还是有很多噪音。请解释清楚。用这里描述的基于FFT的提取,还是这些评论中的过零?
for(int j=0;j<bufferSize;j++){
for(int j=0;j<=bufferSize/2;j++){