在java中录制音频,并确定如果x频率的声音,如果这样做有什么东西在发挥实时 [英] record audio in java and determine real time if a tone of x frequency was played if so do something

查看:797
本文介绍了在java中录制音频,并确定如果x频率的声音,如果这样做有什么东西在发挥实时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够检测到使用Java predetermined频率的声音。什么我做的是打了音调(音调的频率可变由用户输入),我试图来检测,如果语气一定频率的。如果是的,我执行一定的方法。从我读过,我需要给我们FFT,但我不知道如何实现它在Java。似乎有很多关于如何做到这一点的文档,但什么文件也涉及到查找的音频文件,而不是实时分析。我并不需要保存音频文件只是确定是否以及何时频率x的音调被记录。

I want to be able to detect a tone of a predetermined frequency using java. What I am doing is playing a tone (the frequency of the tone is variable by user input) and I am trying to detect if the tone is of a certain frequency. If it is, I execute a certain method. From what I have read I will need to us FFT, but I'm not sure how to implement it in java. There seems to be a lot of documentation for how to do it, but what documentation there is involves looking at an audio file rather than real time analysis. I don't need to save the audio to a file just determine if and when a tone of frequency x was recorded.

理想情况下,我想在44KHz的采样率,并确定是否检测到了音调,确定与+ -3ms的精度检测到音调时后进行记录。然而,低于此的精度将只要是可以接受的,因为它不是荒谬(即+ 100毫秒)。我大概知道我需要什么,从我所抬头做,但我需要帮助绑到一起。使用伪code将大致如下(我认为)

Ideally I would like to record at a sample rate of 44KHz and after determining if a tone was detected, determine when the tone was detected with an accuracy of +-3ms. However, an accuracy less than this would be acceptable as long as it isn't ridiculous (ie +100ms). I know roughly what I need to do from what I have looked up, but I need help tying it all together. Using pseudo code it would look roughly like this (I think)

请注意,我大致知道在+ -1s满足时频率的声音,也许检测

Note that I know roughly within +-1s of when a tone of satisfying frequency maybe detected

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,所以我相信,通过简单地寻找时,录音机检测到一个很高的频率我可以肯定这是我的音(也基调将与播放高振幅为说不定.5s或1)。我知道,不会有其他高频率的声音作为背景噪声(我期待也许为5KHz的背景频率高)。

There will be considerable background noise while the tone is played. However the tone will have a very high frequency, like 15-22KHz, so it is my belief that by simply looking for when the recorder detects a very high frequency I can be sure it is my tone (also the tone will be played with a high amplitude for maybe .5s or 1s). I know that there will not be other high frequency sounds as background noise (I am expecting a background frequency high of maybe 5KHz).

我有两个问题即可。是,我已经提供了足够的什么我想要做的伪code?如果不是,或是否有这样做,我为这一切的更好的方法。其次,我将如何在Java中实现这一点?我明白我需要做的,但我有麻烦绑到一起。我是pretty体面与Java,但我不熟悉的涉及音频的语法和我没有与任何FFT经验。请明确,给code。与评论。我一直在试图弄清楚这一点了,而我只需要看到这一切绑在一起。谢谢你。

I have two questions then. Is the pseudo code that I have provided sufficient for what I want to do? If it isn't or if there is a better way of doing this I'm all for it. Second, how would I implement this in java? I understand what I need to do, but I'm having trouble tying it all together. I'm pretty decent with java but I'm not familiar with the syntax involved with audio and I don't have any experience with fft. Please be explicit and give code with comments. I've been trying to figure this out for a while I just need to see it all tied together. Thank you.

修改

据我了解,使用for循环像我有不会产生我想要的频率。这是更粗略我想要的显示。也就是说,记录,进​​行FFT和测试频率一下子随着时间的推移。

I understand that using a for loop like I have will not produce the frequency that I want. It was more to show roughly what I want. That is, recording, performing fft, and testing the frequency all at once as time progresses.

推荐答案

如果你只是寻找一个特定的频率,然后基于FFT的方法可能是为具体应用一个不错的选择,原因有二:

If you're just looking for a specific frequency then an FFT-based method is probably a bad choice for your particular application, for two reasons:


  1. 这是矫枉过正 - 你的计算整个频谱只是在一个点上检测到的震级

  1. it's overkill - you're computing an entire spectrum just to detect the magnitude at one point

拿到3毫秒的分辨率为您的起始点检测则需要连续的FFT之间有很大的重叠,这将需要远远超过CPU带宽只是处理样品的连续块

to get 3 ms resolution for your onset detection you'll need a large overlap between successive FFTs, which will require much more CPU bandwidth than just processing successive blocks of samples

用于检测单音的presence或没有更好的选择是 Goertzel算法(又名戈泽尔过滤器)。这是有效地在单一频率域仓评估一个DFT,并且被广泛地用于音频检测。它的的低计算比FFT昂贵的,很简单的实现,并且可以测试其对每个样品产出,所以没有解决的问题(比由物理定律决定的除外)。您需要低通滤波器输出的大小,然后使用某种类型的阈值检测,以确定你的音色的起效时间。

A better choice for detecting the presence or absence of a single tone is the Goertzel algorithm (aka Goertzel filter). It's effectively a DFT evaluated at a single frequency domain bin, and is widely used for tone detection. It's much less computationally expensive than an FFT, very simple to implement, and you can test its output on every sample, so no resolution problem (other than those dictated by the laws of physics). You'll need to low pass filter the magnitude of the output and then use some kind of threshold detection to determine the onset time of your tone.

请注意,有一些对SO已经有大约音调检测,并使用Goertzel算法(如<一个有用的问题和答案href=\"http://stackoverflow.com/questions/4456855/$p$pcise-tone-onset-duration-measurement/4461542#4461542\">$p$pcise发病音/持续时间测量) - 我建议与维基百科条目是一个很好的起点,沿着读这些

Note that there are a number of useful questions and answers on SO already about tone detection and using the Goertzel algorithm (e.g. Precise tone onset/duration measurement?) - I suggest reading these along with the Wikipedia entry as a good starting point.

这篇关于在java中录制音频,并确定如果x频率的声音,如果这样做有什么东西在发挥实时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆