私は FFT の Exocortex 実装で少し遊んでいますが、いくつか問題があります。
iFFT を呼び出す前に周波数ビンの振幅を変更すると、特に信号に低周波数が存在する場合 (ドラムやベースなど)、結果の信号にクリックやポップが含まれます。ただし、すべてのビンを同じ係数で減衰させると、これは起こりません。
4 サンプル 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
出力は float のペアで構成され、それぞれが 1 つのビンの実部と虚部を表します。したがって、ビン 0 (配列インデックス 0、1) は、DC 周波数の実部と虚部を表します。ご覧のとおり、ビン 1 と 3 は両方とも同じ値 (Im 部分の符号を除く) を持っているため、ビン 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;
}
明らかに私は何か間違ったことをしていますが、何がわかりません。
非常に基本的なダイナミック イコライザーを実装しようとしているので、FIR 係数のセットを生成する手段として FFT 出力を使用したくありません。
周波数領域でフィルタリングする正しい方法は何ですか? 私は何が欠けていますか?
また、負の周波数も減衰させる必要があるのでしょうか? neg の FFT 実装を見てきました。周波数値は合成前にゼロになります。
前もって感謝します。