% % Copyright (C) 2004 by Hernán Ordiales % % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % function fast_conv( archivo, impulso, salida ) % Convolución rápida de una señal de audio con la respuesta impulsiva de algún sistema modelado como LTI % USO: fast_conv( 'archivo_a_procesar.wav', 'respuesta_al_impulso.wav', 'archivo_de_salida.wav' ); h_stereo = true; x_stereo = true; clip_factor = 1.01; % valor por defecto % respuesta impulsiva: [ h, Fs1 ] = wavread( impulso ); % matriz de 2 columnas, una por cada canal h1 = h(:,1); % columna 1 -> Canal izquierdo h_channels = size(h); h_channels = h_channels(2); if( h_channels == 2 ) h2 = h(:,2); % columna 2 -> Canal derecho else h2 = h(:,1); % columna 1 -> Canal izquierdo h_stereo = false; end % archivo a procesar: [ x, Fs2 ] = wavread( archivo ); x1 = x(:,1); % columna 1 -> Canal izquierdo x_channels = size(x); x_channels = x_channels(2); if( x_channels == 2 ) x2 = x(:,2); % columna 2 -> Canal derecho else x2 = x(:,1); % columna 1 -> Canal izquierdo x_stereo = false; end % si las frecuencias de muestreo coinciden if( Fs1 == Fs2 ) % busca la cantidad de puntos que debo utilizar para realizar la FFT L = length(h1) + length(x1) - 1; % el tamaño de la convolución lineal disp('Procesando...'); % el siguiente código se puede reemplazar por la función nextpow2 (si esta disponible) % N = 2^nextpow(L); N = 2; while( N=L ya que la IDFT de la multiplicacion es la convolución circular y para que esta % equivalga a la tradicional se debe pedir N>=L (donde L=N1+N2-1;N1=longitud(x);N2=longitud(h)) % FFT(X,N) es la FFT de N puntos, rellenada con ceros si X tiene más de N puntos y truncada si tiene demás. H1 = fft( h1, N ); % transformada de Fourier del impulso X1 = fft( x1, N ); % transformada de Fourier de la señal de entrada F_y1 = H1 .* X1; % multiplicación de espectros y1 = ifft( F_y1 ); % se vuelve al dominio del tiempo % normalización del audio: si "y = y/max(y)" -> "los valores fuera del rango [-1,+1] son recortados" y1 = y1/( max(y1)*clip_factor ); % para que no "clipee" % si alguno de los 2 archivos es stereo también procesa el otro canal if( h_stereo || x_stereo ) H2 = fft( h2, N ); % transformada de Fourier del impulso X2 = fft( x2, N ); % transformada de Fourier de la señal de entrada F_y2 = H2 .* X2; % multiplicación de espectros y2 = ifft( F_y2 ); % se vuelve al dominio del tiempo y2 = y2/( max(y2)*clip_factor ); % para que no "clipee" y = [ y1 y2 ]; % se define la salida stereo else y = y1; % se define la salida mono end wavwrite( y, Fs1, salida ); disp( 'Convolución realizada con éxito. Fin.' ); else disp('Error: los archivos no tienen la misma frecuencia de sampleo. No se puede realizar la convolución.'); end