• Nenhum resultado encontrado

5.7 RESULTADOS UTILIZANDO SOFTWARE DE TERCEIROS

5.7.1 Multi Layer Perceptron

Tabela 11 Resultados com rede MLP

Método de extração Nós na camada escondida Total de conexões Média de acertos STFT (35 divisões) 3 184 35.00% STFT (35 divisões) 5 294 78.13% STFT (35 divisões) 10 569 92.50% STFT (35 divisões) 25 1394 93.13% STFT (35 divisões) 70 3869 95.63%

Figura 5.18 Curva de aprendizado do MLP com

6 Conclusões

Duas técnicas para análise do sinal de voz foram abordadas neste trabalho: uma que faz a decomposição em funções de base senoidais e pressupõe que o sinal de voz é estacionário – o que não é bem verdade (Long, 1996); outra que faz a decomposição em funções de base com energia finita no tempo (Wavelets) sendo mais precisa na representação de características transientes.

Os resultados obtidos não indicam superioridade absoluta de alguma das duas técnicas. Enquanto o melhor resultado obtido pela rede neural artificial implementada foi usando a transformada Wavelet durante a extração de características (acerto de 96,39%), o melhor resultado apresentado pelos algorítmos de redes neurais do SAS foi usando STFT na fase de extração (acerto de 97,15%).

Quanto à topologia da rede neural, conclui-se que o uso de uma rede multi-camadas não é interessante para este problema. Os resultados mostram (seção 5.7.1) que são necessários muitos nós na camada escondida (conseqüentemente muitos pesos e muito processamento gasto da retropropagação dos erros) para se obter o poder de representação alcançado pelas redes de camada única.

A função de ativação usada, multi-logística, foi responsável tanto por um aumento na taxa de classificação correta da rede (já que interfere no processo de ajuste dos pesos) como na precisão dos valores de saída (erro médio muito menor). Tal nível de precisão permite que se adote um critério para decidir quando a rede foi ou não capaz de identificar a palavra com um nível de confiança adequado. Observe na tabela 9 como a intersecção entre os valores de saída para os casos em que a rede classificou corretamente e incorretamente ou é muito pequena ou sequer existe.

Outra vantagem da rede conforme implementada é que não ocorre o supertreinamento, como nas redes MLP. Observe a seção 5.6 onde os resultados são mostrados para um treinamento de dez mil épocas. Quanto mais épocas, mais a rede reduz seu erro médio para o conjunto de treinamento, e mais precisa se torna ao aplicarmos o conjunto de teste (novas ocorrências). Quanto à regra de aprendizado, a função de erro de Bernoulli se mostrou uma forma mais adequada de corrigir os pesos. Apesar de não abordarmos nos resultados, o método LMS e função de ativação linear (regra delta) leva muito mais épocas para convergir a um resultado satisfatório (e sem a mesma precisão), necessitando que se utilize uma taxa de treinamento dezenas de vezes menor.

Ainda quanto aos métodos de extração, observou-se que a extração STFT com definição de cinco sub-bandas foi superior ao cálculo da centróide do espectro de cada frame. Com a transformada Wavelet, dos dois métodos de divisão das sub-bandas de coeficientes de detalhe, o primeiro (numéro fixo de coeficientes) foi ligeiramente superior em todos os testes realizados com a rede neural implementada. No teste realizado com o SAS, o segundo método foi ligeiramente superior (93,82% de acertos), porém não atingiu o mesmo nível da rede neural implementada.

A utilização de redes neurais no reconhecimento de palavras isoladas se mostrou não só possível como extremamente eficaz. Um dos temas a se trabalhar futuramente é o teste com coeficientes Wavelet que possam ser mais adequados para modelagem da voz, especificamente sons vocálicos, que apresentam algum nível de periodicidade. Outra possibilidade é o uso da rede neural para o reconhecimento de fonemas de forma independente de locutor.

REFERÊNCIAS

Barone, D. A. "Projeto Revox". Universidade de Caxias do Sul. Centro de Ciências Exatas e Tecnologia, 1999. <http://ccet.ucs.br/pesquisa/projetos/revox/> acessado em 8 jul. 2006 Brierley, P. “Back Propagation Weight Update Rule”. Sem data.

<http://www.philbrierley.com/code/bpproof.html>. Acesso em 8 jul. 2006. Chaplais, F. “A WAVELET TOUR OF SIGNAL PROCESSING BY STÉPHANE

MALLAT. Academic Press, 1998. A SHORT PRESENTATION BY F. CHAPLAIS”. February 2, 1999.

<http://cas.ensmp.fr/~chaplais/Wavetour_presentation/Wavetour_presentation_US.html >. Acessado em 13 jul. 2006.

Chow, M. & Goode, P. “Bernoulli Error Measure Approach to Train Feedforward Artificial Neural Networks for Classification Problems”. 0-7803-1901-X/94 IEEE 1994. pp.44-49.

Cook, P.R. Tzanetakis, G. Essl, G. “Audio Analysis using the Discrete Wavelet Transform”, In Cook, P.R. “Audio Analysis using the Discrete Wavelet

Transform”, In Proc. WSES Int. Conf. Acoustics. <www.cs.princeton.edu/~gessl/CV- online.pdf>

Dovicchi, J. C. L. e Alves, J. B. M. “Functional Programming as a Natural Choice for Spectral Centroid Analysis in Digital Signal Processing (DSP)” Enviado ao Journal of Functional Programming.

http://turing.rexlab.ufsc.br/page/papers-jcd/centroide-jfp.ps. Acesso em 8 jul. 2006.

Dovicchi, J. C. L. “Novos Coeficientes Wavelets Baseados em Intervalos Musicais para a Análise de Timbres de Instrumentos Acústicos”, Tese apresentada para obtenção de título de Doutor em Engenharia Elétrica, Universidade Federal de Uberlândia,

Uberlândia, MG, Brasil, 171 pp., 1999. Disponível em:

http://turing.rexlab.ufsc.br/page/papers-jcd/douttese.ps. Acesso em 8 jul. 2006.

Dovicchi, J. C. L. Carrijo, G. Lima, L. "Short Time Fourier Transforms And Wavelets: A Combined Technique For Musical Signal Analysis" In: Conference on Mathematical and Computational Methods in Music, 1999, Viena, Diderot´99. Viena - Austria: , 1999. < http://turing.rexlab.ufsc.br/page/papers-jcd/fft-wav.ps>

Goya, D. H. “Tecnologia do Reconhecimento de Voz”. Revista PCWord. Acessado em set. 2002. http://pcworld.uol.com.br/pcw/testes/index_categoria?categ=tecno_hard

Hebb, D. O. 1988. The organization of behavior. In Neurocomputing: Foundations of Research, J. A. Anderson and E. Rosenfeld, Eds. MIT Press, Cambridge, MA, 43-54.

IBM. “IBM Home Page Reader 3.04”. 2006a. Acessado em jun. 2006. <http://www- 3.ibm.com/able/solution_offerings/hpr.html>

IBM. “Embedded ViaVoice, Enterprise Edition”. 2006b. Acessado em jun. 2006.

<http://www-306.ibm.com/software/pervasive/embedded_viavoice_enterprise/about/> Ynoguti, C. A. "Transformada Discreta de Fourier". Instituto Nacional de

Telecomunicações. Santa Rita do Sapucaí - Minas Gerais - Brasil. Set. 2004 <http://www.inatel.br/docentes/ynoguti/e724/DFT.pdf>

Kaplan, I “Spectral Analysis and Filtering with the Wavelet Transform”. August 2002. http://www.bearcave.com/misl/misl_tech/wavelets/freq/index.html. Acessado em 16 jul. 2006.

Kovács, Z. L. Redes Neurais Artificiais: Fundamentos e Aplicações. Segunda Edição, Collegium Cognitio, 1996.

Kröse, B., & Smagt, P. “An Introduction to Neural Networks”. Oitava edição, Universidade de Amsterdã, 1996. http://www.gmd.de/ftp/div/documents/neuroprose/neuro-intro.ps.gz Lima, P. C. "Wavelets: uma introdução". Departamento de Matemática - ICEX - UFMG.

Matemática Universitária, Nº33 (2002) , 13-44.

<http://www.mat.ufmg.br/%7Elima/artigos/rmu33.pdf>

Long, C.J. & Datta, S. “Wavelet Based Feature Extraction for Phoneme Recognition”. PROC. ICSLP 1996, pp. 264-267.

http://www.asel.udel.edu/icslp/cdrom/vol1/239/a239.pdf

McCulloch, W. S. & Pitts, W. 1988. “A logical calculus of the ideas immanent in nervous activity”. In Neurocomputing: Foundations of Research, J. A. Anderson and E. Rosenfeld, Eds. MIT Press, Cambridge, MA, 15-27.

Minsky, M. & Papert, S. 1988. “Perceptrons”. In Neurocomputing: Foundations of Research, J. A. Anderson and E. Rosenfeld, Eds. MIT Press, Cambridge, MA, 157-169.

Nascimento, C. L. Artificial Neural Networks in Control and Optimization. Doctor Thesis. University of Manchester. Manchester, 1994.

Parreira, W. D. "Reconhecimento de Locutor pela Voz usando o Classificador Polinomial e Quantizaçãoo Vetorial". Dissertação de mestrado. Faculdade de Engenharia Elétrica, UFU, 38400-902, Uberlândia, MG, abr. 2005.

Patterson, D. W. “Artificial Neural Networks: Theory and Applications”. Prentice Hall, 1995.

Reza, A. M. “Wavelet Characteristics.What Wavelet Should I use?”. Oct. 19, 1999. WHITE PAPER, Spire Lab, UWM.

Sarle, W. “What is a softmax activation function?”. Jun. 2004 <http://www.faqs.org/faqs/ai- faq/neural-nets/part2/section-12.html>

Schniter, P. “Short-time Fourier Transform”. Version 2.13: 2005/10/05 15:21:14.374 GMT-5 Connexions module: m10417. Creative Commons.

<http://cnx.rice.edu/content/m10417/latest/>

Schubert, E. Wolfe, J. Tarnopolsky, "A. Spectral centroid and timbre in complex, multiple instrumental textures". University of New South Wales, Sydney, Australia. Ago. 2004. ISBN 1-876346-50-7 2004 ICMP.

<http://www.phys.unsw.edu.au/~jw/reprints/SchWolTarICMPC8.pdf>

Silva, E. L. & Menezes, E. M. "Metodologia da Pesquisa e Elaboração de Dissertação". 3a edição revisada e atualizada”. Universidade Federal de Santa Catarina. Programa de Pós-Graduação em Engenharia de Produção. Laboratório de Ensino a Distância. Florianópolis. 2001.

Torrence, C. & Compo, G. P. "A Practical Guide to nWavelet Analysis". Program in Atmospheric and Oceanic Sciences, University of Colorado, Boulder, Colorado. 1998. <http://www.ma.utexas.edu/users/davis/reu/ch1/signals/torrence.pdf>

Traube, C. "Instrumental and vocal timbre perception". May 24, 2006 - Musicology Department - University of Graz Psychology of Music Performance Seminar. <http://www-gewi.uni-graz.at/staff/parncutt/guests/2006/traube/

Slides_CTraube_timbre.pdf>

Tafner, M. A. Reconhecimento de palavras isoladas usando redes neurais artificiais. Dissertação de mestrado. Programa de Pós-Graduação em Engenharia da Produção. Universidade Federal de Santa Catarina. Florianópolis, 1996.

Widrow, B. and Hoff, M. E. 1988. “Adaptive switching circuits”. In Neurocomputing: Foundations of Research, J. A. Anderson and E. Rosenfeld, Eds. MIT Press, Cambridge, MA, 123-134.

Weisstein, E. W. "Apodization Function." From MathWorld--A Wolfram Web Resource. 2006a. <http://mathworld.wolfram.com/ApodizationFunction.html>. Acessado em 13 jul. 2006.

Weisstein, E. W. "Gibbs Phenomenon." From MathWorld--A Wolfram Web Resource. 2006b. <http://mathworld.wolfram.com/GibbsPhenomenon.html>. Acessado em 13 jul. 2006.

Zanchettin, C. & Ludermir, T. B. "Sistemas Neurais Híbridos para Reconhecimento de padrões em Narizes Artificiais". XXV Congresso da Sociedade Brasileira da Computação. UNISINOS - São Leopoldo/RS. jul. 2005.

Outras referências (sem autor):

Wikipédia contributors. “Rede Neural”. Wikipédia, The Free Encyclopedia, 2006. Disponível em: http://pt.wikipedia.org/wiki/Redes_neurais. Acesso em 8 jul. 2006.

Wikipedia contributors. “Harmonic Series”, Wikipedia, The Free Encyclopedia, Jul. 2005, <http://en.wikipedia.org/wiki/Harmonic_series_%28music%29> Acesso em 8 jul. 2006. Wikipedia contributors. “Fundamental Frequency”, Wikipedia, The Free Encyclopedia, Jul.

2005, <http://en.wikipedia.org/wiki/Fundamental_frequency> Acesso em 8 jul. 2006. Wikipedia contributors. “Continuous Fourier transform”, Wikipedia, The Free

Encyclopedia, Jul. 2005, <http://en.wikipedia.org/wiki/Continuous_Fourier_transform> Acesso em 8 jul. 2006.

Wikipedia contributors. “Fourier series”, Wikipedia, The Free Encyclopedia, Jul. 2005, <http://en.wikipedia.org/wiki/Fourier_series> Acesso em 8 jul. 2006.

Wikipedia contributors. “Discrete wavelet transform”, Wikipedia, The Free Encyclopedia, Jul. 2005, <http://en.wikipedia.org/wiki/Discrete_wavelet_transform> Acesso em 8 jul. 2006.

Wikipedia contributors. “Fast wavelet transform”, Wikipedia, The Free Encyclopedia, Jul. 2005, <http://en.wikipedia.org/wiki/Fast_wavelet_transform> Acesso em 8 jul. 2006. Wikipedia contributors. “Daubechies wavelet”, Wikipedia, The Free Encyclopedia, Jul. 2005,

<http://en.wikipedia.org/wiki/Daubechies_wavelet> Acesso em 8 jul. 2006. Wikipedia contributors. “Derivative”, Wikipedia, The Free Encyclopedia, Jul. 2005, <

http://en.wikipedia.org/wiki/Derivative> Acesso em 8 jul. 2006.

Wikipedia contributors. “Chain rule”, Wikipedia, The Free Encyclopedia, Jul. 2005, <http://en.wikipedia.org/wiki/Chain_rule> Acesso em 8 jul. 2006.

APÊNDICE A – Código fonte da rede neural usada nos experimentos

RedeNeural.java

Created with JBuilder package neural;

import java.io.*;

import java.text.*;

import java.util.*;

import DSP.*;

public class RedeNeural{

String[] palavras = {"seis","sete","oito","nove","zero","rosa", "laranja","preto","marrom","roxo","amarelo", "verde","azul","branco","vermelho","um","dois", "tres","quatro","cinco"};

int numEpochs = 500; int numInputs = 30; int numOutputs = 20; int numPatterns = 720;

private boolean softmax=true; double LR = 0.25;

double Error; int patNum;

double errThisPat[] = new double[numOutputs]; public double outPred[] = new double[numOutputs];

public double[][] trainInputs = new double[numPatterns][numInputs]; public double[][] trainOutput = new double[numPatterns][numOutputs]; public double[][] weights = new double[numInputs+1][numOutputs]; //+1 bias

Extrator extrator = new ExtratorWavelet(); public RedeNeural() {

PrintStream treinamento = null; try {

treinamento = new PrintStream(new FileOutputStream("treinamento.txt")); }

catch (FileNotFoundException ex) { }

initWeights(); initData();

Random random = new Random();

for(int j = 0;j <= numEpochs;j++){ for(int i = 0;i<numPatterns;i++){

patNum = random.nextInt(numPatterns); calcNet();

System.out.println("epoch = " + j + " Error = " + Error); treinamento.println(Error);

}

displayResults(); }

public String Predict(double[] Input){

trainInputs[0] = extrator.PowerSpectrum3(Input); for (int j=0; j<numInputs; j++){

if (trainInputs[0][j] != 0)

trainInputs[0][j] = (trainInputs[0][j] - extrator.min) / (extrator.max - extrator.min);

}

patNum = 0; calcNet();

for (int i =0; i<20; i++)

System.out.println(outPred[i]); return palavras[toint(outPred)]; }

public void Softmax() { //MLogistic activation

double SumExp = 0;

for(int k = 0;k<numOutputs;k++){

SumExp = SumExp + Math.exp(outPred[k]); }

for(int k = 0;k<numOutputs;k++){

outPred[k] = Math.exp(outPred[k])/SumExp;

errThisPat[k] = trainOutput[patNum][k] - outPred[k]; }

}

public void calcNet() {

for(int k = 0;k<numOutputs;k++){ outPred[k] = 0.0;

for(int j = 0;j<numInputs;j++){

outPred[k] = outPred[k] + (trainInputs[patNum][j] * weights[j][k]); }

outPred[k] = outPred[k] + weights[numInputs][k]; //bias

errThisPat[k] = trainOutput[patNum][k] - outPred[k]; }

if (softmax) Softmax(); }

public void WeightChanges(){

for(int k = 0;k<numOutputs;k++){

for (int j = 0; j < numInputs; j++){

double delta = LR * errThisPat[k] * trainInputs[patNum][j]; weights[j][k] = weights[j][k] + delta;

}

weights[numInputs][k] = weights[numInputs][k] + (LR * errThisPat[k]); //bias

} }

public void initWeights(){

Random random = new Random(); for(int j = 0;j<numOutputs;j++){

} }

public void initData(){

DecimalFormat format = new DecimalFormat(); format.setMinimumIntegerDigits(2);

format.setMaximumFractionDigits(0);

for (int i=0; i<60; i++){ //10 palavras, 6 repetições, 6 sessões

int j = i / 6;

double out[] = new double[numOutputs]; out[j]=1;

String num = format.format(i+1);

trainInputs[i] = extrator.Extrair("waves1/c("+num+").wav"); trainOutput[i] = out; //pattern 0 ao 59

trainInputs[i+360] = extrator.Extrair("waves2/c("+num+").wav"); trainOutput[i+360] = out;

trainInputs[i+120] = extrator.Extrair("waves3/c("+num+").wav"); trainOutput[i+120] = out;

trainInputs[i+180] = extrator.Extrair("waves4/c("+num+").wav"); trainOutput[i+180] = out;

trainInputs[i+240] = extrator.Extrair("waves5/c("+num+").wav"); trainOutput[i+240] = out;

trainInputs[i+300] = extrator.Extrair("waves6/c("+num+").wav"); trainOutput[i+300] = out;

}

for (int i=0; i<60; i++){ //+10 palavras, 6 repetições, 6 sessões

int j = i / 6;

double out[] = new double[numOutputs]; out[j+10]=1;

String num = format.format(i+1);

trainInputs[i+60] = extrator.Extrair("waves7/c("+num+").wav"); trainOutput[i+60] = out; //pattern 60 ao 119

trainInputs[i+60+360] = extrator.Extrair("waves8/c("+num+").wav"); trainOutput[i+60+360] = out;

trainInputs[i+120+360] = extrator.Extrair("waves9/c("+num+").wav"); trainOutput[i+120+360] = out;

trainInputs[i+180+360] = extrator.Extrair("waves10/c("+num+").wav"); trainOutput[i+180+360] = out;

trainInputs[i+240+360] = extrator.Extrair("waves11/c("+num+").wav"); trainOutput[i+240+360] = out;

trainInputs[i+300+360] = extrator.Extrair("waves12/c("+num+").wav"); trainOutput[i+300+360] = out;

}

PrintStream padroes = null; try {

padroes = new PrintStream(new FileOutputStream("padroes.txt")); }

catch (FileNotFoundException ex) { }

padroes.print("Palavra");

padroes.println();

for (int i=0; i<numPatterns; i++){

padroes.print(palavras[toint(trainOutput[i])]); for (int j=0; j<numInputs; j++){

if (trainInputs[i][j] != 0)

trainInputs[i][j] = (trainInputs[i][j] - extrator.min) / (extrator.max - extrator.min); padroes.print("\t");

padroes.print(trainInputs[i][j]); }

padroes.println(); }

System.out.print("maximo = "+extrator.max); System.out.print("minimo = "+extrator.min); numPatterns = 120;

}

public void displayResults(){

PrintStream acertos = null, err = null; try {

acertos = new PrintStream(new FileOutputStream("acertos.txt")); err = new PrintStream(new FileOutputStream("err.txt"));

}

catch (FileNotFoundException ex) { }

numPatterns = 720;

int acertostst = 0, acertostrn = 0; for(int i = 0; i<numPatterns; i++){ patNum = i;

calcNet();

int actual = toint(trainOutput[patNum]); int model = toint(outPred);

double value = outPred[actual];

double sumerr = sum(outPred) - outPred[model]; if (i < 120){ //conj. trein. if (actual == model) { acertostrn++; } else { }

}else{ //conj. teste

if (actual == model){ acertostst++; acertos.println(value); } else{ err.println(value); } } /* System.out.println("pat = " + (patNum+1) + " actual = " + palavras[actual] + " neural model = " + palavras[model]

+ " >>value "+ value+ " **sumerr "+ sumerr);*/

}

System.out.println("ACERTOS NO TESTE = "+ acertostst);

System.out.println("ACERTOS NO TREINAMENTO = "+ acertostrn); }

Error = 0.0; double E = 0.0;

for(int i = 0;i<numPatterns;i++){ patNum = i;

calcNet();

double Ep = 0.0;

for (int k = 0; k < numOutputs; k++){

Ep = Ep + (errThisPat[k]*errThisPat[k]/(2*numOutputs)); }

Error = Error + Ep/(numPatterns); }

Error = Math.sqrt(Error); }

public int toint(double[] d){

double great = Integer.MIN_VALUE; int index = -1;

for (int i = 0; i<d.length; i++){ if (d[i] == 1) return i; if (d[i] > great) { great = d[i]; index = i; } } return index; }

public double sum(double[] d){ double s = 0;

for (int i = 0; i<d.length; i++) s = s+Math.sqrt(d[i]*d[i]); return s;

} }

RedeNeural.java

APÊNDICE B – Algoritmos de extração usando STFT

Extrator.java

Created with JBuilder package DSP;

import java.io.*;

import java.io.IOException;

import javax.sound.sampled.*;

import javax.sound.sampled.AudioInputStream;

public class Extrator { public double[] data;

static int txamostra = 8000;

static int framelength = 512; //divisível por 2

//framelength*frames > length

static int length = 8192; //numero de amostras lidas

static int frames = 2*length/framelength;//50% de sobreposição

static int nsb = 5; //número de subbandas analisadas

double[] mags;

double[] centroides;

double[] janela = new double[framelength]; public double max=Double.NEGATIVE_INFINITY, min=Double.POSITIVE_INFINITY; public Extrator(){

double x = -1;

for (int i=0; i<framelength; i++){ //Gaussian

//janela[i] = Math.exp(-0.5*(Math.pow(2.5*x,2)));

//Hann

janela[i] = (0.5*(1+Math.cos(Math.PI*(x)))); //Blackmann //janela[i] = (0.42 -0.5*Math.cos(2*Math.PI*((1+x)/2)) // +0.08*Math.cos(4*Math.PI*((1+x)/2))); x = x + 2.0/framelength; } }

public double[] Extrair(String nomearquivo) { data = this.readwave(nomearquivo);

return PowerSpectrum2(data); }

public double[] Centroides(double[] data){ mags = new double[(framelength/2)*frames]; centroides = new double[frames];

double[] frame = new double[framelength]; int p = 0, numframe = 0;

double[] magnitude = new double[framelength]; double[] real = new double[framelength]; double[] imag = new double[framelength]; double[] angle = new double[framelength];

ForwardRealToComplexFFT01.transform(frame,real,imag,angle,magnitude); double pfreq = txamostra/framelength;

double num = 0, den = 0;

for(int i = 0; i < framelength/2; i++){ //abaixo da freq/2

magnitude[i] = log10(1+magnitude[i]);

num = num + i * pfreq * magnitude[i]; //Frequencia * Intensidade

den = den + magnitude[i]; }

centroides[numframe] = (num/den);

if (centroides[numframe]>max) max = centroides[numframe]; if (centroides[numframe]<min) min = centroides[numframe];

System.arraycopy(magnitude,0,mags,(framelength/2)*numframe,framelength/2); numframe++;

p = p + length/frames; }

return centroides; }

public double[] PowerSpectrum(double[] data){ Centroides(data);

return mags; }

public double[] PowerSpectrum2(double[] data){ mags = new double[nsb*frames];

double[] frame = new double[framelength]; int p = 0, numframe = 0;

while (p+framelength <= length) { for (int i=0; i<framelength; i++)

frame[i] = data[p+i]*janela[i]; //Janelamento

double[] magnitude = new double[framelength]; double[] real = new double[framelength]; double[] imag = new double[framelength]; double[] angle = new double[framelength];

ForwardRealToComplexFFT01.transform(frame,real,imag,angle,magnitude); int pf = framelength/(int)Math.pow(2,nsb),

numband = 1;

for (int i=0; i<pf; i++)//numband = 0

mags[numframe*nsb] = mags[numframe*nsb]+magnitude[i]; mags[numframe*nsb] = log10(1+mags[numframe*nsb]); while (pf < framelength/2) {

for(int i=pf; i<(pf*2); i++)

mags[numband+numframe*nsb] = mags[numband+numframe*nsb] + magnitude[i]*magnitude[i];

mags[numband+numframe*nsb] = log10(1+mags[numband+numframe*nsb]); numband++;

pf = pf*2; }

numframe++;

p = p + length/frames; }

return mags; }

public double[] readwave(String filename){

byte[] audioBytes = null; try {

AudioInputStream audioInputStream =

AudioSystem.getAudioInputStream(new File(filename)); audioInputStream = AudioSystem.

getAudioInputStream(getAudioFormat(), audioInputStream); if (audioInputStream.getFormat().getSampleSizeInBits() != 8)

throw new RuntimeException("File format not supported: " + filename); int nlengthInFrames = (int) audioInputStream.getFrameLength();

audioBytes = new byte[nlengthInFrames]; audioInputStream.read(audioBytes); }

catch (Exception ex) { ex.printStackTrace(); }

int start, end;

for (start = 0; start < audioBytes.length; start++) if(audioBytes[start] > 128*0.1) break;

//detecta primeiro pico (vogal)

start = start - txamostra/10;

//recua 100ms (incluir eventual consoante)

end = start + length;

double[] data = new double[length]; for (int i=0; i+start < end; i++) data[i]=audioBytes[i+start]; return data;

}

private AudioFormat getAudioFormat(){ float sampleRate = 8000.0F; //8000,11025,16000,22050,44100 int sampleSizeInBits = 8; //8,16 int channels = 1; //1,2

boolean signed = true;

//true,false

boolean bigEndian = false;

//true,false

return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian); }//end getAudioFormat

}

public double[] PowerSpectrum3(double[] data){ return null;

} }

Extrator.java

APÊNDICE C – Algoritmos de extração usando DWT

ExtratorWavelet.java

Created with JBuilder package DSP;

import java.io.*;

public class ExtratorWavelet extends Extrator { public ExtratorWavelet() {

}

public double[] PowerSpectrum(double[] data){ int ncoeficientes=8192;

mags = new double[13]; Daub daub = new Daub(); daub.daubTrans(data);

int p = 1, numband = 0; while (p < ncoeficientes) { for(int i=p; i<(p*2); i++){

mags[numband] = mags[numband] + data[i]*data[i]; }

mags[numband] = log10(1+mags[numband]); numband++;

p = p*2; }

for (int i=0; i<13; i++){

if (mags[i]>max) max = mags[i]; if (mags[i]<min) min = mags[i]; }

return mags; }

public double[] PowerSpectrum2(double[] data){ Daub daub = new Daub();

daub.daubTrans(data); int ncoeficientes=8192,

blperband = 8, //qtos frames

numband = 9, //primeira subbanda considerada

p = (int)Math.pow(2,numband), inicio=blperband*numband;

mags = new double[(13*blperband)-inicio]; while (p < ncoeficientes) {

int tmbl = p / blperband;

int offset = numband*blperband -inicio; for(int i=p; i<(p*2); i++){

int p2 = i/tmbl - blperband;

mags[offset+p2] = mags[offset+p2] + data[i]*data[i]; }

numband++; p = p*2; }

}

int index = 0;

double[] mags2 = new double[(13*blperband)-inicio]; //reordenar

for (int bl=0; bl<blperband; bl++){

for (int ba=0; ba<mags.length/blperband; ba++){ mags2[index] = mags[(ba*blperband)+bl]; index++; } } return mags; }

public double[] PowerSpectrum3(double[] data){ mags = new double[64+32+16+8];

Daub daub = new Daub(); daub.daubTrans(data); int ncoeficientes=8192, tmbl = 64, p = 512, p1 = 0; while ( p < ncoeficientes) { int blperband = p/tmbl; for(int i=p; i<(p*2); i++){ int p2 = i/tmbl - blperband;

mags[p1+p2] = mags[p1+p2] + data[i]*data[i]; }

p = p*2;

p1 = p1 + blperband; }

for (int i=0; i<mags.length; i++){ mags[i] = log10(1+mags[i]); if (mags[i]>max) max = mags[i]; if (mags[i]<min) min = mags[i]; }

return mags; }

public double[] Extrair(String nomearquivo) {

return PowerSpectrum3(this.readwave(nomearquivo)); }

}

ExtratorWavelet.java

ANEXO A – Código fonte da FFT

ForwardRealToComplexFFT01.java

Created with JBuilder package DSP;

/*File ForwardRealToComplexFFT01.java Copyright 2004, R.G.Baldwin

Rev 5/14/04 */

public class ForwardRealToComplexFFT01{ public static void transform(

double[] data, double[] realOut, double[] imagOut, double[] angleOut, double[] magnitude){ double pi = Math.PI;//for convenience

int dataLen = data.length;

//The complexToComplex FFT method does an

// in-place transform causing the output

// complex data to be stored in the arrays

// containing the input complex data.

// Therefore, it is necessary to copy the

// input data to this method into the real

// part of the complex data passed to the

// complexToComplex method.

System.arraycopy(data,0,realOut,0,dataLen);

//Perform the spectral analysis. The results

// are stored in realOut and imagOut. The +1

// causes it to be a forward transform. A -1

// would cause it to be an inverse transform.

complexToComplex(1,dataLen,realOut,imagOut);

//Compute the magnitude and the phase angle

// in degrees.

for(int cnt = 0;cnt < dataLen;cnt++){ magnitude[cnt] = (Math.sqrt(realOut[cnt]*realOut[cnt] + imagOut[cnt]*imagOut[cnt]))/(dataLen); if(imagOut[cnt] == 0.0 && realOut[cnt] == 0.0){ angleOut[cnt] = 0.0; }//end if else{ angleOut[cnt] = Math.atan( imagOut[cnt]/realOut[cnt])*180.0/pi; }//end else if(realOut[cnt] < 0.0 && imagOut[cnt] == 0.0){ angleOut[cnt] = 180.0; }else if(realOut[cnt] < 0.0 && imagOut[cnt] == -0.0){ angleOut[cnt] = -180.0; }else if(realOut[cnt] < 0.0 && imagOut[cnt] > 0.0){

angleOut[cnt] += -180.0; }//end else

}//end for loop

}//end transform method

//---//

//This method computes a complex-to-complex

// FFT. The value of sign must be 1 for a

// forward FFT.

public static void complexToComplex( int sign, int len,

double real[], double imag[]){ double scale = 1.0;

//Reorder the input data into reverse binary

// order.

int i,j;

for (i=j=0; i < len; ++i) { if (j>=i) {

double tempr = real[j]*scale; double tempi = imag[j]*scale; real[j] = real[i]*scale; imag[j] = imag[i]*scale; real[i] = tempr; imag[i] = tempi; }//end if int m = len/2; while (m>=1 && j>=m) { j -= m; m /= 2;

}//end while loop

j += m; }//end for loop

//Input data has been reordered.

int stage = 0;

int maxSpectraForStage,stepSize;

//Loop once for each stage in the spectral

// recombination process. for(maxSpectraForStage = 1, stepSize = 2*maxSpectraForStage; maxSpectraForStage < len; maxSpectraForStage = stepSize, stepSize = 2*maxSpectraForStage){ double deltaAngle = sign*Math.PI/maxSpectraForStage; //Loop once for each individual spectra

for (int spectraCnt = 0;

spectraCnt < maxSpectraForStage; ++spectraCnt){

double angle = spectraCnt*deltaAngle; double realCorrection = Math.cos(angle); double imagCorrection = Math.sin(angle); int right = 0;

for (int left = spectraCnt;

left < len;left += stepSize){ right = left + maxSpectraForStage; double tempReal =

realCorrection*imag[right] + imagCorrection*real[right]; real[right] = real[left]-tempReal; imag[right] = imag[left]-tempImag; real[left] += tempReal; imag[left] += tempImag; }//end for loop

}//end for loop for individual spectra

maxSpectraForStage = stepSize; }//end for loop for stages

}//end complexToComplex method

}//end class ForwardRealToComplexFFT01

ForwardRealToComplexFFT01.java

ANEXO B – Código fonte da transformada wavelet Daubechies 4

Daub.java

Created with JBuilder package DSP;

/*

http://www.bearcave.com/software/java/wavelets/daubechies.html Ian Kaplan, July 2001

Revised: November 2001 */

import java.lang.Math.*;

class Daub {

protected final double sqrt_3 = Math.sqrt( 3 ); protected final double denom = 4 * Math.sqrt( 2 ); //

// forward transform scaling (smoothing) coefficients

//

protected final double h0 = (1 + sqrt_3)/denom; protected final double h1 = (3 + sqrt_3)/denom; protected final double h2 = (3 - sqrt_3)/denom; protected final double h3 = (1 - sqrt_3)/denom; //

// forward transform wavelet coefficients

//

protected final double g0 = h3; protected final double g1 = -h2; protected final double g2 = h1; protected final double g3 = -h0; //

// Inverse transform coefficients for smoothed values

//

protected final double Ih0 = h2; protected final double Ih1 = g2; // h1

protected final double Ih2 = h0; protected final double Ih3 = g0; // h3

//

// Inverse transform for wavelet values

//

protected final double Ig0 = h3;

protected final double Ig1 = g3; // -h0

protected final double Ig2 = h1;

protected final double Ig3 = g1; // -h2

/**

Forward wavelet transform.

Note that at the end of the computation the calculation wraps around to the beginning of the signal.

*/

protected void transform( double a[], int n ) {

if (n >= 4) { int i, j;

int half = n >> 1;

tmp[i+half] = a[j]*g0 + a[j+1]*g1 + a[j+2]*g2 + a[j+3]*g3; i++;

}

tmp[i] = a[n-2]*h0 + a[n-1]*h1 + a[0]*h2 + a[1]*h3; tmp[i+half] = a[n-2]*g0 + a[n-1]*g1 + a[0]*g2 + a[1]*g3; for (i = 0; i < n; i++) {

a[i] = tmp[i]; }

}

} // transform

protected void invTransform( double a[], int n ) {

if (n >= 4) {

int i, j;

int half = n >> 1;

int halfPls1 = half + 1;

double tmp[] = new double[n];

// last smooth val last coef. first smooth first coef

tmp[0] = a[half-1]*Ih0 + a[n-1]*Ih1 + a[0]*Ih2 + a[half]*Ih3; tmp[1] = a[half-1]*Ig0 + a[n-1]*Ig1 + a[0]*Ig2 + a[half]*Ig3; j = 2;

for (i = 0; i < half-1; i++) {

// smooth val coef. val smooth val coef. val

Documentos relacionados