如何使用FFT从PCM获得频率数据?



我有一个音频数据数组,我传递给阅读器:

 recorder.read(audioData,0,bufferSize); 

实例化如下:

AudioRecord recorder;
short[] audioData;
int bufferSize;
int samplerate = 8000;
//get the buffer size to use with this audio record
bufferSize = AudioRecord.getMinBufferSize(samplerate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT)*3;
//instantiate the AudioRecorder
recorder = new AudioRecord(AudioSource.MIC,samplerate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,bufferSize); 
recording = true; //variable to use start or stop recording
audioData = new short [bufferSize]; //short array that pcm data is put into.

我有一个我在网上找到的FFT类和一个复杂的类。我已经尝试了两天到处上网寻找,但无法解决如何循环通过存储在audioData中的值并将其传递给FFT。

这是我使用的FFT类:http://www.cs.princeton.edu/introcs/97data/FFT.java这是一个复杂的类:http://introcs.cs.princeton.edu/java/97data/Complex.java.html

假设audioData数组包含原始音频数据,您需要从audioData数组创建一个Complex[]对象,如下所示:

Complex[] complexData = new Complex[audioData.length];
for (int i = 0; i < complexData.length; i++) {
    complextData[i] = new Complex(audioData[i], 0);
}

现在你可以把你的complexData对象作为参数传递给FFT函数:

Complex[] fftResult = FFT.fft(complexData);

一些细节将取决于FFT的目的。

所需FFT的长度取决于您在分析中希望的频率分辨率和时间精度(它们是负相关的),这可能会或可能不会接近音频输入缓冲区的长度。考虑到这些长度上的差异,您可能必须组合多个缓冲区,分割单个缓冲区,或者两者的某种组合,以获得满足您分析需求的FFT窗口长度。

PCM是对数据进行编码的技术。这与使用FFT对音频数据进行频率分析无关。如果你使用Java来解码PCM编码的数据,你会得到原始的音频数据,然后可以传递到你的FFT库。

最新更新