java - 如何对录音应用 FFT 以获得频率?

标签 java android audio fft frequency-analysis

这应该是针对 Android 应用程序的,因此所讨论的语言显然是 Java。 我正在尝试录制一些音频并获得主频率。这是为了一个非常具体的目的,我需要检测的频率是另一个设备发出的纯声音。我已经完成了录音部分,所以我唯一需要做的就是从它生成的缓冲区中计算频率。

我知道我应该使用称为 FFT 的东西,所以我将它们放入我的项目中:http://introcs.cs.princeton.edu/java/97data/FFT.java ,和http://introcs.cs.princeton.edu/java/97data/Complex.java.html

我知道对此有很多问题,但没有一个给出我能理解的答案。其他人的链接已损坏。

有人知道如何做到这一点,并以相对简单的方式解释一下吗?

最佳答案

通常,DFT(包括 FFT)实现将采用 N 个时域样本(您的记录)并在频域中产生 N/2 个复数值。复数值的角度代表相位,其绝对值代表幅度。通常,输出值将从最低频率到最高频率排序。

某些实现可能会输出 N 个复数值,但除非您的输入包含复数值,否则额外的值是多余的。在你的情况下不应该。这就是为什么许多实现输入实数值并输出 N/2 复数值,因为这是 FFT 最常见的用途。

因此,您需要计算输出的绝对值,因为您感兴趣的是振幅。复数的绝对值是实数平方和的平方之和的平方根。这是一个复杂的组件。

每个值的确切频率将取决于输入样本的数量和样本之间的间隔。位置 i 处的值的频率(假设 i 从 0 到 N/2 - 1)将为 i *(采样频率)/N。

这是假设您的 N 是偶数,而不是试图解释 N 是奇数的情况,为了简单起见,我建议您保留 N 为偶数。对于 FFT 的情况,N 始终是 2 的幂,因此 N 始终是偶数。

如果您正在寻找最短时间 T 内的音调,那么我还建议以 T/2 大小的 block 处理输入。

关于java - 如何对录音应用 FFT 以获得频率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41232782/

相关文章:

java - 阻止传入短信

java - 虚拟主机 * :80 is not working

java - 在gradle中的jar命令中使用include和exclude并没有包含所有需要的类

python - 从在线 mp3 文件中读取元数据

java - .net 和 java 的不同 MD5 哈希值

java - 如何从 Firebase 数据库检索图像并将其显示在 RecyclerView 中?

按下主页键时Android停止背景音乐

android - Kotlin DSL 构建脚本依赖更新

Android:如何以最大音量播放音乐?

javascript - 在 HTML 页面中显示音频数据