Vous êtes sur la page 1sur 21

Universidad de Málaga

Sonido e Imagen

Fundamentos de Audio

Práctica 1

Audio Digital

José Fernández Sánchez


Apartado 0. Manejo básico de señales de audio

[audio,fs] = audioread('queen_corto.wav');
sound(audio,fs/2)
sound(audio,2*fs)

Con las anteriores líneas de código podremos comenzar a analizar audios. Con la función
audioread obtenemos la frecuencia de muestreo fs propia del archivo de audio que leemos.
Luego con sound se podrá escuchar dicho audio con fs. De modo que cuando disminuimos fs, el
periodo en el que aparece cada muestra, Ts, será mayor creando un notorio efecto en el audio
el cual se reproducirá ralentizado y por ello una tonalidad más grave. Caso inverso que ocurre
al aumentar fs¸ reproduciendo el audio más rápido y agudo.

0.2. Generar tono 440Hz y visualizar su especto


fs=44100;
t=0:1/fs:2;
tono440=sin(2*pi*440*t);

TFtono=fft(tono440); %transformada de Fourier

%Definimos parámetro para la correcta representacion


L=length(tono440); f=fs*(0:(L/2-1))/L;

plot(f,abs(TFtono(:,1:length(f))))%plot representa TFtono respecto a f

xlabel('f(Hz)'), axis([0 1000 0 5e4]) %caracterizamos el eje ‘x’ de la


xlabel('f(Hz)'), axis([0 1000 0 5e1]) %reajustamos el eje ‘x’

Generamos el segundo y tercer armónico del tono anterior.


Representamos su suma en la figura 0.1.

fs=44100;
t=0:1/fs:2;
tono440=sin(2*pi*440*t);
tono440segundo=sin(2*pi*2*440*t);
tono440tercero=sin(2*pi*3*440*t);
sumaArmonicos = tono440segundo + tono440tercero;
TFarmonicos=fft(sumaArmonicos);
L=length(sumaArmonicos); f=fs*(0:(L/2-1))/L;
plot(f,abs(TFarmonicos(:,1:length(f))))
xlabel('f(Hz)'), axis([0 2000 0 5e2])

figura 0.1. Espectro positivo de los dos armónicos


0.3. Forma de onda en tiempo y espectro de algunas señales

Analizaremos diferentes sonidos para saber si son diferenciables observando la caracterización


de su representación temporal y en frecuencia. Utilizaremos el siguiente código cambiando el
archivo que se utiliza en la función ‘audioread’.

close all;
[audio,fs]=audioread('notapiano.wav');
sound(audio,fs)

figure(1);plot(audio) %dos colores si está en estéreo

TFaudio=fft(audio); L=length(audio);

figure(2); espectro_centrado(audio,fs);

figura 0.3.1. violín

figura 0.3.2. piano


figura 0.3.3. Charlie

Como era de espera, la gran característica que diferencia a cada sonido, instrumento, es la
composición de los armónicos. Siendo el piano el más selectivo en frecuencia casi parece
generar un tono puro como obsevarmos en la figura 0.3.2 mientras que los otros se aprecian
más complejos. En el violín, figura 0.3.1, se podría deducir que es un instrumento virtual ya
que los armónicos se muestran solo en unas frecuencias determinadas cosa que parece
antinatural sabiendo la cantidad que componentes en la construcción de un violín que influye
en la coloración de sus armónicos. En el caso del Charlie, figura 0.3.3, no podemos identificar
con claridad la nota que se está tocando como si podríamos en los dos casos anteriores. Se de
a que el sonido del Charlie no se rige por la misma naturaleza para formar los armónicos ya
que, por ejemplo, físicamente está vibrando una superficie que se puede considerar
tridimensional mientras que en instrumentos de cuerdas, esta se puede considerar
bidimensional.

Apartado 1. Muestreo
En este apartado vamos muestrear señales a diferentes velocidades de muestreo y se va a ver
el efecto del muestreo sobre la señal y su espectro. Todo el código Matlab está incluido en el
archivo [A1_submuestreoAudio.m].
1.1. Vamos a simular que tenemos una señal de audio continua.
t=0:1/176400:0.2;
fs=176400;
y=sin(2*pi*t*400)+sin(2*pi*t*1500)+sin(2*pi*t*4200)+sin(2*pi*t*5000)+sin(2*pi*t*10000);

figure(1); plot(t,y); title('señal en tiempo'),xlabel('t')


figure(2); espectro_centrado(y,fs);
1.2. Vamos a convertir esa señal en otra, equivalente, pero muestreada a fs=44100Hz.
%% 1.2 Submuestreo a 44100 Hz

figure(3);hold on
fs=fs1;
t=0:1/fs:((L/fs)-1/fs); stem(t,y);
fs=fs0;
t=0:1/fs:((L/fs)-1/fs); stem(t,y);
title('señal en tiempo'),xlabel('t');

hold off;

figure(4);
hold on
espectro_centrado(y,fs0); espectro_centrado(y,fs1);
hold off;

Figura 1.2.1. Representación temporal

Figura 1.2.2. Representación en frecuencia

Observando la figura 1.2.1 vemos como la señal submuestreada, representada en color azul,
tiene mayor duración. Considerando que se trata de la misma señal, ese efecto de haber sido
ensanchado en el tiempo implica que al escucharla será igual que la original pero sonará más
grave, de modo que estaremos perdiendo frecuencias agudas.

fs0=176400 fs1=44100 fs2=11025

A medida que reducimos la frecuencia de


muestreo, el filtro en el espectro se hace más
selectivo y deja pasar menos frecuencia. Por
ello para fs0 deja pasar como frecuencia
máxima fs0/2= 88200Hz.

De modo que para una frecuencia de


muestreo baja, se rechazan las frecuencias
altas y perdemos información, por ello nuestra
señal suena más grave que la original.
Conforme más reduzcamos la frecuencia a la que se submuestrea la señal, más notorio será el
efecto de aliasing.

1.3. Muestrea ahora la señal original con fs=11025Hz.


%% 1.3 Submuestreo a 11025 Hz

y2=sin(2*pi*t*400)+sin(2*pi*t*1500)+sin(2*pi*t*4200)+sin(2*pi*t*5000);

figure(5);hold on
fs=fs2;
t=0:1/fs:((L/fs)-1/fs); stem(t,y);
fs=fs0;
t=0:1/fs:((L/fs)-1/fs); stem(t,y);
title('señal en tiempo'),xlabel('t');

hold off;

figure(6);
hold on
espectro_centrado(y,fs0); espectro_centrado(y,fs2);
hold off;

Figura 1.3.1. Representación temporal

Figura 1.3.2. Representación en frecuencia

Repetimos con fs2 para y2. Ahora submuestrear con fs2 no tiene una repercusión tan notoria
ya que la señal original no está compuesta por frecuencias tan altas las cuales se filtra y
rechazan como comprobamos en la figura 1.3.4.
Figura 1.3.3. Representación temporal

Figura 1.3.4. Representación en frecuencia

1.4. Efectos sobre una señal "real"

Repetiremos el proceso para una señal de audio real leida la cual está caracterizada por su
propia frecuencia de audio fs0. Submuestrearemos para diferentes frecuencias para
comprobar los efectos que sufrieron nuestra señal en las pruebas anteriores.
%% 1.4 Submuestreo de señal 'real’
[audio,fs0] = audioread('queen_corto.wav'); %obtenemos fs0 = 44100Hz

L=length(audio);
fs1=5512;
fs2= 11025;
fs3= 22050;

figure(7);hold on
fs=fs1;
t=0:1/fs:((L/fs)-1/fs); stem(t,audio);
fs=fs2;
t=0:1/fs:((L/fs)-1/fs); stem(t,audio);
fs=fs3;
t=0:1/fs:((L/fs)-1/fs); stem(t,audio);
fs=fs0;
t=0:1/fs:((L/fs)-1/fs); stem(t,audio);
title('señal en tiempo'),xlabel('t');

hold off;

figure(8);hold on

espectro_centrado(audio,fs0);
espectro_centrado(audio,fs3);
espectro_centrado(audio,fs2);
espectro_centrado(audio,fs1);
hold off;
Figura 1.4.1. Representación temporal

Figura 1.4.2. Representación en frecuencia

En este caso ningún submuestreo es favorable ya que para fs0 del audio siendo 44.1kHz, las
frecuencias de muestreo con las que experimentamos no cubren todo el ancho de banda para
audio que vemos en la figura 1.4.2. de color azul en contraste con las del resto que se va
estrechando el ancho de banda a medida que disminuimos la frecuencia de muestreo. En el
caso de fs1=5512 representado en color violeta, habremos perdido gran parte de la
información frecuencial de la señal audio.
Apartado 2.

Para analizar la señal en su espectro y apreciar el efecto de aliasing aplicaremos una


conversión de la unidad de frecuencia, y representaremos replicas del epectro para diferentes
frecuencias de muestreo al aplicar el factor de diezmado M a la frecuencia original. El código
utilizado se halla en [A2_espectrosTipo].

2.1. Espectros asociados a la señal continua y la señal de audio discreta.


[audio,fs]= audioread('audio_apartado2_1.wav');

%% Espectro señal continua_____Hz

figure(1)
[Ym,f]=espectro_centrado(audio,fs);

%% Espectro señal continua muestreada______'Xs(jomega'

figure(2)
hold on;
title('Xs(jomega');
plot(f,abs(Ym));
xlabel('omega');

plot(f+fs,abs(Ym)); % Muestra espectro continua y 2 replicas


plot(f-fs,abs(Ym));

%% Espectro señal discreta ____'X(e^jw)'

figure(3)
hold on;
title('X(e^jw)');

w = 2*pi*f;
Ts = 1/fs;
omega = w*Ts; % Cambio a dominio de (omegaT)

plot(omega,abs(Ym),'r');
xlabel('omegaT'); %w=omega*T

plot(omega+2*pi,abs(Ym));
plot(omega-2*pi,abs(Ym));
2.2. Reconstrucción de una señal discreta a partir de sus muestras.
fs=11025;
t= 0:1/fs:0.02;

audio_disc= sin(2*pi*t*440)+cos(2*pi*t*620)+sin(2*pi*t*1500)+
cos(2*pi*t*2250);

stem(t,audio_disc);
2.3. Representaremos el espectro de nuestra señal en distintas unidades. La señal será
diezmada para apreciar cómo influye el efecto de Aliasing.

El código Matlab usado está contenido en [A2_subm_Aliasing.m].


%% SUBMUESTREO de una señal con fmax=10kHz. Analisis de ALIASING

[y,fs]=audioread('audio_apartado2_2.wav');
[audio,f]=espectro_centrado(y,fs);

%t=0:1/fs:0.2; %intervalo muestreo


Ts=1/fs;

% Espectro señal continua_____Xc(jOmega)


figure(1);hold on;
title('Xs(jomega)');
plot(f,abs(audio));
xlabel('omega');
plot(f+fs,abs(audio)); plot(f-fs,abs(audio)); hold off;

w = 2*pi*f;
Ts = 1/fs;
omega = w*Ts; % Cambio a dominio de (omegaT)

figure(2);hold on;
title('X(e^jw)');
plot(omega,abs(audio),'r');
xlabel('omegaT');
plot(omega+2*pi,abs(audio)); plot(omega-2*pi,abs(audio)); hold off;
Figura 2.3.1. Representación frecuencial

%% 2.3 SUBMUESTREAR LA SEÑAL ANTERIOR CON UN FACTOR M=2

M2=2;
T2=M2*Ts; %Diezmamos
fs2=1/T2;
omega2 = w*T2;

% Espectro señal continua_____Xc(jOmega)


figure(3);hold on;
title('Xd(jomega)');
plot(f,abs(audio));
xlabel('omega2´');
plot(f+fs2,abs(audio)); plot(f-fs2,abs(audio)); hold off;

figure(4);hold on;
title('Xd(e^jw)');
plot(omega2,abs(audio));
xlabel('omegaT2´'); %w=omega*T
plot(omega2+2*pi,abs(audio)); plot(omega2-2*pi,abs(audio)); hold off;

Figura 2.3.2. Representación frecuencial

%% 2.4 SUBMUESTREAR LA SEÑAL ANTERIOR CON UN FACTOR M=3

M3=3;
T3=M3*Ts; %Diezmamos
fs3=1/T3;
omega3 = w*T3;

% Espectro señal continua_____Xc(jOmega)


figure(5);hold on;
title('Xd(jomega)');
plot(f,abs(audio));
xlabel('omega3´');
plot(f+fs3,abs(audio)); plot(f-fs3,abs(audio)); hold off;

figure(6);hold on;
title('Xd(e^jw)');
plot(omega3,abs(audio));
xlabel('omegaT3´');
plot(omega3+2*pi,abs(audio)); plot(omega3-2*pi,abs(audio)); hold off;
Figura 2.4. Representación frecuencial

Nuestra señal ha sido diezmada por el factor M el cual modifica el valor del periodo al que se
muestrea la señal. Cuando M aumenta, dicho periodo se hace mayor y a la inversa, la
frecuencia de muestreo disminuye. En este caso, el espectro de las réplicas de la señal se
estarán aproximando entre ellas como comprobamos en la figura 2.3.2 con respecto a la
figura 2.3.1. Cuanto más aumente M más se acercarán hasta el punto en que empiecen a
solaparse y empecemos a apreciar el efecto del Aliasing donde no podremos recuperar la señal
original aplicando un filtro ya que no se cumplió la condición de frecuencia máxima de Nyquist,
efecto claramente apreciable en el espectro de la figura 2.4.

Apartado 3. Cuantificación
El proceso que transforma una señal analógica a digital es la cuantificación. A partir del
número de bist con los que se trabaja delimitamos el numero de niveles y los valores
que los delimitan para asignarle un valor binario a los valores continuos de la analógica
original que se encuandra dentro de los márgenes de un nivel de la cuantificación.
Usamos el código Matlab de [A3__cuantificacion.m] donde representamos la
cuantificación del tipo ‘midtreat’ y ‘midrise’ por medio de la función [cuantificar.m].

[cuantificar.m]____________________________________________________
%% Funcion 'cuantificar' para procesa el nivel de la señal analogica y
%% asignarle un nivel con su determinado valor de cuantificacion.
%% Definimos 8 niveles de cuantificacion con 3 bits
% 'y' es la señal original continua que deseamos cuantificar
% 'A'es la Amplitud de la señal 'y' para la correcion y ajuste con los niveles de
cuantificacion
% Tipo toma el valor '0' si queremos cuantificacion midrise o valor '1' si es midtreat

function ycuantf = cuantificar(y,A,tipo)

y=y/A;
n_bits = 3; %% 8 valores posibles
yinicial=y;

if tipo==1
%% Cuantificacion 'midtreat' {se incluye el '0'}
x = find(abs(y) >= 0 & abs(y) <= 0.125);
y(x) = 0;
x = find(abs(y) > 0.125 & abs(y) <= 0.25);
y(x) = 0.25;
x = find(abs(y) > 0.25 & abs(y) <= 0.375);
y(x) = 0.25;
x = find(abs(y) > 0.375 & abs(y) <= 0.5);
y(x) = 0.5;
x = find(abs(y) > 0.5 & abs(y) <= 0.625);
y(x) = 0.5;
x = find(abs(y) > 0.625 & abs(y) <= 0.75);
y(x) = 0.75;
x = find(abs(y) > 0.75 & abs(y) <= 0.875);
y(x) = 0.75;
x = find(abs(y) > 0.875 & abs(y) <= 1);
y(x) = 1;
x = find(abs(y) > 1);
y(x) = 1;
s = sign(yinicial);

ycuantf = y .* s;

elseif tipo == 0
%% Cuantificacion 'midrise' {se excluye el 0}
y=yinicial;

x = find(abs(y) >= 0 & abs(y) <= 0.125);


y(x) = 0.125;
x = find(abs(y) > 0.125 & abs(y) <= 0.25);
y(x) = 0.125;
x = find(abs(y) > 0.25 & abs(y) <= 0.375);
y(x) = 0.375;
x = find(abs(y) > 0.375 & abs(y) <= 0.5);
y(x) = 0.375;
x = find(abs(y) > 0.5 & abs(y) <= 0.625);
y(x) = 0.625;
x = find(abs(y) > 0.625 & abs(y) <= 0.75);
y(x) = 0.625;
x = find(abs(y) > 0.75 & abs(y) <= 0.875);
y(x) = 0.875;
x = find(abs(y) > 0.875 & abs(y) <= 1);
y(x) = 1;
x = find(abs(y) > 1);
y(x) = 1;
s2 = sign(yinicial);
ycuantf = y .* s2;

end
_____________________________________________________________
Observamos como para el caso de midtreat el proceso acarrea menor error como se aprecia en
la figura 3.3 ya que cuando la señal a cuantificar toma el valor 0, este no es obligado a
tomar un valor distinto de cero ya que en ‘midtreat’ los niveles no se organizan de
manera simétrica, de modo que hay más niveles para los valores negativos, pero se
asigna un nivel para el valor ‘0’ o próximos.
%% 3.1 CUANTIFICACION DE SEÑAL GENERADA
fs = 44100;
t = 0:1/fs:10/400;
y=sin(2*pi*t*400)+sin(2*pi*t*1500)+sin(2*pi*t*4200); %%Experimento con señal generada
(3.1)
y=y/3;
n_bits = 3; %% 8 valores posibles al utilizar 3 bits

ymidtreat=cuantificar(y,1,1);
ymidrise=cuantificar(y,1,0);

figure(1);
subplot(2,1,1);
plot(t,y)
title('señal original');
subplot(2,1,2);
plot(t,ymidtreat)
title('señal cuantificada midtreat');
figure(2);
subplot(2,1,1); plot(t,y)
title('señal original');
subplot(2,1,2); plot(t,ymidrise)
title('señal cuantificada midrise');

Ye1= ymidtreat-y; %Definimos la señal del error de cuantificacion


Ye2= ymidrise-y;

figure(3);
subplot(2,1,1); plot(t,Ye1)
title('error cuantificacion midtreat');
subplot(2,1,2); plot(t,Ye2)
title('error cuantificacion midrise');

Figura 3.1.1. Representación temporal con método midtreat

Figura 3.1.2. Representación temporal con método midrise

Figura 3.1.3. Representación temporal del Error de Cuantificación


3.2. Cuantificación de una señal real

Repetimos el proceso anterior para una señal de audio real. Se presentan errores más notorios
ya que la señal es más compleja y necesitaremos un numero infinito de niveles o cada uno de
ellos con un margen suficientemente pequeño para que no haya cambios abruptos y la señal
se represente con una forma más natural. No es nuestro caso ya que con solo 3 bits solo
podemos definir 8 niveles y luego la señal presentará una forma cuadrada sufriendo el efecto
de la cuantificación la cual también es notoria al escucharla donde se aprecia un ruido
granulado de fondo.
%% 3.2 CUANTIFICACION DE SEÑAL AUDIO REAL
[audio,fs]= audioread('queen_corto.wav'); %%Experimento con audio real (3.2)
L=length(audio);
t = 0:1/fs:((L/fs)-1/fs);
audmidtreat=cuantificar(audio,1,1);
audmidrise=cuantificar(audio,1,0);

figure(4);
subplot(2,1,1);
plot(t,audio)
title('señal original');
subplot(2,1,2);
plot(t,audmidtreat)
title('señal cuantificada midtreat');

figure(5);
subplot(2,1,1);
plot(t,audio)
title('señal original');
subplot(2,1,2);
plot(t,audmidrise)
title('señal cuantificada midrise');

Aude1= audmidtreat-audio; %Definimos la señal del error de cuantificacion


Aude2= audmidrise-audio;

figure(6);
subplot(2,1,1);
plot(t,Aude1)
title('error cuantificacion midtreat');
subplot(2,1,2);
plot(t,Aude2)
title('error cuantificacion midrise');

Figura 3.2.1. Representación temporal con método midtreat


Figura 3.2.2. Representación temporal con método midrise

Figura 3.2.3. Representación temporal del Error de Cuantificación

Apartado 4. Dither
Desarrollamos el proceso de aplicar dither para corrección en señales cuantificadas. Utilizamos
el código Matlab contenido en [A4_Dither.m] donde se hace uso de la función [cuantificar.m]
para contener todas las etapas del proceso el cual consiste en generar una señal la cual será
cuantificada y se le sumará el ruido generado con la función [genera_dither.m] que es
dependiente de un parámetro, la forma de la señal ruido. Experimentaremos el proceso para
distintas formas de ruido y veremos cómo se desarrolla nuestra señal y el error que resulta.

Analizamos los resultados de aplicar cuantificación a una señal sinusoidal corregida con dither
para distintos tipos de ruido.

En el caso de usa el ruido ‘shaped’ cuya señal presenta una forma mas uniforme en el tiempo,
acarrea mayor error y amplitud en las frecuencias propias a dicho ruido como comprobamos
en el espectrograma figura 4.3.
Sin embargo, dicha amplitud de las frecuencias propias al ruido usado para el dither se ve
disminuido incluso inapreciable en el caso de utilizar ruido ‘triangle’, figura 4.5, ya que su
forma en tiempo se asemeja más a la señal que se forma con la función seno, al igual que
nuestra señal generada. De modo que en este caso favorece más aplicar un ruido ‘triangle’
para el dither.

figura 4.1

figura 4.2
Tipo ruido: shaped

figura 4.3. Espectro de la señal Cuantificada y de la señal Cuantificada con Dither

Tipo ruido: triangle

figura 4.4.
figura 4.5. Espectro de la señal Cuantificada y de la señal Cuantificada con Dither

Vous aimerez peut-être aussi