如何从fft结果中获取频率?

我已经在Android手机上记录了来自麦克风的数据数组[1024],并将其通过真实数据的一维前向DFT传递(将另外的1024位设置为0)。我将数组保存到文本文件,并重复了8次。


我得到了16384个结果。我在Excel中打开了文本文件,并制作了图表以查看其外观(x =数组的索引,y =返回的数字的大小)。在110、232左右有一些巨大的峰值(正负),小峰值以这种方式持续,直到1817年和1941年左右,峰值再次变大,然后再次下降。


我的问题是,无论何时我在涉及实数和虚数的话题上寻求帮助时,我只有一个一维数组,这是我从Piotr Wendykier的课程所使用的方法中获得的:


DoubleFFT_1D.realForwardFull(audioDataArray); // from the library JTransforms.

我的问题是:我需要对这些数据做些什么来返回频率?录制的声音是我在吉他的底部弦(第5品格)(大约440Hz)上演奏“ A”。


PIPIONE
浏览 1366回答 2
2回答

富国沪深

复杂数据被交织,实数分量在偶数索引处,虚分量在奇数索引处,即实数分量在索引处2*i,虚分量在索引处2*i+1。要获得索引i处的频谱幅度,您需要:re = fft[2*i];im = fft[2*i+1];magnitude[i] = sqrt(re*re+im*im);然后,可以针对i = 0至N / 2绘制幅度[i],以获得功率谱。根据音频输入的性质,您应该在频谱中看到一个或多个峰值。要获得任何给定峰的近似频率,可以按如下所示转换峰的索引:freq = i * Fs / N;哪里:freq = frequency in Hzi = index of peakFs = sample rate (e.g. 44100 Hz or whatever you are using)N = size of FFT (e.g. 1024 in your case)注意:如果您之前未在时域输入数据上应用合适的窗口函数,则将获得一定量的频谱泄漏,并且功率谱看起来会“被抹上”。为了进一步扩展,下面是一个完整示例的伪代码,其中我们获取音频数据并确定最大峰值的频率:N = 1024          // size of FFT and sample windowFs = 44100        // sample rate = 44.1 kHzdata[N]           // input PCM data bufferfft[N * 2]        // FFT complex buffer (interleaved real/imag)magnitude[N / 2]  // power spectrumcapture audio in data[] bufferapply window function to data[]// copy real input data to complex FFT bufferfor i = 0 to N - 1  fft[2*i] = data[i]  fft[2*i+1] = 0perform in-place complex-to-complex FFT on fft[] buffer// calculate power spectrum (magnitude) values from fft[]for i = 0 to N / 2 - 1  re = fft[2*i]  im = fft[2*i+1]  magnitude[i] = sqrt(re*re+im*im)// find largest peak in power spectrummax_magnitude = -INFmax_index = -1for i = 0 to N / 2 - 1  if magnitude[i] > max_magnitude    max_magnitude = magnitude[i]    max_index = i// convert index of largest peak to frequencyfreq = max_index * Fs / N

皈依舞

fft上面示例中的数组是FFT例程的输出。该magnitude数组是第二个数组,您可以在其中根据复数FFT输出值计算幅度。
打开App,查看更多内容
随时随地看视频慕课网APP