java - 在 java 中录制音频并实时确定是否播放了 x 频率的音调(如果播放)

标签 java audio real-time fft audio-recording

我希望能够使用 java 检测预定频率的音调。我正在做的是播放一个音调(音调的频率因用户输入而异)并且我正在尝试检测该音调是否具有特定频率。如果是,我执行某个方法。从我读到的内容来看,我需要我们进行 FFT,但我不确定如何在 Java 中实现它。似乎有很多关于如何执行此操作的文档,但其中的文档涉及查看音频文件而不是实时分析。我不需要将音频保存到文件中,只需确定是否以及何时记录了频率为 x 的音调。

理想情况下,我想以 44KHz 的采样率进行录制,并在确定是否检测到音调后,确定何时以 +-3ms 的精度检测到音调。但是,只要不是荒谬的(即 +100 毫秒),低于此的精度也是可以接受的。根据我所查找的内容,我大致知道我需要做什么,但我需要帮助将它们联系在一起。使用伪代码它看起来大致像这样(我认为)

请注意,我大致知道在检测到令人满意频率的音调后的 +-1 秒内

for(i = 0, i < 440000 * 2, i++){//*2 because of expected appearance interval;may change
    record sound sample
    fft(sound sample)
    if(frequencySoundSample > x){
        do something
        return
    }
}

播放音调时会有相当大的背景噪音。然而,音调会有一个非常高的频率,比如 15-22KHz,所以我相信只要简单地寻找录音机何时检测到一个非常高的频率,我就可以确定这是我的音调(音调也会用高振幅可能为 0.5 秒或 1 秒)。我知道不会有其他高频声音作为背景噪音(我预计背景频率可能高达 5KHz)。

那我有两个问题。我提供的伪代码是否足以满足我的需求?如果不是,或者如果有更好的方法来做到这一点,我完全赞成。其次,我将如何在 java 中实现它?我明白我需要做什么,但我无法将它们结合在一起。我对 java 相当不错,但我不熟悉与音频相关的语法,而且我对 fft 没有任何经验。请明确并给出带有注释的代码。一段时间以来,我一直在努力解决这个问题,我只需要将它们全部联系在一起即可。谢谢。

编辑

我知道像我这样使用 for 循环不会产生我想要的频率。更多的是粗略地展示我想要的东西。也就是说,随着时间的推移同时记录、执行 fft 和测试频率。

最佳答案

如果您只是寻找特定频率,那么基于 FFT 的方法对于您的特定应用可能不是一个好的选择,原因有二:

  1. 这太过分了 - 您计算整个频谱只是为了检测一个点的幅度

  2. 要获得起始检测的 3 毫秒分辨率,您需要在连续的 FFT 之间有很大的重叠,这将需要比处理连续的样本 block 多得多的 CPU 带宽

检测是否存在单音的更好选择是 Goertzel algorithm(又名 Goertzel 过滤器)。它实际上是在单个频域 bin 上评估的 DFT,广泛用于音调检测。它的计算成本比 FFT 低,实现起来非常简单,而且您可以在每个样本上测试它的输出,因此没有分辨率问题(物理定律规定的除外)。您需要对输出幅度进行低通滤波,然后使用某种阈值检测来确定音调的开始时间。

请注意,SO 上已经有许多关于音调检测和使用 Goertzel 算法(例如 Precise tone onset/duration measurement? )的有用问题和答案 - 我建议阅读这些以及维基百科条目作为一个很好的起点。

关于java - 在 java 中录制音频并实时确定是否播放了 x 频率的音调(如果播放),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18652000/

相关文章:

java - Appium无法启动的问题

java - 需要使用http/2 java发送APNS推送

java - JVM 内部发生了什么,以至于当您在代码中的其他地方调用 Java 中的方法时,调用它的速度变慢了?

java - MIDI 输入的实时解析 - 节奏区分

java - 在java中将时间加在一起

java - OSGI导入包: version vs bundle-version - what's the difference?

android - jPlayer 为 android chrome 预加载音频

javascript - 来自用户麦克风的 WAV 文件与来自文件 : Some difference is causing bugs, 的 WAV 文件,但它们有何不同?

com - 你能阻止 SndVol 显示空的 Audio Session 吗?

real-time - 添加更多节点时,Storm 如何处理字段分组?