我正在尝试实现基于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个频率箱可以使用。

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

提前致谢。

有帮助吗?

解决方案

出于这个问题的目的,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;
    }

}

更新: 阅读您的编辑后,我不得不说您的代码正在按预期工作。我以为你正在 大量 扭曲的重新合成信号,不是“轻微的扭曲信号,尤其是在低频下”。

我认为您看到的失真是您使用的窗口尺寸很小的结果 - 如果您不使用汉宁窗口方法来重建原始信号,则尤其是这种情况。

尝试使用更典型的窗口大小(例如1024)运行代码。 8频均衡器通常不使用8箱FFT窗口。通常,将使用8个滑块的设置来计算连接频域中8点的弯曲函数,然后将使用此函数将bin振幅设置为更大,更细粒度的频率集。

还有一个点:频率箱将可用范围均匀划分,因此无论您的窗户大小有多大,超过一半的垃圾箱涵盖了人耳听不到的频率。这就是为什么 乐队 均衡器覆盖通常是对数(例如100Hz,1kHz和10kHz,对于典型的3频段均衡器),因此不适用于等量的频率数量 垃圾箱.

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top