如何使用 FFT 从 PCM 获取频率数据
Posted
技术标签:
【中文标题】如何使用 FFT 从 PCM 获取频率数据【英文标题】:How can I get frequency data from PCM using FFT 【发布时间】:2011-09-29 22:18:52 【问题描述】:我有一组要传递给阅读器的音频数据:
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
【问题讨论】:
【参考方案1】:假设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);
【讨论】:
@Ben Taliadoros:这对你有帮助吗?因为我也在努力解决这个问题【参考方案2】:某些详细信息将取决于您的 FFT 的目的。
所需的 FFT 长度取决于您在分析中希望的频率分辨率和时间精度(它们成反比),它们可能接近也可能不接近音频输入缓冲区的长度。鉴于这些长度差异,您可能必须组合多个缓冲区、分割单个缓冲区或两者的某种组合,以获得满足您分析要求的 FFT 窗口长度。
【讨论】:
据我所知,窗口长度仅从我的输出中获取一些值?我是否在此处获取数据峰值以达到频率?谢谢【参考方案3】:PCM 是一种编码数据的技术。它与使用 FFT 对音频数据进行频率分析无关。如果您使用 Java 解码 PCM 编码数据,您将获得原始音频数据,然后可以将其传递到您的 FFT 库。
【讨论】:
我已经尝试过,使用过零方法,我是否必须将通过这种方法得到的数据传递给 FFT?以上是关于如何使用 FFT 从 PCM 获取频率数据的主要内容,如果未能解决你的问题,请参考以下文章