Filtros Introducción: Consideramos el siguiente problema: Tenemos una grabación de sonido x(t) con frecuencia de muestreo 32 kHz y frecuencias máximas de unos 16 kHz en la grabación. Tenemos que conseguir y(t), la misma grabación con frecuencia de muestreo de 8 kHz, es decir un valor para cada 4 muestras. Consideramos las siguientes aproximaciones a la solución del problema: 1) Tomamos cada 4-ta muestra y ignoramos los restantes 3. La operación es frecuente en teoría de señal y se llama submuestrear (downsampling) la señal con un factor de 4 (1 de cada 4). La solución es mala. La señal contendrá sonidos por encima de la mitad de la frecuencia de muestreo y por tanto este espectro se convertirá en ruido. Escuchar el sonido original. (grab.wav y la submuestreada sub4.wav). 2) Tomamos la media de cada 4 muestras y la guardamos como el resultado. y(t ) ( x(t ) x(t 1) x(t 2) x(t 3)) / 4 (1) Esto evidentemente es mejor solución y es exactamente lo que tenemos que hacer si de una imagen se tratase, pero no garantiza que no vamos a guardar frecuencias por encima de la frecuencia de Nyquist. Por lo tanto, no es válida para el sonido. También veamos que la señal y(t) está desplazada y más bien representa el momento y(t-3/2). Escuchar canc_med4.wav. 3) La solución es – eliminar de la señal todas las frecuencias por encima de la frecuencia de Nyquist (4kHz) y muestrearla con 8 kHz. Podemos hacerlo de varias maneras: i. Transformando la señal en el espacio de frecuencias (con transformada de Fourier), multiplicando por 0 todas las frecuencias por encima de 4000Hz y haciendo la transformada inversa (Fig.1). Multiplicamos el espectro de la señal en el espacio de frecuencias x( f ) por la función g(f ), que se define como: 1 | f | Fc / Fm g( f ) 0 | f | Fc / Fm El problema – para la transformada de Fourier necesitamos toda la señal. El tiempo de espera de la señal estaría tan grande que no podemos esperar tanto para cualquier problema práctico. Además requiere muchos cálculos. Es decir – necesitamos de esperar un tiempo infinito para hacerlo. Nota: Cuando trabajamos con filtros, es cómodo utilizar la frecuencia de muestreo Fm como medida de la frecuencia (es decir lo que mide 1 es Fm, la frecuencia de Nyquist es ½ : Fm/2). Vamos a señalar esta situación explícitamente y por tanto no vamos a escribir siempre la frecuencia f sino f/Fm. Así los f-s que nos interesan son de 0 a ½. ii. Sabiendo de las propiedades de la transformada de Fourier que la multiplicación punto de F(omega) por punto es equivalente a una convolución en el espacio de tiempo, tratamos de conseguir esta convolución (2f ) : g (t ) g ( f )e 2if t Fc / Fm df 1 2ift e 2it g (t ) f Fc / Fs f Fc / Fs 1e Fc / Fs 2if t f Fc / Fm df f Fc / Fs e 2ift d 2ift 2it 1 sin(2t Fc / Fs) (e 2itFc/ Fs e 2itFc/ Fs ) 2it t sin(2t Fc / Fs) , t 0,1,2,...,. t Al obtener esta solución, también necesitamos un tiempo infinito, ya que el índice t recorre todos los valores del tiempo. Pero los valores de g(t) bajan y podemos parar hasta un valor determinado de t. La gráfica es esencialmente la de sinc(t). Generalizando la transformada, si transformamos la señal x(t), tendremos: m y(t ) x(t k )ak . (2) k 0 Operación de este tipo sobre la señal se llama FIR (Finite Impulse Response). Esta es una solución ya aceptable para el problema (con a_k=g(k)). En práctica se utiliza m=40, pero m puede ir a valores aun mas elevados en equipos de calidad. Al considerar el ejemplo de arriba, para conseguir una precisión razonable, tenemos que coger bastantes valores. Además tenemos que desplazar la señal en el tiempo, es decir, introducir retrasos en la salida, porque no podemos trabajar con el futuro de la señal (fig.....). Es decir los FIRs surgen los desperfectos de largo retraso del resultado y de muchos cálculos por muestra. Buscamos una solución más eficiente. Notamos que si, por ejemplo, hacemos la media no de 4 valores, como en 1, pero de m valores, lo lógico no es de calcular directamente y(t)=(x(t)+x(t-1)+...+x(t-k+1))/k, pero de utilizar el y() ya calculado en el paso anterior: y(t)=y(t-1)+(x(t)-x(t-k))/k. Es decir, al utilizar los valores ya conocidos de y(), podemos conseguir una fórmula mucho más corta. Generalizando tenemos: n m k 0 k 0 y(t ) y(t k )bk x(t k )a k . Este tipo de filtro se llama IIR (Infinite Impulse Response). Problemas con IIR: Consideramos la respuesta del filtro IIR: y(t)=2 y(t-1)+x(t). (3) Al elegir un pulso en el momento 0: {x(t)=1, t=0 y x(t)=0, t!=0} e y(-1)=0, tendremos la respuesta 1,2,4,8,16,.... Con otras palabras el filtro va a desbordar. IIR pueden desbordar. Al contrario del IIR, el mismo impulso como entrada a un filtro IIR cualquiera, producirá la respuesta en los momentos 0,1,...,m,.... igual a a0,a1,..., am, 0,0,0... FIR no puede desbordar. Cualquier valor x(t) tiene impacto finito en el tiempo y al valor de y(t). Se puede utilizar esta propiedad también para generar señales. Consideramos el caso más simple: y(t) = -y(t-1)+x(t). Al dar un impulso como entrada a este filtro, tendremos respuesta 1,-1,1,-1,1,-1, ... Se genera una señal periódica. En actualidad, eligiendo correspondientes bk, se generan señales periódicas. Respuesta espectral de los filtros (de una frecuencia) Respuesta a una frecuencia de un filtro FIR: Si la señal x(t) es estrictamente periódica con frecuencia omega: x(t ) Aeit . Entonces según (2): m m k 0 k 0 y (t ) k ak Aei (t k ) Aeit k ak Aeik x (t ) ak e ik x(t ) ak (e i ) k y (t ) g ( ) x (t ). Con otras palabras, la frecuencia omega tiene ganancia g. De este modo la respuesta espectral del filtro es fácil de calcular. Dibujando g como función de la frecuencia, tenemos la línea de ganancia del filtro, es decir el ecualizador. También vamos a utilizar la notación a( z ) k ak z k . Para el filtro IIR, la respuesta depende de la historia de la señal. Pero suponiendo que la respuesta es del mismo tipo, si podemos escribir y (t ) g ( ) x (t ) , podemos calcular g(.): y (t ) g ( ) x (t ) k bk y (t k ) k ak x (t ) k bk g ( ) Aei (t k ) k ak Aei (t k ) (t ) g ( )b(e x (t ) g ( )k bk (e i ) k k ak (e i ) k x i ) a(e i ) g ( ) x (t ). Eliminando x(t) de las dos ultimas líneas, tenemos: g ( )b(e i ) a(e i ) g ( ) g ( ) a(e i ) . 1 b(e i ) De nuevo la ganancia a una sola frecuencia se calcula fácil y explícitamente. En general la ganancia es un número complejo, reflejando que la señal con frecuencia dada no solo se amplia, pero también se desplaza en el tiempo, es decir cambia de fase. En realidad, al trabajar con sonido, la fase de la señal no nos interesa, porque los seres humanos somos insensibles a la fase. Podemos simplificar la expresión de arriba considerando solo el valor absoluto de la ganancia. a ( e i ) | g ( ) | (4) 1 b ( e i ) Normalmente |g| se representa en escala logarítmica (decibelios) y la frecuencia también se representa en escala logarítmica. Ejemplo: Calcular la respuesta espectral del filtro que toma promedio de 4 valores. Comparar con el efecto deseado al principio del capitulo (filtrar con frecuencia Fm/4). Solución: Tenemos a0=a1=a2=a3=1/4. Sustituyendo en (4): | g (2f ) || 1 e i e i 2 e i 3 | / 4 | e i 3 / 2 (ei 3 / 2 ei / 2 e i / 2 e i 3 / 2 ) | / 4 | e i 3 / 2 || (ei 3 / 2 e i 3 / 2 e i / 2 ei / 2 ) | / 4 1 | 2 cos(3 / 2) 2 cos( / 2) | / 4 | cos(2f / 2) cos(2f 3 / 2) | / 2 | cos(f ) cos(3f ) | / 2. El grafico de esta función está representado en la figura. (Notar que en unidades de la frecuencia de muestreo necesitamos la función solo en el intervalo f = [0,1/2].) Vemos que la aproximación deseada de filtrar todo por debajo de ¼ de la frecuencia de Nyquist no es muy buena. El grafico en escala logarítmica es aun más claro: Ejercicio 2: Encontrar la respuesta espectral del filtro IIR y(t) = 0.9 y(t-1) + 0.1 x(t). Solución: Este es un promedio exponencial. De nuevo utilizamos la formula (4). Tenemos b1=-0.9 y a0=0.1: | g ( ) | a ( e i ) 1 b ( e i ) 0.1 1 0. 9 e i 0.1 / | 1 0.9e i | 0.1 / (1 0.9e i )(1 0.9e i ) 0.1 / 1 0.9 * 0.9 0.9(e i e i ) 0.1 / 1 0.9 * 0.9 0.9 * 2 cos(2f ) Cuando f=0, cos(0)=0 y g(0)=1. Cuando f=1/2 (lo máximo posible) cos(1800)=-1 y g=0.1/1.9. La curva entre f=0 y f=1/2 solo baja, porque el cos() de 0 a 180 grados baja. Así que este es un filtro de paso bajo. La figura representa la respuesta en escala normal y en escala logarítmica. Vemos que la curva es bastante suave y no cruza el valor 0. Escripts: Los ficheros de sonido están conseguidos a partir de fichero WAV con frecuencia de muestreo 32kHz con los siguientes scripts y líneas de comando: od --width 2 -v -t d2 grab.wav | \ awk -f wav_downs4.awk | \ awk –f tobin.awk > sub4.wav od --width 2 -v -t d2 grab.wav | \ awk -f wav_med4.awk | \ awk –f tobin.awk > med4.wav Aplicar el filtro en el ejemplo 2: od --width=2 -t d2 -v grab.wav | \ awk '{if (NR<300) print; else {y = y*0.9+$2*0.1; print $1,int(y);}}'|\ awk -f tobin.awk > gr.wav # tobin.awk: { a=((256*256+$2)%(256*256)); printf "%c%c",a%256,int(a/256); } #downsampling.awk: BEGIN{ k=0; }{ # leer la cabecera n=$1+0; if (n==4 || n== 52) { low=(256*256+$2)%(256*256); next; } if (n==6 || n== 54) { high=(256*256+$2)%(256*256); a=int(low/4)+high*256*(256/4); print n-2,a%(256*256); print n,int(a/(256*256)); next; } if (n==30) { print $1,((256*256+$2)%(256*256))/4; next; } if (NR<500) { print; next; } # here do the job. if (k==0) print; k++; if (k==4) k=0; } #med4 difiere solo en las lineas en negrita: .... x_3=x_2; x_2=x_1; x_1=x_0; x_0=$2; if (k==0) print $1,int((x_0+x_1+x_2+x_3)/4+0.5); k++; if (k==4) k=0; ....