He estado jugando un poco con la implementación Exocortex de la FFT, pero estoy teniendo algunos problemas.DSP - Filtrado en el dominio de la frecuencia a través de FFT
Cada vez que modifico las amplitudes de los bins de frecuencia antes de llamar al iFFT, la señal resultante contiene algunos clics y pops, especialmente cuando hay bajas frecuencias en la señal (como baterías o bajos). Sin embargo, esto no sucede si atenúo todos los contenedores por el mismo factor.
me deja poner un ejemplo de la memoria intermedia de salida de un FFT 4-muestra:
// 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
La salida se compone de pares de flotadores, cada uno representando las partes real e imaginay de un solo bin. Entonces, bin 0 (índices de matriz 0, 1) representaría las partes real e imaginaria de la frecuencia de DC. Como puede ver, los contenedores 1 y 3 tienen los mismos valores (excepto el signo de la parte Im), así que supongo que bin 3 es la primera frecuencia negativa, y finalmente los índices (4, 5) serían los últimos positivos compartimiento de frecuencia.
A continuación, para atenuar el contenedor de frecuencia 1 esto es lo que hago:
// 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;
Para las pruebas reales que estoy usando una FFT de 1024 de longitud y siempre proporcionan todas las muestras por lo que no es 0-padding necesario.
// 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;
}
Obviamente estoy haciendo algo mal pero no puedo entender qué.
No quiero usar la salida FFT como un medio para generar un conjunto de coeficientes FIR ya que estoy tratando de implementar un ecualizador dinámico muy básico.
¿Cuál es la forma correcta de filtrar en el dominio de la frecuencia? ¿Qué me estoy perdiendo?
Además, ¿es realmente necesario atenuar las frecuencias negativas también? He visto una implementación de FFT donde neg. los valores de frecuencia se ponen a cero antes de la síntesis.
Gracias de antemano.
Parece que supone que el filtrado de paso alto se realiza tomando una DFT con ventana, multiplicando los coeficientes y tomando la transformación inversa ("resyntehsis"). Bueno, no es la forma habitual. Primero debe leer sobre los conceptos básicos del procesamiento digital de señales o hacer una pregunta más concreta. http://www.dspguide.com/pdfbook.htm – leonbloy
No estoy asumiendo nada en particular con respecto al filtrado de paso alto pero filtrando en el dominio de la frecuencia, pensé que estaba claro que solo era un ejemplo. Además, no ser la 'manera habitual' no invalida mi pregunta. Todo lo que pido es una explicación de por qué estoy teniendo estas distorsiones extrañas después de la síntesis, y eso no se explica en ese libro, y es por eso que estoy preguntando aquí. No creo que esto merezca un voto negativo, de verdad. – Trap
Su pregunta es razonable, pero sus dudas son conceptuales y no están relacionadas con la programación (ni siquiera con la programación de Matlab), sino con los fundamentos de DSP y DFT. Para responderlo, debe copiar y pegar dos o tres capítulos de cualquier libro de procesamiento de señal digital. – leonbloy