繁体   English   中英

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

[英]Using gdx Library and FFT to Calculate Frequency (Java)

我目前正在使用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]));

检查此链接以获取更多信息: 如何从fft结果中获取频率?

奈奎斯特定理

...指出只有采样数增加一倍,您才能完美地重构频率。...要重构1000Hz,每秒至少必须有2000个采样。 (但此波将非常失真。)。

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

如果您想确定您的N, 请查看此答案或更多Google。 尝试以任意数字开始,例如采样率fs的十分之一。 N越大,算法就越慢。

音符频率表

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

麦克风输入

Google up关键字,例如Java麦克风输入库教程,或查看此答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM