没有从 Exocortex FFT 获得预期的输出

Posted

技术标签:

【中文标题】没有从 Exocortex FFT 获得预期的输出【英文标题】:Not getting expected output from Exocortex FFT 【发布时间】:2015-04-03 12:51:17 【问题描述】:

我正在为 C# 使用 Exocortex.DSP 库,但它没有给我预期的输出。我不太确定为什么。我在本例中使用的音频文件是 16 位无符号 .wav 文件中的纯 800Hz 音调。在 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 )

我还尝试计算每个复数的大小,看看这是否会给我带来更重要的东西,但仍然得到了类似的结果。我不确定我是否遗漏了代码中的某些内容,或者只是不理解结果。请帮忙?

【问题讨论】:

它应该是 800Hz(而不是 800MHz) 相关(可能重复):***.com/questions/4364823/… 您确定您的 .wav 文件包含 32 位样本而不是 16 位整数样本吗? 【参考方案1】:

signal[800] 找不到 800 Hz 分量

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

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

在 44.1 kHz 的采样频率下,第一个 FFT 样本为 0 Hz(直流),最后一个 FFT 样本为 22.05 KHz(奈奎斯特频率)。

如果这是 1024 点 FFT,您将获得 512 个复数样本。所以两个 FFT 样本之间的距离是 22050/512 == 43 Hz,所以你的 800Hz 线大约是第 18 个样本。


编辑

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

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

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

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

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

【讨论】:

好的,所以我没有考虑结果数组中每个索引之间的距离。当我再次运行它并查看幅度时,我在索引 37 处得到一个巨大的峰值。我猜这个结果表示 37 * 22050/1024 ≈ 800,这是我期望的频率。除了音频样本中的特定频率之外,在所有地方都获得更多的尖峰,而不仅仅是简单的零,这是否正常? @ellington:是的,因为您的输入有少量噪声,这会转化为所有频率下的小功率电平。 (即使您在没有任何可能引入噪声的传感器的情况下计算样本,您仍然会有量化噪声)

以上是关于没有从 Exocortex FFT 获得预期的输出的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Tizen 上的实时 FFT 获得最准确的音频数据?

了解正弦曲线的 FFT

使用 EZAudio 从 FFT 获得更精确的频率?

解释 numpy.fft.fft2 输出

Android AudioRecord - 在没有库的情况下获得 FFT 的最佳方式

python和ctypes cdll,没有从函数中获得预期的回报