Ben*_*ros 29 java android fft pcm
我在我的Android手机上录制了麦克风数据[1024]数据,通过实际数据的1D前向DFT(再设置1024位为0).我将数组保存到文本文件中,并重复了8次.
我收到了16384的结果.我在Excel中打开了文本文件并制作了一个图表以查看它的外观(x =数组索引,y =返回的数字大小).有大量的尖峰(正面和负面)大约在110,232左右,并且小尖峰继续以这种方式持续到1817年和1941年左右,尖峰再次变大,然后再次下降.
我的问题是,无论我在哪个主题上寻求帮助,它都会提到实数和虚数,我只有一维数组,我从Piotr Wendykier的类中使用的方法得到了回复:
DoubleFFT_1D.realForwardFull(audioDataArray); // from the library JTransforms.
Run Code Online (Sandbox Code Playgroud)
我的问题是:我需要对此数据做什么才能返回频率?录制的声音是我在吉他的底弦(第五音品)上演奏'A'(大约440Hz).
Pau*_*l R 47
复数数据是交错的,偶数索引处的实数分量和奇数索引处的虚数分量,即实数分量处于索引处2*i,虚部处于索引处2*i+1.
要获得索引i处的频谱幅度,您需要:
re = fft[2*i];
im = fft[2*i+1];
magnitude[i] = sqrt(re*re+im*im);
Run Code Online (Sandbox Code Playgroud)
然后,您可以绘制i = 0到N/2的幅度[i]以获得功率谱.根据音频输入的性质,您应该在频谱中看到一个或多个峰值.
要获得任何给定峰值的近似频率,您可以转换峰值索引,如下所示:
freq = i * Fs / N;
Run Code Online (Sandbox Code Playgroud)
哪里:
freq = frequency in Hz
i = index of peak
Fs = sample rate (e.g. 44100 Hz or whatever you are using)
N = size of FFT (e.g. 1024 in your case)
Run Code Online (Sandbox Code Playgroud)
注意:如果您之前没有对时域输入数据应用合适的窗口函数,那么您将获得一定量的频谱泄漏,并且功率谱看起来相当"模糊".
为了进一步扩展,这里有一个伪代码,用于我们获取音频数据并识别最大峰值频率的完整示例:
N = 1024 // size of FFT and sample window
Fs = 44100 // sample rate = 44.1 kHz
data[N] // input PCM data buffer
fft[N * 2] // FFT complex buffer (interleaved real/imag)
magnitude[N / 2] // power spectrum
capture audio in data[] buffer
apply window function to data[]
// copy real input data to complex FFT buffer
for i = 0 to N - 1
fft[2*i] = data[i]
fft[2*i+1] = 0
perform 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 spectrum
max_magnitude = -INF
max_index = -1
for i = 0 to N / 2 - 1
if magnitude[i] > max_magnitude
max_magnitude = magnitude[i]
max_index = i
// convert index of largest peak to frequency
freq = max_index * Fs / N
Run Code Online (Sandbox Code Playgroud)