Vocoder LPC

Embed Size (px)

DESCRIPTION

vocoder

Citation preview

VOCODER LPC 03.06.09 PROYECTO PROCESADO DIGITAL DE VOZ Y AUDIO NDICE 1. Introduccin 2. Emisor 1. Codificador1 2. Codificador2 3. Receptor...... 1. Decodificador1 sntesis a partir del residuo 2. Decodificador2 sntesis a partir de los parmetros 4. Descripcin de cada rutina. 1. 2. 3. 4. 5. Funcin Funcin Funcin Funcin Funcin Vocoder Codificador1 Codificador2 Decodificador1 Decodificador25. Ejemplos de funcionamiento del programa y las diferentes rutinas... 1. 2. 3. 4. 5. Seal original, salida decodificador1 y error Seal original, salida decodificador 2 y error Pitch y vector sonoridad Sonora/Sorda autocorrelacin Seal original y Sonoridad6. Cdigo del programa.. 1.Introduccin El objetivo de este proyecto es implementar una codificacin de la seal de voz medi ante un vocoder LPC y realizar adems el proceso inverso, recuperando la seal sinte tizada. Los Vocoders (voice coder) tienen como objetivo preservar las caractersticas percep tualmente relevantes de la seal de voz. Para ello asumen un modelo simplificado d e produccin de voz. Se basan en modelos especficos de la seal de voz, identificando aspectos relevante s del espectro localizado de la seal de voz, es decir, explotan la baja sensibili dad del odo a la informacin de fase. Funcionamiento: Estimacin de los parmetros del modelo Codificacin y transmisin de los mismos Reconstruccin de la voz en el extremo receptor Requieren evaluacin subjetiva Calidad de comunicaciones en el rango 2.4 - 9.6 kb/s (hoy da se utilizan slo hasta 4.0 kb/s).En resumen: El primer codificador tipo LPC, que es la tcnica ms importante desarrollada en los ltimos 25 aos es: buen modelo acstico del tracto vocal cuando falla, todava retiene las propiedades perceptualmente importantes adecuada para realizaciones hardware Ventajas: calidad aceptable, baja tasa binaria, coste computacional moderado Inconveniente: modelo excesivamente simple Vocoder LPC: Parmetros a estimar: coeficientes del filtro decisin sorda/sonora pitch energa Asignacin de bits: coeficientes: 6 bits/coeficiente pitch: 6 bits energa (logaritmo): 5 bits decisin sorda/sonora: 1 bit 72 bits cada 20-30 ms.(2.4-4.8 kb/s) El diagrama de bloques general que vamos a seguir en nuestro proyecto es el sigu iente: CompF [pic] FIGURA1. Diagrama de bloques general del vocoder. Como vemos en este diagrama en el emisor hemos implementado dos codificadores qu e slo se diferencian en el enventanado (rectangular y haming respectivamente) y e n el receptor hemos implementado dos tipos de decodificadores (sntesis a partir d el residuo y sntesis a partir de los parmetros). Del codificador1 transmitiremos al decodificador1 para recuperar la seal de voz o riginal y del codificador2 transmitiremos al decodificador2 para recuperar la sea l de voz sintetizada. 2. Emisor Sabemos que el vocoder LPC es un codificador paramtrico, que caracteriza cada tra ma mediante una serie de parmetros a partir de los cuales consigue sintetizar la voz de nuevo. Estos parmetros son: - Sonoridad - Pitch - Energa de la seal - Respuesta al impulso lineal El emisor se divide en dos bloques, que tienen las siguientes funciones: Fase de anlisis Codificacin de parmetros La sonoridad, el Pitch y la energa se utilizan en la fase de anlisis y sntesis de la seal de excitacin mientras que la respuesta al impulso caracteriza al filtro del modelo. El diagrama de bloques a seguir es: Figura2.Diagrama de bloques del codificador Para realizar la divisin en tramas tomaremos segmentos de 30 ms de duracin. 2.1 Codificador 1 Los parmetros de la seal de entrada son la seal de voz (audio), la frecuencia de mu estreo (fs) y el nmero de bits (nbits). El filtrado LPC se realizar siguiendo el estndar americano LPC-10. La principal diferencia con el codificador 2 es el enventanado. En este codificador empleamos una ventana rectangular para conseguir que la seal de salida del decodificador 1 sea exactamente igual a la seal original. A continuacin se muestra el diagrama de bloques que sigue el codificador1: F Figura 3. Diagrama de bloques del codificador1 Las salidas del codificador vector_residuo y vector_lpc sern las entradas del dec odificador 1 que comentaremos ms adelante. 2.2 Codificador 2 Al igual que en el codificador 1 tenemos como parmetros de entrada, audio, fs, nb its. En este codificador2 utilizamos una ventana haming que es ms apropiada para la pr ediccin lineal. Los parmetros de salida que sern las entradas del decodificador2 son: Pitch vector_sonoridad vector_energiaE0 vector_indicesA continuacin se muestra el diagrama de bloques del codificador 2: Figura4. Diagrama de bloques del codificador 2. 3. Receptor Para realizar la decodificacin, es decir, la sntesis de la voz es necesario realiz ar el proceso inverso. En este proyecto implementaremos dos mtodos: 3.1 Decodificador 1 Sntesis a partir del residuo Como hemos comentado en el codificador 1 los parmetros de entrada del decodificad or 1 sern el vector_residuo que almacena todos los distintos valores de los resid uos de cada trama y el vector_lpc que almacena los valores de los coeficientes L PC de cada trama. El filtro LPC ser el inverso al utilizado en el anlisis. El diagrama de bloques a seguir es:[pic] Figura 5. Diagrama de bloques del Decodificador 1 En este modelo no existe prdida de informacin, por lo que la seal de salida (audio_ original), ser igual a la de entrada(audio). Sin embargo, este modelo no es el que se utiliza en la prctica ya que resulta muy costoso y poco eficiente. 3.2 Decodificador 2 Sntesis a partir de los parmetros Como podemos observar en el diagrama de bloques que se muestra a continuacin, la sntesis de la voz se realiza a partir de los parmetros obtenidos en el codificador 2. Este sistema debe funcionar de manera sncrona. Los parmetros de entrada son: Pitch Vector_sonoridad Vector_indices Vector_energiaA la salida obtendremos la voz sintetizada. El diagrama de bloques a seguir es el siguiente: [pic] Figura 6. Diagrama de bloques del Decodificador 2 4. Descripcin de cada rutina A continuacin mostramos un esquema general de las rutinas que se implementan en n uestro vocoder: [pic] 3.1 FUNCIN VOCODER: Esta es la funcin principal de nuestro programa: En primer lugar, lee la seal de voz, extryendo la frecuencia de muestreo y el nmer o de bits de la misma. Dentro de esta funcin llamaremos a las otras 4 funciones que conforman nuestro pr ograma de anlisis y sntesis que son: Codificador 1,Codificador 2,Decodificador 1,Decodificado 2. 3.2 FUNCIN CODIFICADOR1: Introducimos como parmetros de entrada la seal de audio,la frecuencia de muestreo y el n de bits (audio,fs,nbits). Definimos el n de muestras por trama como N=fs*30*10^-3. L=longitud de la seal de entrada. Inicializamos los vectores de salida pitch, vector_sonoridad, vector_residuo,vec tor_lpc,vector_energiaE0 donde almacenaremos los valores que queremos transmitir al receptor. A continuacin, mediante el comando floor redondeamos el n de tramas para que en ca so de no ser un n entero aproxime al n entero menor ms prximo. Inicializamos la variable j que utilizaremos como ndice en el bucle for para reco rrer cada trama de la seal. Realizamos el enventanado con una ventana rectangular de N muestras para consegu ir recuperar en el Decodificador 1 una seal exactamente igual a la original. Aplicamos seguidamente el filtro LPC de 10 parmetros y calculamos el valor del re siduo en cada trama.Estos valores quedan almacenados en vector_residuo. Y los valores de los parmetros lpc quedan almacenados en el vector_lpc que sern lo s dos parmetros que servirn como seales de entrada del decodificador1 . Calculamos la energa a corto plazo del residuo de cada trama mediante la frmula : Los valores de la energa sern almacenados en vector_energia. Eliminamos el valor medio de la seal para analizarla en banda base. Filtrado paso bajo: Calculamos la frecuencia de corte del filtro mediante la frmu la: Y lo aplicamos al valor medio de la seal de cada trama. A continuacin aplicamos el filtro lpc de 4 parmetros. Calculamos la autocorrelacin del residuo mediante la orden xcorr. Este parmetro lo utilizamos para buscar la amplitud y posicin de los dos picos mxim os que nos darn la frecuencia de pitch. Por ltimo realizamos el algoritmo de estudio de la sonoridad de cada trama: Para ello diferenciamos entre tramas sonoras y sordas y calculamos el pitch y la sonoridad para cada una de ellas. Estos valores son almacenados en vector_sonoridad y pitch respectivamente. 3.3 FUNCIN CODIFICADOR2: Esta funcin est implementada de manera similar a la funcin Codificador1 a excepcin d el enventanado. En este caso hemos utilizado una ventana Hamming dado que es ms apropiada para la prediccin lineal. Las salidas a transmitir al Decodificador 2 son: Pitch, vector_sonoridad, vector _energaE0 y vector_indices que en este caso es el que almacena los valores de los parmetros lpc obtenidos para cada trama. 3.4 FUNCIN DECODIFICADOR1: Tiene como parmetros de entrada las salidas del codificador1: vector_lpc y vector _residuo. Inicializamos el vector audio_original que almacenar la salida de la voz recupera da y definimos su tamao. Realizamos el filtrado inverso mediante el cual recuperamos la seal de voz y la a lmacenamos en el vector audio_original. 3.5 FUNCIN DECODIFICADOR2: Tiene como parmetros de entrada las salidas del Codificador2: Pitch,vector_sonori dad,vector_energiaE0 y vector_indices. Y a la salida obtenemos un vector voz_sintetizada que contiene la seal de audio r ecuperada. El proceso de recuperando comienza con un bucle for en el que estudiamos la sono ridad de la trama a analizar: - Si la trama es sorda: Le aplicaremos un generador de ruido aleatorio - Si la trama es sonora: Le aplicaremos un tren de pulsos. En ambos casos aplicaremos una ganancia segn hemos explicado en el diagrama de bl oques, que calculamos mediante la frmula: Y realizamos el filtrado inverso para obtener el residuo de cada trama. La voz sintetizada queda almacenada en la salida en el vector voz_sintetizada.5. Ejemplos de funcionamiento del programa y las diferentes rutinas 5.1 Seal original, salida decodificador1 y error [pic] [pic] Figura7. Seal original Figura8. Seal recuperado Dec1 [pic] Figura 9. Error Como podemos observar en las grficas que presentamos en la parte superior obtenem os la misma seal de audio a la salida del decodificador 1 que la que tenamos a la entrada del codificador, lo cual indica que se ha realizado el proceso de anlisis y sntesis correctamente. El error obtenido como resta de ambas seales es cero como muestra la figura 9. 5.2 Seal original, salida decodificador 2 y error En este ejemplo mostramos la seal de audio original y el resultado obtenido al co dificarla y decodificarla con el codificador y decodificador2. En este caso ha sido imposible recuperar totalmente la seal original ya que en e proceso de codificacin hemos realizado un filtrado paso bajo que nop hemos invert ido posteriormente y adems, los parmetros utilizados para la estimacin no son realm ente fiables ya que hemos aproximado la sonoridad de la trama como sonora o sord a y puede que en algunos casos sea mezcla de ambas. Vemos por tanto que la seal de error en este caso no es cero y no presenta un val or demasiado aceptable. [pic] [pic] Figura 10. Seal original Figura 11. Seal de voz sintetizada [pic] Figura 12. Seal de error 5.3 Pitch y vector sonoridad A continuacin presentamos un ejemplo del clculo de los valores del pitch para cada trama y la sonoridad de las mismas y vemos que se corresponden perfectamente la s tramas sordas tiene una frecuencia de pitch=0 que es exactamente lo que esperba mos. Por tanto podemos concluir que el algoritmo de la deteccin del pitch funciona cor rectamente. Figura 14. Pitch Figura 15. Vector sonoridad 5.4 Sonora/Sorda autocorrelacin Para comprobar si el decodificador 2 est funcionando correctamente hemos realizad o un estudio de una trama sorda y una sonora. Mirando en las grficas de las figuras 10,14 y 15 Seal original, Pitch y vector son oridad hemos deducido que la trama 25 es sorda y para comprobar que se ejecuta c orrectamente hemos calculado la autocorrelacin para esa trama concreta y hemos ob tenido como resultado la grfica representada en la figura 16 que indiscutiblement e se corresponde con la autocorrelacin de una trama sorda. Figura 16. Autocorrelacin trama sordaPor otra parte hemos buscado una trama sonora y hemos estudiado su autocorrelacin . En este caso hemos obtenido la grfica representada en la figura 17 que claramente es la autocorrelacin de una trama sonora. [pic] Figura 17. Autocorrelacin de una trama sonora 5.5 Seal original y Sonoridad Una buena forma de comprobar si el vector sonoridad est recogiendo correctamente los valores en el codificador 2 y ejecuta bien la sntesis de voz en el decodifica dor 2 es comparar la seal original con la sonoridad y ver que en las tramas en la s que claramente la seal original es sonora o sorda tambin lo es en la representac in de la sonoridad, es decir, 1 0 respectivamente. A continuacin podemos comprobar que esto se cumple satisfactoriamente. [pic] Figura 18. Seal original Figura 19. Vector sonoridad 6. Cdigo del programa FUNCIN VOCODER function vocoder(file); % Funcin principal que llama al resto de funciones del pr ograma [audio,fs,nbits]=wavread(file); % Leemos la seal de entrada [vector_residuo,vector_lpc]=codificador1(audio,fs,nbits); %Llamamos a la funcin Codificador1 con sus argumentos de entrad/salida pause(3) [audio_original]=decodificador1(vector_residuo,vector_lpc,fs); %Llamamos a la funcin decodificador1 con sus entradas/salidas pause(3) [pitch,vector_indices,vector_energiaE0,vector_sonoridad,N]=codificador2(audio,fs ,nbits); %Llamamos a la funcin Codificador2 pause(3) [voz_sintetizada]=decodificador2(pitch,vector_indices,vector_energiaE0,vector_so noridad,fs,N); %Llamamos a la funcin Decodificador2 end FUNCIN CODIFICADOR1 function[vector_residuo,vector_lpc]=codificador1(audio,fs,nbits); %definimos nue stra funcin con sus argumentos de entrada y de salida. N=round (fs*(30)*10^(-3)); %N=n de muestras que tomamos por trama L=length(audio); %longitud de la seal de audio pitch = []; %Inicializamos un vector de salida en el que guardamos los distintos valores calculados en el algoritmo de clculo del pitch vector_sonoridad = []; %inicializamos un vector que almacena los distintos resultados del anlisis de sonoridad de cada trama y nos dice si es sorda o sonora vector_residuo = []; %Inicializamos este vector que contendr los valores del residuo que transmitiremos al decodificador1 vector_lpc=[]; %Inicializamos un vector que almacena los parmetros lpc calculados para transmitirlos al decodificador1 vector_energiaE0 = []; %Inicializamos el vector que contiene los valores calculados de energa que transmitiremos al decodificador2%COMPLETAR SEAL DE VOZ %N= n muestras por trama %L=longitud de la seal de entrada ntramas=floor(L/N); %redondeamos el n de tramas j=0; for i=1:ntramas %Ejecutamos el algoritmos tantas iteraciones como tramas tenemos trama=audio(j+1:j+N); V=rectwin(N); % Aplicamos un filtrado con ventana rectangular trama1=trama.*V; %APLICAMOS LPC 10 f_lpc=lpc(trama1,10); %Calculamos los 10 parmetros lpc vector_lpc=[vector_lpc;f_lpc]; %Almacenamos los parmetros lpc en este vector para transmitirlos al decodificador1 residuo=filter(f_lpc,1,trama1); %Calculamos el valor del residuo en cada trama y lo almacenamos en vector _residuo para transmitirlo a decodificador1 vector_residuo=[vector_residuo residuo]; % ENERGIA A CORTO PLAZO energia= sum((residuo.^2)); %Calculamos la energa para cada trama y lo almacenamos en vector_energia vector_energiaE0=[vector_energiaE0,energia]; % ELIMINAR VALOR MEDIO DE LA SEAL valormedio=mean(trama1); %Eliminamos el valor medio de la seal para tenerla en banda base trama_vmedio =trama1-valormedio; % FILTRADO PASO BAJO fpb=(2/fs)*900; %Aplicamos un filtro paso bajo filtro_pb = fir1(25,fpb,'low'); filtro_pb2 = filtro_pb; seg_filt = filter(filtro_pb2,1,trama_vmedio); %APLICAMOS LPC 4 f_lpc2=lpc(seg_filt,4); %Calculamos ahora los coeficientes lpc4 y el residuo residuo2=filter(f_lpc2,1,seg_filt); % CALCULAMOS LA AUTOCORRELACION DEL RESIDUO residuo_corr = xcorr(residuo2); %Calculamos la autocorrelacin del residuo mediant e la orden xcorr % BUSCAMOS EL PICO MAXIMO(CENTRAL) [amp1,pos1]=max(residuo_corr); %Definimos amplitud y posicin de 2 picos consecutivos [amp2,pos2]=max(residuo_corr(pos1+round(fs*0.0025):pos1+round(fs*0.002)));%Trasl adamos el eje pos2=pos1+pos2+round(fs*0.0025); %Corregimos la traslacin que hemos hechoanteriormente % ESTUDIAMOS SONORIDAD if amp2 > 0.25*amp1 sonoridad = 1; % Es sonora frecpitch = pos2-pos1; %Calculamos la frec. de pitch en muestras else sonoridad = 0; %Si sonoridad=0 es sorda frecpitch = 0; end pitch = [pitch frecpitch]; %Almacenamos en este vector los distintos valores del pitch para cada trama vector_sonoridad = [vector_sonoridad sonoridad]; %Almacenamos los distintos valores de sonoridad para cada trama j=j+N; end sound(audio,fs); %Escuchamos la seal de audio original end FUNCIN DECODIFICADOR1 function[audio_original]=decodificador1(vector_residuo,vector_lpc,fs); %Definimo s la funcin con sus argumentos de entrada y de salida audio_original =[]; %Inicializamos el vector audio_original que contendr la seal d e audio decodificada [M1,N1]=size(vector_residuo); %Definimos el tamao de vector_residuo que es el vec tor donde tenemos almacenados los distintos valores del residuo para cada trama for i=1:N1 residuo_d=vector_residuo(:,i); param_lpc = vector_lpc(i,:); original = filter(1,param_lpc,residuo_d); %Realizamos un filtrado inverso para recuperar la seal de audio audio_original = [audio_original;original]; %Almacenamos la seal de audio recuperada en este vector end sound(audio_original,fs); %Escuchamos la seal de audio y comprobamos que es igual a la original end FUNCIN CODIFICADOR2 function[pitch,vector_indices,vector_energiaE0,vector_sonoridad,N]= codificador1 (audio,fs,nbits); %definimos nuestra funcin con sus argumentos de entrada y de salida. N=round (fs*(30)*10^(-3)); %N=n de muestras que tomamos por trama L=length(audio); %longitud de la seal de audiopitch = []; %Inicializamos un vector de salida en el que guardamos los distintos valores calculados en el algoritmo de clculo del pitch vector_sonoridad = []; %inicializamos un vector que almacena los distintos resultados del anlisis de sonoridad de cada trama y nos dice si es sorda o sonora vector_residuo = []; %Inicializamos este vector que contendr los valores del residuo que transmitiremos al decodificador2 vector_indices=[]; %Inicializamos un vector que almacena los parmetros lpc calculados para transmitirlos al decodificador2 vector_energiaE0 = []; %Inicializamos el vector que contiene los valores calculados de energa que transmitiremos al decodificador2 %COMPLETAR SEAL DE VOZ %N= n muestras por trama %L=longitud de la seal de entrada ntramas=floor(L/N); %redondeamos el n de tramas j=0; for i=1:ntramas %Ejecutamos el algoritmos tantas iteraciones como tramas tenemos trama=audio(j+1:j+N); V=hamming(N); % Aplicamos un filtrado con ventana hamming trama1=trama.*V; %APLICAMOS LPC 10 f_lpc=lpc(trama1,10); %Calculamos los 10 parmetros lpc vector_indices=[vector_lpc;f_lpc]; %Almacenamos los parmetros lpc en este vector para transmitirlos al decodificador2 residuo=filter(f_lpc,1,trama1); %Calculamos el valor del residuo en cada trama y lo almacenamos en vector _residuo para transmitirlo a decodificador2 vector_residuo=[vector_residuo residuo]; % ENERGIA A CORTO PLAZO energia= sum((residuo.^2)); %Calculamos la energa para cada trama y lo almacenamos en vector_energia vector_energiaE0=[vector_energiaE0,energia]; % ELIMINAR VALOR MEDIO DE LA SEAL valormedio=mean(trama1); %Eliminamos el valor medio de la seal para tenerla en banda base trama_vmedio =trama1-valormedio; % FILTRADO PASO BAJO fpb=(2/fs)*900; %Aplicamos un filtro paso bajo filtro_pb = fir1(25,fpb,'low'); filtro_pb2 = filtro_pb; seg_filt = filter(filtro_pb2,1,trama_vmedio); %APLICAMOS LPC 4 f_lpc2=lpc(seg_filt,4); %Calculamos ahora los coeficientes lpc4 y el residuo residuo2=filter(f_lpc2,1,seg_filt); % CALCULAMOS LA AUTOCORRELACION DEL RESIDUOresiduo_corr = xcorr(residuo2); %Calculamos la autocorrelacin del residuo mediant e la orden xcorr % BUSCAMOS EL PICO MAXIMO(CENTRAL) [amp1,pos1]=max(residuo_corr); %Definimos amplitud y posicin de 2 picos consecutivos [amp2,pos2]=max(residuo_corr(pos1+round(fs*0.0025):pos1+round(fs*0.002)));%Trasl adamos el eje pos2=pos1+pos2+round(fs*0.0025); %Corregimos la traslacin que hemos hecho anteriormente % ESTUDIAMOS SONORIDAD if amp2 > 0.25*amp1 sonoridad = 1; % Es sonora frecpitch = pos2-pos1; %Calculamos la frec. de pitch en muestras else sonoridad = 0; %Si sonoridad=0 es sorda frecpitch = 0; end pitch = [pitch frecpitch]; %Almacenamos en este vector los distintos valores del pitch para cada trama vector_sonoridad = [vector_sonoridad sonoridad]; %Almacenamos los distintos valores de sonoridad para cada trama j=j+N; end sound(audio,fs); %Escuchamos la seal de audio original end FUNCIN DECODIFICADOR2 function[voz_sintetizada]=decodificador2(pitch,vector_indices,vector_energiaE0,v ector_sonoridad,fs,N); %Definimos la funcin con sus argumentos de entrada y de salida pause(4) voz_sintetizada = []; %Inicializamos el vector que contendr el resultado de la vo z sintetizada a la salida de este decodificador 2 for i=1:length(pitch) %Entramos en el bucle que hemos creado para ir viendo si l a trama es sorda o sonora y aplicarle como excitacin ruido aleatorio o un tren de pulsos respectivamente if (vector_sonoridad(1,i) == 0) % Si es sordo la seal de excitacin ser un generador de ruido aleatorio ruido = rand(1,N); G=vector_energiaE0(1,i)/(sum(ruido.^2)); %Le aplicamos la ganancia G ruido1 = ruido.*sqrt(G); residuo = filter(1,vector_indices(i,:),ruido1);%Obtenemos el residuo mediante filtradoelse tren = zeros(1,N); %Si la trama es sonora la excitacin ser un tren de pulsos for j=1:pitch(i):N %Creamos el tren de pulsos tren(j)=1; end G = (vector_energiaE0(1,i))/((sum(tren).^2)); %Aplicamos la ganancia G tren1 = tren.*sqrt(G); residuo = filter(1,vector_indices(i,:),tren1); %Obtenemos el residuo mediante filtrado end voz_sintetizada = [voz_sintetizada residuo]; %En este vector tenemos almacenada la seal de salida que contiene la voz sintetizada end sound(voz_sintetizada,fs); %Escuchamos la voz sintetizada normalizada % error2=audio-voz_sintetizada; end ----------------------VOCODER CODIFICADOR1 DECODIFICADOR 1 CODIFICADOR 2 DEC DECODIFICADOR2 Audio original Voz sintetizada Vector_residuo Vector_lpc Vector_indices Vector_EnergiaE0 Vector_sonoridad Pitch Audio (Seal de entrada) Fs nbits Audio Fs nbits G=sqrt(E1/E0) FPB = (2/fs)*900 HzE Energa = residuo^2