FFT 频率分析似乎得到了错误的值

Posted

技术标签:

【中文标题】FFT 频率分析似乎得到了错误的值【英文标题】:FFT frequency analysis seems to get wrong values 【发布时间】:2013-11-12 14:10:34 【问题描述】:

我在这里看到很多关于频率分析的帖子,似乎对我有很大帮助, 但是我试图记录我的声音并打印出频率,似乎这些值没有关系 对于录制的内容,尝试上下提高我的音高以查看频率值会发生什么, 但是您可以在发布的 logcat 中看到打印的频率有自己的意愿,可能是背景噪音的原因:)

这是我如何获得频率的代码:

fftArray = FFT.fft(fftTempArray);

MAX = 0;
int index= 0;
for (int i = 0; i < fftArray.length/2; i++)    
    if (fftArray[i].magnitudes() > MAX) 
        MAX = fftArray[i].magnitudes();
        index = i;                      
    
    double freq = index * sampleFreq / fftArray.length;
    System.out.println(freq);

这里是日志:

11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:40.678: I/System.out(23397): 150.0
11-12 16:01:41.409: I/System.out(23397): 0.0
11-12 16:01:41.409: I/System.out(23397): 0.0
11-12 16:01:41.409: I/System.out(23397): 0.0
11-12 16:01:41.409: I/System.out(23397): 0.0
11-12 16:01:41.409: I/System.out(23397): 0.0
11-12 16:01:41.409: I/System.out(23397): 0.0
11-12 16:01:41.409: I/System.out(23397): 64.0
11-12 16:01:41.409: I/System.out(23397): 75.0
11-12 16:01:41.409: I/System.out(23397): 75.0
11-12 16:01:41.409: I/System.out(23397): 75.0
11-12 16:01:41.419: I/System.out(23397): 107.0
11-12 16:01:41.419: I/System.out(23397): 118.0
11-12 16:01:41.419: I/System.out(23397): 118.0
11-12 16:01:41.419: I/System.out(23397): 118.0
11-12 16:01:41.419: I/System.out(23397): 118.0
11-12 16:01:41.419: I/System.out(23397): 161.0
11-12 16:01:41.419: I/System.out(23397): 161.0
11-12 16:01:41.419: I/System.out(23397): 161.0
11-12 16:01:41.419: I/System.out(23397): 161.0

无论我做什么,它都保持在这个值范围内。

有人可以帮忙吗? 当我向麦克风发出高音或不同类型的噪音时,频率怎么会没有变化?

【问题讨论】:

你转换成极坐标了吗?我不明白你的日志输出应该是什么。 你的日志很奇怪,为什么在循环中? 您使用的库是什么?你自己的还是其他地方的?返回的数组是什么?我认为您确实没有提供足够的信息来判断问题所在(如果有的话)。 我的日志在循环中,因为我在我的应用程序中不断记录,所以记录在循环中并且它打印出值..关于我正在使用的库,我接受了来自网络并通过多个来源进行了检查,因此问题不存在。 【参考方案1】:

您错误地将 FFT 索引转换为倒数第二行代码中的频率。应该是:

double freq = index * sampleFreq * 2 / fftArray.length;

除此之外,您的代码很好(据我所知)。尝试通过代码运行一些测试数据并通过麦克风运行一些测试音频来隔离错误。 Audacity 是一个非常有用的程序,可以查看音频的频谱图,顺便说一句。

请记住,如果您的采样率对您正在分析的频率施加了限制。这可能就是您的值似乎保持在该范围内的原因

【讨论】:

从 OP 的 for 循环如何从 0 运行到 fftArray.length / 2 来判断,我假设变换没有丢弃负频率。在这种情况下,它们不应将频率加倍。 该示例中的当前采样率为 44100,所以应该没问题,我不确定将频率加倍意味着什么。我发现很难弄清楚为什么会发生这种情况,尝试将特定频率放在麦克风旁边以查看偏差,但没有运气...... @Radiodef 你说得对,但我不知道有多少转换可以做到这一点。如果这样做,从技术上讲,这将是 FFT 的错误实现。在任何一种情况下,您仍然会遍历循环 fftArray.length/2 次​​span> 【参考方案2】:

您可能会将音高与频谱的峰值混淆。尽管它们都具有相同的维度单位 (Hz),但音高是一种心理声学现象,它可能与频谱峰值非常不同(这通常是音高更高且不断变化的泛音,有时是轻微的不和谐等)。因此,基音检测/估计方法不同于 FFT 频率峰值估计。

【讨论】:

好吧,我可能会感到困惑,如果我发出更高的声音,频率不是应该更高吗?因为它每秒的声波振动。我当然知道我的音调变化,但频率也应该改变/ 如果您在几个时间点绘制整个频谱,这里的可能点就会变得很清楚。只看最强的峰可能会产生误导。 @Er85 :不,峰值频率可以降低,从而产生更高音调的声音。例如,峰值可能是一个非常不同(低得多)的泛音。

以上是关于FFT 频率分析似乎得到了错误的值的主要内容,如果未能解决你的问题,请参考以下文章

如何正确 FFT 声音阵列?

FFT后如何得到幅度和对应的频率

MATLAB中fft的频率轴怎么计算

基于MATLAB的FFT傅立叶分析

更改块大小会导致 FFT 分析失败

在进行 FFT 和改变频率分量值之后,我只会在音频中得到噪音。我哪里错了?