FFT 频谱中的毛刺

Posted

技术标签:

【中文标题】FFT 频谱中的毛刺【英文标题】:Glitches in FFT Spectrum 【发布时间】:2020-10-29 11:14:56 【问题描述】:

我的 FFT 以某种方式工作。我用一些频率扫描对其进行了测试,我可以清楚地看到峰值,但我在整个频谱中得到了一些奇怪的毛刺和强烈的噪音。信号上下跳跃,有时一些条形消失。我有时尝试读取这些值并获得 NaN。我在这里做错了什么?

    void FFTLive()

    int sampleCount = 8192;

    NAudio.Dsp.Complex[] complex = new NAudio.Dsp.Complex[sampleCount];

    float[] dat = new float[sampleCount];
    source.clip.GetData(dat, source.timeSamples);
    for (int i = 0; i < sampleCount; i++)
    
        complex[i].X = dat[i];
        complex[i].Y = 0;
    

    NAudio.Dsp.FastFourierTransform.FFT(false, (int)Mathf.Log(sampleCount, 2), complex);

    for (int i = 0; i < sampleCount; i++)
    
        float value = 10 * Mathf.Abs(Mathf.Log10((complex[i].X * complex[i].X + complex[i].Y * complex[i].Y)));
        Debug.DrawLine(new Vector3(-10 + (float)(i / 20), -16 + value, 40), new Vector3(-9 + (float)(i / 20), -16 + value, 40), Color.green, 0.002f);

    


更新 我添加了窗口并检查了 0,但它看起来仍然有大量的噪音。

 for (int i = 0; i < sampleCount; i++)
    
        complex[i].X = dat[i]*(float)NAudio.Dsp.FastFourierTransform.BlackmannHarrisWindow(i,sampleCount);
        complex[i].Y = 0;
    
    


    NAudio.Dsp.FastFourierTransform.FFT(false, (int)Mathf.Log(sampleCount, 2), complex);


    for (int i = 0; i < sampleCount / 4; i++)
    
        float value = 0;
        if (complex[i].X + complex[i].Y != 0)
            value = 10 * Mathf.Abs(Mathf.Log10(100 * (complex[i].X * complex[i].X + complex[i].Y * complex[i].Y)));
        Debug.DrawLine(new Vector3(-10 + (float)(i / 20), -16, 40), new Vector3(-9 + (float)(i / 20), -16 + value, 40), Color.green, 0.0002f);

    

更新 2

解决了。我忘记了采样数据是 2 个通道,所以我将这两个通道混合在一起,导致了所有的故障。所以我把数据数组分成两半,只取每一个应该来自一个通道的条目。

【问题讨论】:

【参考方案1】:

至少有两个问题。

您没有检查最后一个 Log10() 的幅度输入是否不为零。这将导致 NaN。

在 FFT 之前,您没有使用非矩形窗函数来消除窗伪影(来自 FFT 孔径末端和开始之间不连续的非整数周期波形)。尝试使用 Von Hann 或 Hamming 窗口。

【讨论】:

所以我添加了更新 #1 中的窗口,并检查值何时变为 0,但它仍然不起作用。似乎有大量噪音,但我直接从音频文件中获取数据。我用相同的数据绘制波形,结果很好。

以上是关于FFT 频谱中的毛刺的主要内容,如果未能解决你的问题,请参考以下文章

matlab 作出信号频谱图

matlab中powergui中的fft分析怎么用

关于用FFT分析信号频谱的问题

关于数字信号处理的问题,高速傅立叶变换里DIT-FFT(按时间)和DIF-FFT(按频谱)两种方法

FFT频谱分析(补零频谱泄露栅栏效应加窗细化频谱混叠),MatlabC语言代码

FFT 频谱未正确显示