record audio in java and determine real time if a tone of x frequency was played if so do something

后端 未结 2 788
一向
一向 2021-01-23 04:17

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 try

相关标签:
2条回答
  • 2021-01-23 04:30

    Im actually working on a similar project with pitch detection, in Java as well. If you want to use FFT, you could do it with these steps. Java has a lot of libraries that can make this process easy for you.

    First, you need to read in the sound file. This can be done using Java Sound. It's a built in library with functions that make it easy to record sound. Examples can be found here. The default sample rate is 44,100 KHz (CD quality). These examples can get you from playing the actual tone to a double array of bytes representing the tone.

    Second, you should take the FFT with JTransforms. Here is an example of FFT being taken on a collection of samples.

    FFT gives you an array twice the length of the array of samples you passed it. You need to go through the FFT array by two's, since each part of this array is represented as an imaginary and a real piece. Compute the magnitude of each part of this array with sqrt(im^2 + re^2). Then, find which magnitude is the largest. The index of that magnitude corresponds to the frequency you're looking for.

    Keep in mind, you don't take FFT on the entire portion of sound. You break the sound up into chunks, and FFT each one. The chunks can overlap for higher accuracy, but that shouldn't be a problem, since you're just looking for a predetermined note. If you want to improve performance, you can also window each chunk before doing this.

    Once you have all the FFTs, they should confirm a certain frequency, and you can check that against the note you want.

    If you want to try and visualize this, I'd suggest using JFreeChart. It's another library that makes it easy to graph things.

    0 讨论(0)
  • 2021-01-23 04:41

    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. it's overkill - you're computing an entire spectrum just to detect the magnitude at one point

    2. 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

    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.

    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.

    0 讨论(0)
提交回复
热议问题