gpt4 book ai didi

java - 使用 gdx 库和 FFT 计算频率 (Java)

转载 作者:行者123 更新时间:2023-11-30 11:25:48 31 4
gpt4 key购买 nike

我目前正在使用 gdx 库 com.badlogic.gdx.audio.analysis.FFT 和方法:

private float[] fft(int N, int fs, float[] array) {
float[] fft_cpx, tmpr, tmpi;
float[] res = new float[N / 2];
// float[] mod_spec =new float[array.length/2];
float[] real_mod = new float[N];
float[] imag_mod = new float[N];
double[] real = new double[N];
double[] imag = new double[N];
double[] mag = new double[N];
double[] phase = new double[N];
float[] new_array = new float[N];
// Zero Pad signal
for (int i = 0; i < N; i++) {
if (i < array.length) {
new_array[i] = array[i];
}
else {
new_array[i] = 0;
}
}

FFT fft = new FFT(N, 8000);

fft.forward(new_array);
fft_cpx = fft.getSpectrum();
tmpi = fft.getImaginaryPart();
tmpr = fft.getRealPart();
for (int i = 0; i < new_array.length; i++) {
real[i] = (double) tmpr[i];
imag[i] = (double) tmpi[i];

mag[i] = Math.sqrt((real[i] * real[i]) + (imag[i] * imag[i]));
phase[i] = Math.atan2(imag[i], real[i]);

/**** Reconstruction ****/
real_mod[i] = (float) (mag[i] * Math.cos(phase[i]));
imag_mod[i] = (float) (mag[i] * Math.sin(phase[i]));

}
fft.inverse(real_mod, imag_mod, res);
return res;

}

然后如何使用此方法找到从麦克风录制的声音的频率(然后是音符)?

最佳答案

您的目标是获取 mag[i] 中各个频率的所有大小并找到最大的一个。首先,您可以遍历它们并找到最大的 mag[i]。然后你必须从 i 索引重新计算它的相应频率。

频率由这个等式决定:

freq = i * Fs / N;

Fs 是您的时域数据(输入波形数据)的采样频率,N - 您计算 FFT 的样本数。 i 是您的频域数据(计算的幅度和相位)的索引

在你的情况下,你可以在你的 for 循环中添加一行来调试它:

double freq = (double)i*(double)fs/(double)N;
System.out.println("Frequency: "+ Double.toString(freq) + "Magnitude: "+ Double.toString(mag[i]));

查看此链接以获取更多信息: How to get frequency from fft result?

Nyquist theorem

...声明只有在样本数量翻​​倍的情况下才能完美地重建频率...要重建 1000Hz,每秒必须至少有 2000 个样本。 (不过这个波会很扭曲。)。

如果您的采样率为 22000Hz,您将能够以某种方式测量高达 11000Hz 的频率。 magphase 中的数据对数组 0..N/2 的前半部分有意义,然后,您将看到先前数据的镜像(有关图片,请参阅 wikipedia page 的链接。)

如果你想确定你的N check this answer或谷歌更多。尝试从任意数字开始,例如采样率 fs 的十分之一。 N 越大,您的算法就越慢。

Table of note frequencies

最简单的方法是制作一张包含您将检测到的所有频率的表格,然后将您的频率与最大幅度与表格中的所有频率值进行比较。具有较小的公差,例如表中值的 +-2%。确保两个连续音符的公差不重叠。

麦克风输入

Google 搜索关键字,如 java 麦克风输入库教程,或查看 this answer .

关于java - 使用 gdx 库和 FFT 计算频率 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20131442/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com