在Java中,如何将快速傅里叶变换(FFT)的输入和输出用于分析音频文件的频率?

10

我需要使用FFT来分析音频文件的频率。但是我不知道输入和输出应该是什么。

如果我想绘制频谱的音频文件,我应该使用一维、二维还是三维数组?有没有人能够建议我在J2ME上使用的FFT库?

3个回答

35

@thongcaoloi,

关于您输入数据的维数,简单答案是:您需要1D数据。现在我将解释一下这是什么意思。

由于您要分析音频数据,您将离散傅里叶变换(DFT或FFT)的输入作为表示音频信号电压随时间变化的一维实数序列,而您的音频文件是该随时间变化的电压的数字表示。

您的音频文件是通过以固定采样率(也称为采样频率)对连续音频信号的电压进行采样而产生的,通常是44.1 KHz的CD质量音频。

但是您的数据文件可能已经以更低的采样频率进行了采样,因此在对该数据进行FFT之前,请尝试查找其采样频率。

因此,现在您需要从音频文件中提取单独的样本。如果您的文件是立体声,则会有两个单独的样本序列,一个用于右声道,一个用于左声道。如果该文件是单声道,则只会有一个样本序列。

如果您的文件是立体声或任何其他多声道音频格式,例如5.1或7.1,则可以分别对每个声道进行FFT,或者使用电压加法将任意数量的声道组合在一起。这取决于您要对FFT结果进行的操作。

DFT或FFT的输出是一系列复数。每个复数都是由实部和虚部组成的一对,通常表示为(re,im)。

如果您想绘制音频文件的功率谱密度(大多数人所需的FFT),则将使用FFT输出的前N / 2个复数,并绘制20 * log10(sqrt(re ^ 2 + im ^ 2))。

您可以尝试构建自己的频谱分析软件程序,但我建议使用已经构建和测试的软件。

这两个FFT频谱分析仪可以立即给出结果,并具有内置的逆傅里叶变换综合功能,这意味着您可以将频域谱数据逆变换回时间域以重建原始信号。

http://www.mathworks.com/help/techdoc/ref/fft.html

http://www.sooeet.com/math/fft.php

这个话题有很多内容,而数字信号处理的主题也一样,但这篇简短介绍可以让您开始学习。


4
理论意义上,FFT将复数[N]=>复数[N]。但是,如果你的数据只是音频文件,则你的输入将仅为没有虚部的复数。因此,你将把实数[N]=>复数[N]。然而,通过一些数学计算,你会发现输出格式总是output[i]==complex_conjugate(output[N-i])。因此,你只需要查看前N/2+1个样本即可。此外,FFT的复杂输出提供关于相位和幅度的信息。如果你只关心在你的音频中有多少某种频率,你只需要查看每个输出元素的幅度,它可以被计算为square_root(imaginary^2+real^2)。
当然,你需要查看你使用的库的文档,以了解哪个数组元素对应于第N个复杂数组输出的实部,同样地,找到第N个复杂数组输出的虚部。

1

我记得FFT算法并不是很复杂,我曾经为我的论文编写了一个FFT计算类。当时输入是从*.WAV文件中读取的一维值数组。但在进行FFT之前,还进行了一些滤波和归一化处理。


谢谢帮助。您可以告诉我输出是一个值还是一个数组吗?你可以分享给我FFT的源代码吗?非常感谢! - thongcaoloi
1
我必须查看我的备份硬盘是否还有那段代码,那是很久以前的事了。请给我发一封电子邮件提醒我。 - user591593

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接