viv
viv

Reputation: 6177

Extracting frequency from wav file

I am trying to extract frequency from a wav file, but looks like something is going wrong.

First of all I am extracting bytes from files, then applying FFT on it and at last finding the magnitude.

Seems like I am doing something wrong as the output is not close to real value. Below is the code.

try{

        File log = new File("files/log.txt");
        if(!log.exists()) log.createNewFile();
        PrintStream ps = new PrintStream(log);

        File f  = new File("files/5000.wav");                       
        FileInputStream fis = new FileInputStream(f);   
        int length = (int)f.length();
        length = (int)nearestPow2(length);
        double[] ibr = new double[length]; //== real
        double[] ibi = new double[length]; //== imaginary
        int i = 0;
        int l=0;
        //fis.skip(44);
        byte[] b = new byte[1024];
        while((l=fis.read(b))!=-1){
            try{

                for(int j=0; j<1024; j++){
                    ibr[i] = b[j];
                    ibi[i] = 0;
                    i++;
                }
            }catch(Exception e){}
        }

        double[] ftb = FFTBase.fft(ibr, ibi, true);
        double[] mag = new double[ftb.length/2];
        double mxMag = 0;
        long avgMg = 0;
        int reqIndex = 512; //== no need to go till end
        for(i=1;i<ibi.length; i++){
            ibr[i] = ftb[i*2];
            ibi[i] = ftb[i*2+1];
            mag[i] = Math.sqrt(ibr[i]*ibr[i]+ibi[i]*ibi[i]);
            avgMg += mag[i];
            if(mag[i]>mxMag) mxMag = mag[i];
            ps.println(mag[i]);
        }
        avgMg = avgMg/ibi.length;
        ps.println("MAx===="+mxMag);
        ps.println("Average===="+avgMg);

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

When I run this code for a 5KHZ file , these are the values I am getting. https://pastebin.com/R3V0QU4G

This is not the complete output, but its somewhat similar.

Thanks

Upvotes: 1

Views: 1112

Answers (1)

treeno
treeno

Reputation: 2600

Extracting a frequency, or a "pitch" is unfortunatly hardly possible by only doing a fft and searching for the "loudest" frequency or something like that. At least if you are trying to extract it from a musical signal.

Also there are different kinds of tones. A large portion of musical instruments (i.e. a guitar or our voice) create harmonic sounds which consists of several frequencies which follow a certain pattern.

But there are also tones that have only one Peak / frequency (i.e. whistleing)

Additionally you usually have to deal with noise in the signal that is not tonal at all. This could be a background noise, or this could be produced by the instrument itself. Guitars for instance have a very large noise-portion while the attack-phase.

You can use different approaches, meaning different algorthims to find the pitch of these signals, depending of its type.

If we stay in the frequency domain (fft) and assuming we want to analyze a harmonic sound there is for example the two way mismatch algorithm that uses a statistical patternmatching to find harmonics and to guess the fundamental frequency, which is the frequency that is perceived as the tone by our ears.

An example-implementation can be found here: https://github.com/ausmauricio/audio_dsp This repo is part of a complete course on audio signal processing at coursera, maybe this is helpful.

Upvotes: 1

Related Questions