DSP - 使用 DFT 过滤频率

Posted

技术标签:

【中文标题】DSP - 使用 DFT 过滤频率【英文标题】:DSP - Filtering frequencies using DFT 【发布时间】:2010-05-20 16:58:45 【问题描述】:

我正在尝试实现基于 DFT 的 8 波段均衡器,其唯一目的是学习。为了证明我的 DFT 实现是有效的,我输入了一个音频信号,对其进行分析,然后再次重新合成它,而不对频谱进行任何修改。到目前为止一切顺利。

我正在使用所谓的“计算 DFT 的标准方法”,即相关性。此方法计算长度为 N/2 + 1 个样本的实部和虚部。衰减我正在做的频率:

float atnFactor = 0.6;
Re[k] *= atnFactor;
Im[k] *= atnFactor;

其中“k”是 0 到 N/2 范围内的索引,但我在重新合成后得到的是轻微失真的信号,尤其是在低频时。

输入信号采样率为 44.1 khz,由于我只想要一个 8 波段均衡器,因此我一次输入 16 个 DFT 样本,因此我有 8 个频段可供使用。

谁能告诉我我做错了什么?我试图在互联网上查找有关此主题的信息,但找不到任何信息。

提前致谢。

【问题讨论】:

【参考方案1】:

就本题而言,DFT 和 FFT 本质上是相同的。

要衰减 FFT 变换阵列中的频率仓(或“频带”),您需要将实部和虚部乘以相同的因子,并将相应的实部和虚部相乘 负频率箱。 FFT 生成一对变换后的数组,其中前半部分的值表示正频率分量,后半部分表示负频率分量。

这是一个用于解释我的意思的低通滤波器的简化代码示例:

// fftsize = size of fft window
int halfFFTsize = fftsize / 2;
float lowpassFreq1 = 1000.0;
float lowpassFreq2 = 2000.0;
for (int i = 0; i < halfFFTsize; i++)

    int ineg = fftsize - 1 - i; // index of neg. freq.
    float freq = (float)i * (44100.0F / (float)halfFFTsize);
    if (freq >= lowpassFreq2)
    
        real[i] = 0;
        imag[i] = 0;
        real[ineg] = 0;
        imag[ineg] = 0;
    
    else if (freq >= lowpassFreq1)
    
        float mult = 1.0 - ((freq - lowpassFreq1) / 
            (lowpassFreq2 - lowpassFreq1));
        real[i] *= mult;
        imag[i] *= mult;
        real[ineg] *= mult;
        imag[ineg] *= mult;
    


更新:阅读您的编辑后,我不得不说您的代码按预期工作。我假设您得到的是一个大量失真的重新合成信号,而不是“轻微失真的信号,尤其是在低频时”。

我认为您看到的失真是您使用的窗口尺寸非常小的结果 - 如果您不使用 Hanning 窗口方法来重建原始信号,情况尤其如此。

尝试使用更典型的窗口大小(如 1024)运行您的代码。 8 段均衡器通常不使用 8 段 FFT 窗口。通常,8 个滑块的设置将用于计算连接频域中 8 个点的曲线函数,然后该函数将用于为更大、更细粒度的一组频率设置 bin 幅度。

还有一点:频率区间均匀地划分可用范围,因此无论您的窗口大小有多大,超过一半的区间都覆盖了人耳听不到的频率。这就是为什么均衡器覆盖的频段通常以对数方式缩放(例如,对于典型的 3 频段均衡器,100Hz、1Khz 和 10Khz),因此不适用于相同数量的频率bins。

在均匀间隔的 8 bin 窗口的情况下,8 中的 5 衰减肯定不会产生除了可听频率失真之外的任何可听效果。

【讨论】:

+1。你的最后一句话特别重要。通过将频域中的值设置为零进行滤波实际上是应用了一个方形滤波器,这将在频率响应中引起明显的振铃(吉布斯现象)。请记住,将离散频域中的值设置为零只会影响该精确频率处的响应。频率样本之间的频率响应将在砖墙滤波器的作用下剧烈振荡。我建议您查看有关带通 FIR 设计的教程。 @Jason:你有任何好的滤波器设计教程的链接吗?我对上面示例中的过滤器进行了简短的研究,但没有比这更进一步。 哦,我猜您删除了那句话,但您也更改了代码以显示通带的更渐进的变化。 @Jason:我确信我的减速版本仍然存在一些问题,如果您提供有关此类事情的任何信息,我将不胜感激。我在软件合成器中使用了这样的过滤器,但不是基于对我所做工作的任何真实了解。 ccrma.stanford.edu/~jos/sasp/FIR_Digital_Filter_Design.html 看起来还不错,但是我个人没有用过很多在线教程,因为我有很多教科书。可能最简单的方法是窗口设计方法,但我现在只使用像 Parks-McClellan 这样的滤波器设计的最佳方法来创建滤波器。这个算法相当复杂,但它被广泛使用。它将根据您提供的许多输入参数输出 FIR 滤波器系数。

以上是关于DSP - 使用 DFT 过滤频率的主要内容,如果未能解决你的问题,请参考以下文章

FFT算法理解

DSP - 获取所有频率的幅度

频率域滤波

对于DFT频谱泄漏问题的研究

DSP方法检测在当前声音中可能不是最主要的特定频率

dsp.Audiorecorder的Matlab傅里叶变换实时