Dúvida em Implementação de FFT

0 respostas
lordtiago

Bom dia Galera, estava tentando implementar um software de detecção de frequência, e estou usando de base essa referência:

http://ww2.ce.pdn.ac.lk/users/roshanr/research/papers/herath07implementation.pdf

Eu vi o algoritmo para calculo de FFT usado por ele:

Main:
        While there is data in data chunk
                 Call Subroutine1 with 256 samples
        End while
     For (i = 0 to 256)
           FindMax (|totalCos[i] + totalSin[i]|)
           location = i
      End
   Frequency = SampleRate * location / (2*255)
End Main

Subroutine1: Input data[]
       For (i=0 to 256)
               For (j=0 to 256)
                      X = (-2 * π * i * j ) / 256
                      cosPart [i] = cosPart [i] + data [j] * Cos (X)
                       sinPart [i] = sinPart [i] + data [j] * Sin (X)
                End For
              totalCos [i] = totalCos [i] + cosPart [i]
              totalSin [i] = totalSin [i] + sinPart [i]
        End For
End Subroutine1

Com base neste algoritmo desenvolvi uma classe:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package conversor;

/**
 *
 * @author tiagor
 */
public class FFT {
    private int interval=0;
    private double[]totalCos;
    private double[]totalSin;
    private double[]soma;


    public double getFrequencia(byte[]data, int sampleRate, int bitsPerSample){
        totalCos = new double[bitsPerSample];
        totalSin = new double[bitsPerSample];
        soma     = new double[bitsPerSample];


        byte[] temp = new byte[bitsPerSample];
        double sMajor = 0;
        interval = bitsPerSample;

        while(interval<data.length){
            int h=0;
            for(int g=(interval-bitsPerSample);g<data.length;g++){                
                if(g<interval){
                temp[h]=data[g];
                System.out.println(g+"Inicia de novo: "+temp[h]+" "+h);
                h = h+1;
                }
            }
            fft(bitsPerSample, temp);
            interval +=bitsPerSample;
        }

        sMajor = findMax(soma);

        return (sampleRate*sMajor/(2*bitsPerSample));
    }

    private void fft(int bitsPerSample, byte[]temp){
        double[] cosPart = new double[bitsPerSample];
        double[] sinPart = new double[bitsPerSample];
        
        for(int i=0;i<bitsPerSample;i++){
            for(int j=0;j<bitsPerSample;j++){
                double X = ((-2 * Math.PI * i * j) / bitsPerSample);
                cosPart[i] += temp[j]* Math.cos(X);                
                sinPart[i] += temp[j]* Math.sin(X);                
            }
            /*if(i==0){
                totalCos[i] = cosPart[i];
                totalSin[i] = sinPart[i];
            }else{
                totalCos[i] = totalCos[i-1] + cosPart[i];
            totalSin[i] = totalSin[i-1] + sinPart[i];
            }*/
            totalCos[i] += cosPart[i];
            totalSin[i] += sinPart[i];
            
            soma[i]      = totalCos[i] + totalSin[i];
        }
    }

    private double findMax(double[]soma){
        double major=0;
        for(int i=0;i<soma.length;i++){
            if(soma[i]>major){
                major = soma[i];
                //major = i;
            }
        }
        return major;
    }

}

Porém estou com uma dificuldade. Ao mandar um som de exemplo, o valor me sai um tanto quanto alto:

os parâmetros do audio são esses: Channels: 1 SampleRate: 11025 ByteRate: 11025 BlockAlign: 1 BitsPerSample: 8 DataSize: 5071
e a frequencia retornada é esta: 1668165.[telefone removido]

Gostaria de ver com alguém que entende melhor de matemática, ou já lidou com implementações deste tipo, o ponto que estou errando, para eu melhor implementar meu código.

Desde já, valeu!!!

Criado 15 de setembro de 2011
Respostas 0
Participantes 1