Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the frequency of an audio file in every 1/4 seconds in android

I have a sound file (.3gp) and its about ~1 min. I would like to get the frequency of this sound file in every 1/4 seconds. My idea is to receive samples in every 1/4 seconds from the audio file and using FFT I might get the frequency values. Is there any way to do this?

Actually I would split the sound file into 1/4sec samples sound files (alwyas overwriting the preveious one), then using FFT algorithm and detect the frequency where the magintude is the bigggest. But there might be easier solutions however I dont have a clue how to do this either.

***UPDATE 2 - new code

I use this code so far:

public class RecordAudio extends AsyncTask<Void, double[], Void> {

    @Override
    protected Void doInBackground(Void... arg0) {

        try {
             int bufferSize = AudioRecord.getMinBufferSize(frequency,
             AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);


            //int bufferSize = AudioRecord.getMinBufferSize(frequency, 
                  //  channelConfiguration, audioEncoding); 

            AudioRecord audioRecord = new AudioRecord( 
                    MediaRecorder.AudioSource.MIC, frequency, 
                    channelConfiguration, audioEncoding, bufferSize); 

            short[] buffer = new short[blockSize];
            //double[] toTransform = new double[blockSize];


            audioRecord.startRecording();


            // started = true; hopes this should true before calling
            // following while loop

            while (started) {
               sampling++;

               double[] re = new double[blockSize];
               double[] im = new double[blockSize];

               double[] newArray = new double[blockSize*2];
               double[] magns = new double[blockSize];

               double MaxMagn=0;
               double pitch = 0;

               int bufferReadResult = audioRecord.read(buffer, 0,
                        blockSize);


               for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                   re[i] = (double) buffer[i] / 32768.0; // signed   16bit
                   im[i] = 0;
               }    

               newArray = FFTbase.fft(re, im,true);

               for (int i = 0; i < newArray.length; i+=2) {

                   re[i/2]=newArray[i];
                   im[i/2]=newArray[i+1];
                   magns[i/2] = Math.sqrt(re[i/2]*re[i/2]+im[i/2]*im[i/2]);
               }

              // I only need the first half      

              for (int i = 0; i < (magns.length)/2; i++) {
                   if (magns[i]>MaxMagn)
                   {
                       MaxMagn = magns[i];
                       pitch=i;
                   }
               }                                           
                 if (sampling > 50) {
                   Log.i("pitch and magnitude", "" + MaxMagn + "   " + pitch*15.625f);
                   sampling=0;
                   MaxMagn=0;pitch=0;
                   }                   


            }

            audioRecord.stop();

        } catch (Throwable t) {
            t.printStackTrace();
            Log.e("AudioRecord", "Recording Failed");
        }
        return null;
    }

I use this: http://www.wikijava.org/wiki/The_Fast_Fourier_Transform_in_Java_%28part_1%29

Guitar strings seem correct, but my own sound is not good because of this:

enter image description here

The magnitude of the two peaks change most of the time and I always find the biggest to get the fundamental frequency.

like image 803
Jani Bela Avatar asked Aug 07 '12 11:08

Jani Bela


People also ask

How do you find the frequency of an audio file?

If you need to determine the bitrate or frequency of an audio file, such as an MP3, or the audio in a movie file, such as an MPEG or MP4, you can do so on Windows using a free program called Pazera Free Audio Extractor. This program includes the powerful FFMPEG library with an easy-to-use and quick interface.

What is the frequency of an audio recording?

The generally established audio frequency range is 20 Hz to 20,000 Hz, though most people can hear less than this entire range, and as they get older, the range tends to contract on both ends. The relationship between music and audio frequency is that each time you move up an octave, you double the frequency.


2 Answers

Pitch tracking with the FFT is asked so often on Stack Overflow I wrote a blog entry with sample code. The code is in C, but with the explanation and links you should be able to do what you want.

As to dividing it up into 1/4 second increments, you could simply take FFTs of 1/4 second segments as you suggested, instead of the default (which I think is about 1 second). If this doesn't give you the frequency resolution you want, you may have to use a different pitch recognition method. Another thing you could do is use overlapping segments that are longer than 1/4 second, but start at intervals that are 1/4 second apart. This method is alluded to the blog entry, but it may not meet your design spec.

like image 113
Bjorn Roche Avatar answered Nov 09 '22 09:11

Bjorn Roche


Try AsyncTask:

class GetFrequency extends AsyncTask<String, Void, Void> {
   public Void doInBackground(String... params) {
          while (true) {

             // Apply Logic Here

           try {
                Thread.sleep(250);
               } catch (Exception ie) {
                  // TODO Auto-generated catch block
                e.printStackTrace();
               }
       }
   }  
}

Call this in your MainActivity by,

frequencyButtonListener.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

        new GetFrequency.execute(params);

        }
    });
like image 1
Name is Nilay Avatar answered Nov 09 '22 07:11

Name is Nilay