1

I've trying to calculate peak frequency from android mic buffer as per this How to get frequency from fft result? . Unfortunatly i'm getting wrong values. Even i played a tone in 18Khz,but i'm not getting correct peak frequency. This is my code,

int sampleRate=44100,bufferSize=4096;
AudioRecord audioRec=new AudioRecord(AudioSource.MIC,sampleRate,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,bufferSize);
audioRec.startRecording();
audioRec.read(bufferByte, 0,bufferSize);
for(int i=0;i<bufferByte.length;i++){
    bufferDouble2[i]=(double)bufferByte[i];
}

//here window techniq is appliying

for(int i=0;i<bufferSize-1;i++){
    bufferDouble[2*i]=bufferDouble2[i];    
    bufferDouble[2*i+1] = 0.0;}
DoubleFFT_1D fft = new DoubleFFT_1D(bufferSize); //instance of DoubleFFT_1D class
fft.realForwardFull(bufferDouble);  //this is where it falls

//here calculating magnitude

for (int i = 0; i < (bufferSize/2)-1; i++) {
       double real= bufferDouble[2*i];
       double imag=bufferDouble[2*i+1];
       mag[i] =Math.sqrt((real*real)+(imag*imag));
    }

//calculating maximum frequency

 double max_mag =0.0;
 int max_index = -1;
 for(int j=0;j<(bufferSize/2)-1;j++){
if(mag[j]>max_mag){
    max_mag = mag[j];
    max_index = j;
   }
 }
  final int peak=max_index * sampleRate/bufferSize;
  Log.v(TAG2, "Peak Frequency = " +max_index * sampleRate/bufferSize);

This is the output while listining 18Khz sound in phone

Output while playing 18Khz sound

Help me and please don't give theoretical answers. Thank you

Community
  • 1
  • 1
Pandian
  • 474
  • 1
  • 4
  • 14
  • Check again the documentation for the format of the inputs. You are preparing your data for a run of ComplexForward, but call RealForward. You should be able to pass BufferDouble2 directly to RealForward. – Lutz Lehmann Feb 20 '14 at 15:20
  • @LutzL So you'r saying that, i've to use ComplexForward instead of RealForward,right...? – Pandian Feb 21 '14 at 04:20
  • 1
    @LutzL can you please suggest where should i use window function.i've code for hanning window function. 'case HANNING: // Hanning window r = pi / (m + 1); for (int n = -m; n < m; n++) w[m + n] = 0.5f + 0.5f * Math.cos(n * r); break;' I've no idea what it is, please refer this [link](https://code.google.com/p/musicg/source/browse/src/com/musicg/dsp/WindowFunction.java) Thank you – Pandian Feb 21 '14 at 04:43
  • Your input data is real, so you can also use RealForward, but read about the interpretation of the output. Windowing is used so that your input starts with zero, gently ramps up to the original signal, and at the end gently ramps down to zero again. (1-cos(x))/2 from x=0 to x=pi provides such a gentle ramp function starting horizontally at 0 and ending horizontally at the value 1. Then hold the value 1 and use the same function from -pi to 0 for the ramp down. – Lutz Lehmann Feb 21 '14 at 05:53
  • 1
    Or just use the original Hanning function (1+cos(x))/2 on -pi to pi. You have to map this interval to your time interval, so data buf[k] at index k of N gets multiply with a factor corresponding to x=-pi+k*2*pi/N. – Lutz Lehmann Feb 21 '14 at 06:03
  • @LutzL Is this correct code from original hanning function 'for(int i=0;i – Pandian Feb 21 '14 at 06:26
  • 1
    Yes, that looks correct. Note that if you want to do any further processing of the signal using overlap-add methods that the overlap is exactly half the sampling interval. Then the overlapping window functions add to 1. – Lutz Lehmann Feb 21 '14 at 06:28

0 Answers0