Tra*_*rap 4 signal-processing fft dft
我正在尝试实现一个基于DFT的8波段均衡器,仅用于学习.为了证明我的DFT实现工作,我输入了一个音频信号,对其进行了分析,然后再次重新合成它,而没有对频谱进行任何修改.到现在为止还挺好.
我正在使用所谓的"计算DFT的标准方式",这是通过相关性.该方法计算长度为N/2 + 1个样本的实部和虚部.为了减弱我正在做的频率:
float atnFactor = 0.6;
Re[k] *= atnFactor;
Im[k] *= atnFactor;
Run Code Online (Sandbox Code Playgroud)
其中'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;
}
}
Run Code Online (Sandbox Code Playgroud)
更新:阅读完编辑后,我不得不说你的代码按预期工作.我以为你得到了一个大规模失真的重新合成信号,而不是"轻微的失真信号,特别是在低频时".
我认为你看到的失真是你正在使用的非常小的窗口尺寸的结果 - 如果你没有使用Hanning窗口方法重建原始信号,情况尤其如此.
尝试使用更典型的窗口大小(如1024)运行代码.8波段均衡器通常不使用8-bin FFT窗口.通常,8个滑块的设置将用于计算连接频域中的8个点的曲线函数,然后该函数将用于设置更大,更精细粒度的频率组的区间振幅.
还有一点:频率分档均匀地划分可用范围,因此无论窗口大小多大,超过一半的分档覆盖了人耳听不到的频率.这就是均衡器覆盖的频带通常以对数方式缩放的原因(例如,对于典型的3频段均衡器,为100Hz,1Khz和10Khz),因此不适用于相同数量的频率区间.
在均匀间隔的8个窗口窗口的情况下,除了可听频率的失真之外,8个中的5个的衰减肯定没有听觉效果.