Я немного поиграл с реализацией 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
Выход состоит из пар поплавков, каждый из которых представляет реальную и воображаемую части одного бункера. Итак, bin 0 (индексы массива 0, 1) будут представлять действительную и мнимую части частоты постоянного тока. Как вы можете видеть, бины 1 и 3 имеют одинаковые значения (кроме знака части Im), поэтому я предполагаю, что бит 3 является первой отрицательной частотой, и, наконец, индексы (4, 5) будут последним положительным частотный отсек.
Затем, чтобы уменьшить частоту bin 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 длины, и я всегда предоставляю все образцы, поэтому не требуется 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. значения частоты обнуляются перед синтезом.
Спасибо заранее.