Exocortex FFT无法得到预期输出

3

我正在使用Exocortex.DSP C#库,但是它没有给我期望的输出。我不确定为什么会这样。在这个例子中我使用的音频文件是一个16位无符号的纯800Hz波形的.wav文件。在Audacity中,我可以看到它只是一个单独的正弦波。我使用NAudio将文件作为byte[]读入,然后使用BitConverter.Single进行转换。在对数组运行Fourier.FFT之后,我期望在samples[800]处看到显著的数据,并且其他地方都是零,但是我得到的数据与此完全不同。以下是代码...

public static void Main(string[] args)
    {
        var waveChannel = new WaveChannel32(new WaveFileReader("../../Files/800Hz.wav"));
        var buffer = new byte[4096 * 4];
        waveChannel.Read(buffer, 0, 4096 * 4);
        var samples = new ComplexF[4096];

        for (int i = 0; i < 4096; i++)
        {
            samples[i].Re = BitConverter.ToSingle(buffer, i * 4);
        }
        Fourier.FFT(samples, FourierDirection.Forward);
        for (int i = 790; i < 810; i++)
            Console.WriteLine(i + ": " + samples[i]);
    }

...它给我以下输出...

790: ( -0.4223004, -0.5940632i )
791: ( -0.4242424, -0.6004524i )
792: ( -0.4241259, -0.591617i )
793: ( -0.4438736, -0.5921871i )
794: ( -0.4386246, -0.5902517i )
795: ( -0.4222358, -0.6125283i )
796: ( -0.424219, -0.586903i )
797: ( -0.4283331, -0.6008587i )
798: ( -0.4152279, -0.5989774i )
799: ( -0.4329002, -0.5994851i )
800: ( -0.4230377, -0.5904933i )
801: ( -0.4128067, -0.5878658i )
802: ( -0.4171145, -0.5898319i )
803: ( -0.4254847, -0.572481i )
804: ( -0.4199851, -0.5827408i )
805: ( -0.4186496, -0.5890546i )
806: ( -0.4181305, -0.6026474i )
807: ( -0.4402256, -0.5738652i )
808: ( -0.4149643, -0.589726i )
809: ( -0.4256677, -0.599369i )

我也尝试计算每个复数的大小,看是否能得到更有意义的结果,但仍然得到类似的结果。我不确定是代码出了什么问题还是我没有理解结果。请帮忙解答?


1
应该是800Hz(而不是800MHz) - DrKoch
相关(可能重复):https://dev59.com/YG855IYBdhLWcg3wZzbf#4371627 - Paul R
你确定你的.wav文件包含32位样本而不是16位整数样本吗? - hotpaw2
1个回答

4

在信号中找不到800 Hz分量signal[800]

FFT结果的N个复杂样本具有频率范围

 0 Hz .. Ns/2, with Ns = sampling frequency of your time signal

在采样频率为44.1kHz的情况下,第一个FFT样本位于0Hz(DC),最后一个FFT样本位于22.05kHz(奈奎斯特频率)。

如果是1024点FFT,将得到512个复杂样本。因此两个FFT样本之间的距离为22050/512 == 43 Hz,所以你的800Hz线大约是第18个样本。


编辑

为什么这些其他分量不等于0.0?

傅里叶变换假设输入是循环的。如果您的输入不是循环的,则必须应用窗口使其有限(并适合单个周期)。

如果您不考虑窗口ing,则自动应用矩形窗口:您的信号从FFT开始“突然”开始,FFT结束时“突然”结束。这形成了一个矩形窗口。

现在,FFT结果恰好是输入信号(单个峰值)的傅里叶变换和此矩形窗口(一个sinc == sin(x)/x函数)的傅里叶变换的卷积。

因此,您在单个正弦分量的FFT结果中看到的实际上是一个矩形窗口的傅里叶变换,即一种sinc函数,仅在少数点处为零。


好的,所以我没有考虑到结果数组中每个索引之间的距离。当我再次运行并查看幅度时,我发现在索引37处有一个巨大的峰值。我猜测这个结果表达的是37 * 22050/1024 ≈ 800,这正是我期望的频率。获得更多的峰值而不仅仅是在音频样本的特定频率处得到纯零,这种情况正常吗? - ellington
@ellington:是的,因为您的输入存在少量噪声,这会导致所有频率上的功率水平较低。(即使您在没有可能引入噪声的传感器的情况下计算样本,仍然会有量化噪声) - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接