我一直在玩 FFT 的 Exocortex 实现,但我遇到了一些问题。
每当我在调用 iFFT 之前修改频率箱的幅度时,生成的信号都会包含一些咔嗒声和爆裂声,尤其是当信号中存在低频时(如鼓或贝司)。但是,如果我将所有 bin 衰减相同的因子,则不会发生这种情况。
让我举一个 4-sample FFT 的输出缓冲区的例子:
// Bin 0 (DC)
FFTOut[0] = 0.0000610351563
FFTOut[1] = 0.0
// Bin 1
FFTOut[2] = 0.000331878662
FFTOut[3] = 0.000629425049
// Bin 2
FFTOut[4] = -0.0000381469727
FFTOut[5] = 0.0
// Bin 3, this is the first and only negative frequency bin.
FFTOut[6] = 0.000331878662
FFTOut[7] = -0.000629425049
输出由成对的浮点数组成,每个浮点数代表单个 bin 的实部和虚部。因此,bin 0(数组索引 0、1)将代表 DC 频率的实部和虚部。如您所见,bin 1 和 3 都具有相同的值(除了 Im 部分的符号),所以我猜 bin 3 是第一个负频率,最后索引 (4, 5) 将是最后一个正频率仓。
然后衰减频率仓 1,这就是我所做的:
// Attenuate the 'positive' bin
FFTOut[2] *= 0.5;
FFTOut[3] *= 0.5;
// Attenuate its corresponding negative bin.
FFTOut[6] *= 0.5;
FFTOut[7] *= 0.5;
对于实际测试,我使用的是 1024 长度的 FFT,并且我总是提供所有样本,因此不需要 0 填充。
// Attenuate
var halfSize = fftWindowLength / 2;
float leftFreq = 0f;
float rightFreq = 22050f;
for( var c = 1; c < halfSize; c++ )
{
var freq = c * (44100d / halfSize);
// Calc. positive and negative frequency indexes.
var k = c * 2;
var nk = (fftWindowLength - c) * 2;
// This kind of attenuation corresponds to a high-pass filter.
// The attenuation at the transition band is linearly applied, could
// this be the cause of the distortion of low frequencies?
var attn = (freq < leftFreq) ?
0 :
(freq < rightFreq) ?
((freq - leftFreq) / (rightFreq - leftFreq)) :
1;
// Attenuate positive and negative bins.
mFFTOut[ k ] *= (float)attn;
mFFTOut[ k + 1 ] *= (float)attn;
mFFTOut[ nk ] *= (float)attn;
mFFTOut[ nk + 1 ] *= (float)attn;
}
显然我做错了什么,但不知道是什么。
我不想使用 FFT 输出作为生成一组 FIR 系数的手段,因为我正在尝试实现一个非常基本的动态均衡器。
在频域中过滤的正确方法是什么?我错过了什么?
另外,真的需要衰减负频率吗?我已经看到了一个 FFT 实现,其中 neg。频率值在合成之前归零。
提前致谢。