Práctica 3: Implementación de efectos acústicos 3.0.- Objetivos Al finalizar esta práctica, el alumno debe ser capaz de: • Grabar una señal de voz y procesarla en Matlab. • Añadir un eco, con diferente amplitud y retardo a una señal de voz. Representar y reproducir, la nueva señal de audio. Explicar el efecto de cada parámetro en la señal con eco. • Añadir reverberación, con diferentes amplitudes, retardos, número de ecos…a una señal de voz. Representar y reproducir, la nueva señal de audio. Explicar el efecto de cada parámetro en la señal con reverberación. • Añadir un efecto flanging a una señal de audio. Representar y reproducir, la nueva señal de audio. Explicar el efecto de cada parámetro en la señal con flanging. 3.1.- Introducción En esta tercera práctica, empezaremos a tratar sistemas o filtros. Estrictamente hablando, un filtro es un sistema diseñado para eliminar o modificar componentes de la señal. Hablaremos de los filtros FIR (Finite Impulse Response). Estos filtros son sistemas para los cuales cada salida es un promedio de un número finito de muestras de la señal de entrada. La expresión general de un filtro FIR es de la forma: M y[n] = ∑ bk x[n − k ] k =0 Para computar la salida en el instante n, el filtro emplea las M+1 muestras anteriores multiplicándolas por los coeficientes bk. Un filtro FIR está completamente determinado por dichos coeficientes. El orden del filtro es el número de coeficientes-1. Los efectos de audio que vamos a tratar son todos filtros FIR, de la forma anteriormente indicada. 1.1 3.2.- Retrasos y eco Quizá el más básico de todos los efectos sea el retraso temporal. Este efecto se utilizará luego como base para construir otros efectos más complejos. Un retraso en el tiempo se puede expresar mediante la siguiente ecuación en diferencias: y[n] = x[n − D ] donde D es el retardo en número de muestras que experimenta la señal. Así, un eco, que no es mas que la suma a una señal de la misma señal atenuada y retardada en el tiempo, quedaría representado por: y[n] = x[n] + ax[n − D ] donde a < 1 y representa las pérdidas debidas a las reflexiones y durante la transmisión. El diagrama de bloques aparece representado en la Figura 1. x[n] y[n] D a Retardo Figura 1: Diagrama de bloques de un sistema con eco. Escribir una función en Matlab que genere un eco de la señal de entrada. Sus parámetros de entrada serán la señal de entrada, el retardo y el valor de la atenuación, a, y como salida tendrá la señal generada. Recordar que para leer la señal de entrada se debe utilizar el comando [y,fs,nbits]=wavread('nombre_archivo.wav') donde y será el vector con los datos, fs es la frecuencia de muestreo que se utilizó cuando se generó el fichero '.wav' y nbits es el número de bits con que los datos fueron almacenados. Para más detalles utilizar la ayuda de Matlab. fs es la frecuencia a utilizar cuando reproducimos el sonido utilizando sound. Comprobar que existe un valor mínimo del retardo introducido para que este comience a percibirse. Utilizando Fs calcular el tiempo al que corresponde este retardo Comprobar el efecto del parámetro a, variando su valor. NOTA: Tener en cuenta que la señal retardada tiene una duración D muestras mayor que la original. 1.2 3.3.- Reverberación Si un número infinito de ecos sucesivos es sumando, obtenemos una reverberación similar a la que experimentan las habitaciones. La reverberación es el resultado de las múltiples reflexiones de un sonido, por ejemplo en una habitación. Desde cualquier fuente de sonido existe un camino directo a nuestros oídos. Además, las ondas de sonido pueden tomar un camino más largo, reflejándose en las paredes, suelo y techos de la habitación antes de llegar a nuestros oídos. Una onda reflejada llegará más tarde que la onda directa, ya que la distancia que recorre es más larga, y es así mismo más débil, ya que cada rebote supone una pérdida de energía. La señal de salida puede calcularse recursivamente como: y[n] = x[n] + a· y[n − D ] El valor inicial de y[n] es x[n] y el número de iteraciones será el número de ecos tenidos en cuenta. Así por ejemplo, una iteración nos genera un eco como el que hemos estudiado en el ejercicio anterior. x[n] y[n] D a Figura 2: Diagrama de Bloques de un reverberador. Escribir una función en Matlab que genere un efecto de reverberación de la señal de entrada. Sus parámetros de entrada serán la señal de entrada, el retardo, el valor de la atenuación, a, y el número de ecos tenidos en cuenta. Como salida tendrá la señal generada. NOTA: Tener en cuenta que cada iteración aumenta el tamaño de la señal en D muestras. 3.4.- Flanging El efecto de flanging se puede crear fácilmente haciendo que el retardo varíe periódicamente usando para ello una onda sinusoidal de baja frecuencia. Sin embargo la forma más natural de interpretar el flanging pasa por entenderlo como si fuese un simple “eco”. Es decir, a cada muestra de la señal original se le suma otra muestra de la misma señal pero atenuada y desfasada con respecto a la muestra original. Además el flanging añade la peculiaridad de que este desfase no es fijo, ni aleatorio, sino que se trata de un desfase que viene marcado por una función sinusoidal. 1.3 De ahí que el efecto final del flanging sea el de un eco más o menos curioso con reverberaciones que parecen no ajustarse a un patrón determinado, aunque ahora ya sepamos de dónde proceden. El efecto de flanging se puede resumir en esta fórmula: y[n] = x[n] + ax[n − d (n )] Donde el retardo d[n] realmente varía de igual modo que una sinusoide entre los límites 0 <= d[n] <= D, según cualquiera de las siguientes fórmulas (equivalentes); d[n]= D/2 * ( 1- cos(2*pi*Fd*n) ) d[n]= abs( round ( D cos(2*pi*Fd*n) ) ) Donde Fd representa una frecuencia baja ( típicamente 1Khz) en unidades de ciclos/muestra. El diagrama de flujo que explica conceptualmente el efecto del flanging es el siguiente: X[n] + Y[n] Z-d a Figura 3: Diagrama de bloques para flanging. El siguiente dibujo ilustra de forma clara como se podría conseguir un flanging en caso de disponer de una “pared móvil”: 1.4 Señal ecos + D Señal con flanging Figura 4: Flanging con una pared móvil. Al final la fórmula del flanging quedará así; y(i)= x(i)+a*x(i-delay(i)); donde el delay se saca de la señal sinusoidal. Es muy importante que el argumento de la “señal eco”: [i-delay(i)], tome un valor siempre positivo. Para ello la señal final se construirá en dos pasos: 1. Hacemos que en las D primeras muestras la señal original sea la misma. for i=1:1:D+1 y(i)=x(i); end; 2. En las muestras posteriores ( hasta la última muestra de la señal de entrada) a la señal original se le añade el eco. Se trata de diseñar este eco, sabiendo que su amplitud no puede ser mayor que D y que su frecuencia viene dada en ciclos por muestra. for i=D+1:1:xlen delay(i) = ¿ ---------------- ? y(i)= x(i)+a*x(i-delay(i)); 1.5 end; Una posible estructura para comenzar el programa sería esta: [x,fs,n]=wavread('dt.wav');%cargamos señal de audio xlen=length(x)%número de muestras en la señal original %constantes--------------------------------------a=/****/; % atenuación de la señal de eco D=/****/; % numero de muestras en el retardo y=zeros(size(x)); delay = zeros(size(x)); cycle=/****/; % cosntrucción de la señal ----------------------for i=1:1:D+1 / ******************** / end; for i=D+1:1:xlen delay(i) = / ******************************** / y(i)= x(i)+a*x(i-delay(i)); end; sound(y,fs); Variar el valor del parámetro “a”. ¿Qué observas?, ¿Qué efecto tiene esta constante sobre el la señal resultante? Variar el valor del parámetro “D”. ¿Qué cambios observas?, ¿qué valores de “D” hacen que el eco se haga notar antes? Quizá esta figura te ayude a entenderlo mejor. 1 ….. xlen D ( xlen - D ) Figura 5: Vector de salida en efecto flanging. 1.6