FRECUENCIA Y FASE DE UNA CANCIÓN

 

Hacer este pequeño tutorial se me ocurrió un día que me puse a jugar con el MatLab (yo uso la versión 6.5 pero esto funciona también para la 7) debido a lo que leí en esta web:

http://www.bores.com/courses/intro/freq/3_ft.htm

Lo que me llamó la atención fue lo que dice el segundo párrafo. Calcular la transformada de Fourier de una señal cualquiera (como una canción) es expresarla en una suma de senos y cosenos (sus componentes de frecuencias), es decir: la transformada de Fourier significa que cualquier canción (desde Coma White de Marilyn Manson hasta las sinfonías de Beethoven) pueden ser reproducidas si se tiene un número muy grande de generadores de señal senoidal (un número infinito en teoría, 20000 en la práctica) y si éstos se encienden desde el principio del Tiempo, el Big Bang, y se los deja funcionar hasta que todo el Universo sucumba a la muerte térmica (una forma grandilocuente de decir cuando todo en el universo se enfríe).

Lo malo es que esta no es toda la historia, y ahora voy a explicar porqué:

La transformada de Fourier se basa en la Identidad de Euler:

Donde "x" es una variable cualquiera e "i" la raíz cuadrada de -1 (la unidad imaginaria). Esta igualdad es el resultado de operar con series de sumas infinitas.

"Transformar" una ecuación significa multiplicarla por algo, la transformada de Fourier es la siguiente:

En electrónica a la unidad imaginaria se la define como "j" para no confundirla con la variable "i" que solemos usar para la corriente. En la fórmula "t" es el tiempo y "w" es velocidad angular. Si se divide a ésta entre 2*Pi se obtiene la función en hertz (frecuencia).

Para una señal discreta (digitalizada):

Donde "n" es un número entero, la variable omega es igual a T*w. T es el periodo de muestreo para digitalizar la señal y es la inversa a la frecuencia de muestreo: 1/fs.

Para quien no tiene ni idea de lo que estoy hablando, acá hay un excelente y sencillo tutorial sobre DSP:

http://www.bores.com/courses/intro/index.htm

¿A qué quiero llegar con esto? A que la transformada de Fourier genera valores complejos a partir de una ecuación o una serie de números reales. La unidad imaginaria mantiene separados senos y cosenos, pues éstos son lo mismo, la única diferencia es un desfase de 90º (un cuarto de ciclo). En señales, la unidad imaginaria (nuestro j) simboliza 90º de desfase, y un número complejo cualquiera: a + jb es en realidad una coseno cuya amplitud está dada por:

Y también posee una fase, la cual es:

Por lo que al final, al sacarle la transformada de Fourier a una ecuación o a una señal de audio se obtienen dos tipos de información: la de sus componentes de frecuencia, y la de las fases de cada componente de frecuencia. 

Lo que estuve haciendo en MatLab fue capturar una señal d audio, sacarle la transformada de Fourier, eliminar la información sobre las fases, aplicarle la transformada inversa para devolverla al dominio temporal y escuchar el resultado. 

En Matlab el comando para obtener la transformada de Fourier es "fft", la inversa se obtiene con el comando "ifft". El comando "abs" calcula los módulos de los números complejos, reales o imaginarios que resultaron de calcular la transformada. Con este comando también se eliminan las fases (o lo que es lo mismo: se les asigna a todas las componentes de frecuencia una fase de 0º).

Antes de empezar a capturar audio con el Matlab o cualquier programa es buena idea revisar las opciones de la tarjeta de sonido, yo prefiero no silenciar nada: 

Para la grabación es necesario seleccionar por dónde se quiere la captura de audio: Micrófono, Line In o wave (que es como reproducen la música el winamp y el Windows Media Player):

 

El siguiente programa puede ser copiado y pegado tal como está a un archivo *.m y ejecutado desde el Matlab, como la captura es monoaural puede ocurrir que la señal resulte con algo de ruido; para este pequeño experimento eso no interesa. Este programa sirve para capturar desde el micrófono también, lo importante es que sean menos de 5 o 6 segundos de captura ya que nada se guarda en el disco duro, todo va a la Ram y no es bueno que se sature. (las líneas que se repiten pueden meterse dentro de funciones para luego simplemente llamarlas): 

clear all; %para borrar todas las variables
clc; %para limpiar la ventana de comandos
fs=44100; %frecuencia de muestreo para calidad de CD
Bm=16; %numero de bis de cada muestra de la señal digitalizada
duracion=3; % en segundos, esto puede variarse
numcan=1; %numero de canales: 1 es monoaural, 2 es estereo
repeticiones=0; %1 para una sola repeticion, 1 para repetir dos veces, etc.

% ai y ao no son vectores ni variables, contienen los parametros de captura
%lo que sigue son comandos y funciones propias del matlab y deben ser copiadas tal como estan

ai=analoginput('winsound');
n=1:numcan;
chan=addchannel(ai,n);
set(ai,'SampleRate',fs);
ActualRate=get(ai,'SampleRate');
set(ai,'SamplesPerTrigger',duracion*ActualRate);
set(ai,'TriggerType','Manual');
set(ai,'BitsPerSample',Bm);

ao=analogoutput('winsound');
chan=addchannel(ao,n);
set(ao,'SampleRate',fs);
set(ao,'BitsPerSample',Bm);
set(ao,'TriggerType','manual');
set(ao,'RepeatOutput',repeticiones);

% esto fue para que la computadora sepa como hacer la captura y la reproduccion

%con esto empieza la captura de audio
disp('presione enter para captura de señal');
pause;
start(ai);
trigger(ai);
senal=getdata(ai);
disp('Senal capturada');

%si es monoaural "senal" es un vector de longitud fs*duracion
%si es estereo seran dos vectores senal(1,:) y senal(2,:) para cada canal
% Es aqui donde va la programacion para procesar "senal" 

transformada=fft(senal); %esto es para sacarle la transformada de fourier a senal
senal0 = ifft(transformada); 
%ifft es la transforada inversa de fourier
%es para volver del dominio de la frecencia al dominio del tiempo
%esto es para demostrar que senal0 y la senal original son iguales
transformadanofase=abs(transformada); %esto es para eliminar la informacion sobre las fases
%el comando "abs" solo deja las amplitudes 
senal1=ifft(transformadanofase);
%senal1 es la senal de audio sin la informacion de las fases


disp('presione enter para reproducir la senal original');
pause;

%como matlab captura y reproduce como columna las siguientes líneas
%son para asegurar que la senal capturada esta como columna ya sea mono o estereo

[m,n]=size(senal);
if m<=2 & n>=m
senal=senal';
end; 

[m,n]=size(senal0);
if m<=2 & n>=m
senal0=senal0';
end; 

[m,n]=size(senal1);
if m<=2 & n>=m
senal1=senal1';
end; 

%esto es para la reproduccion
disp('la senal original es:'); 
disp('');
set(ao,'RepeatOutput',repeticiones);
putdata(ao,senal);
start(ao);
trigger(ao);
while strcmp(ao.Running,'On')
%para que espere a que termine la reproduccion para que continue con el programa principal
end; 

disp('presione enter para reproducir la senal resultante de la transformada inversa de la original'); 
disp('');
pause;
set(ao,'RepeatOutput',repeticiones);
putdata(ao,senal0);
start(ao);
trigger(ao);
while strcmp(ao.Running,'On')
end; 

disp('presione enter para reproducir la senal sin la informacion de fase'); 
pause;
set(ao,'RepeatOutput',repeticiones);
putdata(ao,senal1);
start(ao);
trigger(ao);
while strcmp(ao.Running,'On')
end; 

Cuando se reproduce la señal resultante de la transformada inversa aún con sus fases es exactamente igual a la señal original, pero la señal sin las fases de sus componentes de frecuencia suena como todos los sonidos presentes en la original pero mezclados entre sí, y en realidad lo están, todos están sonando al mismo tiempo.

La razón de que suenen más como ruido que como música (aunque es posible distinguir algunos tonos) es porque el ruido está compuesto de todas las componentes de frecuencia sonando al unísono, pero con la característica de que todas tienen la misma amplitud (lo que no ocurre con una canción).

A este tipo de ruido se le conoce como "ruido blanco", y con este programa se obtiene una buena aproximación.

Y esto es lo que le pasaría a la sinfonía de Beethoven si simplemente encendemos los 20000 generadores olvidando que unos deben ser encendidos después de otros.

 

 

www.000webhost.com