DSP - 使用DFT过滤频率

时间:2010-05-20 16:58:46

标签: signal-processing fft dft

我正在尝试实现基于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波段均衡器,所以我一次只能给DFT 16采样,所以我有8个频率区可供使用。

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

提前致谢。

1 个答案:

答案 0 :(得分:5)

对于这个问题,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-bin FFT窗口。通常,8个滑块的设置将用于计算连接频域中8个点的曲线函数,然后该函数将用于设置更大,更精细粒度的频率组的振幅。 / p>

还有一点:频率分档均匀分配可用范围,因此无论窗口大小多大,超过一半的分档都会覆盖人耳无法听到的频率。这就是均衡器覆盖的波段通常按对数比例缩放的原因(例如,对于典型的3波段均衡器,为100Hz,1Khz和10Khz),因此不适用于相同数量的频率 bins < / em>的

在均匀间隔的8个窗口窗口的情况下,除了可听频率的失真之外,8个中的5个的衰减肯定没有听觉效果。