0

i am writing a program on smartphone (on Android) It is about :

  1. Analyzing spectrum of sound by fft algorithms
  2. measuring the intensity of a sound have f = fo (ex. fo = 18khz) from the spectrum which I have got results from the analysis above.
  3. Calculating the distance from smartphone to source of sound with this intensity

After fft, I got two arrays (real and image). I calculate the sound intensity at f=18000hz( suppose that source of sound at 18000 hz is unchanged so that it makes it easier to measure sound intensity). As follow:

frequency at bin FFT[i] is :

    if i <= [N/2] then i * SamplingFrequency / N
    if i >= [N/2] then (N-i) * SamplingFrequency / N

therefore at frequency = 18000hz then I choose i = 304

    sound intensity  = real_array[304] * real_array[304] + image_array[304] * image_array[304]

However, the intensity, in fact, varies a lot making it difficult to measure the distance. And, I have no idea how to explain this.

Besides, I would like to ask you a question that the intensity I have measured above uses what unit to calculate.

Here is my code:

a. fft algorithms( I use fft 512 point)

import define.define512;

public class fft {

private static  float[] W_real;
private static float[] W_img;
private static  float[] input_real= new float[512];
private static  float[] input_img;

//input_real1 is values from mic(smartphone)

//output is values of sound intensity

public static void FFT(float[] input_real1, float[] output)
{
    for(int i =0;i<512;i++) input_real[i] = input_real1[i];
    input_img = new float[512];
    W_real = define512.W_IMAG;
    W_img = define512.W_IMAG;
    int[] W_order = define512.ORDER;
    float[] output_real = new float[512], output_img = new float[512];

    fftradix2(0,511);

//reorder deals with inverse bit

    reorder(input_real, input_img, output_real, output_img, W_order, 512);

    for(int i =0;i<512;i++)
    {
        output[i] = sqrt((output_real[i]*output_real[i] + output_img[i]*output_img[i]));
    }


}
private static  void reorder(float[] in_real,float[] in_imag, float[] out_real,float[] out_imag,int[] order,int N){         
    for(int i=0;i<N;i++){
        out_real[i]=in_real[order[i]];
        out_imag[i]=in_imag[order[i]];
    }
}

//fft algorithms

private static  void fftradix2(int dau,int cuoi)
{
    int check = cuoi - dau;
    if (check == 1)
    {


        input_real[dau] = input_real[dau] + input_real[cuoi];
        input_img[dau] = input_img[dau] + input_img[cuoi];

        input_real[cuoi] = input_real[dau] -2* input_real[cuoi];
        input_img[cuoi] = input_img[dau] -2* input_img[cuoi];


    }
    else
    {
        int index = 512/(cuoi - dau + 1);           
        int tg = (cuoi - dau)/2;
        fftradix2(dau,(dau+tg));
        fftradix2((cuoi-tg),cuoi);
        for(int i = dau;i<=(dau+tg);i++)
        {

             input_real[i] = input_real[i] + input_real[i+tg+1]*W_real[(i-dau)*index] - input_img[i+tg+1]*W_img[(i-dau)*index];
             input_img[i] = input_img[i] + input_real[i+tg+1]*W_img[(i-dau)*index] + input_img[i+tg+1]*W_real[(i%(tg+1))*index];

             input_real[i+tg+1] = input_real[i] -2* input_real[i+tg+1]*W_real[(i-dau)*index] +2* input_img[i+tg+1]*W_img[(i-dau)*index];
             input_img[i+tg+1] = input_img[i] -2* input_real[i+tg+1]*W_img[(i-dau)*index] -2* input_img[i+tg+1]*W_real[(i-dau)*index];

        }
    }
}
    }

b. code use mic in smartphone

    NumOverlapSample = 800;
    NumNewSample = 224;
    private static int Fs = 44100; 
    private byte recorderAudiobuffer[] = new byte [1024];
    AudioRecord recorder = new  AudioRecord(AudioSource.MIC, Fs, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 4096);
    //start recorder
    recorder.startRecording();

    timer.schedule(new task_update(), 1000, 10);
    class task_update extends TimerTask
{
    @Override
    public void run() {
        // TODO Auto-generated method stub

        for(int i=0;i<NumOverlapSample;i++)
             recorderAudiobuffer[i] = recorderAudiobuffer[i+NumNewSample];
        int bufferRead = recorder.read(recorderAudiobuffer,NumOverlapSample,NumNewSample);
        convert.decode(recorderAudiobuffer, N, input);
        fft.FFT(input, output);
    }

and my soucre https://www.box.com/s/zuppzkicymfsuv4kb65p

thanks for all

giang.ngo
  • 47
  • 4
  • You seem to be confused about which bin to look at for 18 kHz. If your FFT size is 512 and sample rate is 44.1 kHz then the bin index will be 512 * 18000 / 44100 = 209. See [this question](http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft-result/4371627#4371627) for a fuller explanation. – Paul R May 13 '13 at 16:44
  • 1
    You are not going to be able to measure distance this way. – Chris Stratton May 13 '13 at 17:40
  • according to theory: frequency at bin FFT[k] is : if k <= [N/2] then k * SamplingFrequency / N if k >= [N/2] then (N-k) * SamplingFrequency / N then FFT[209] = FFT[304] because they are symmmetric to each other when i test on smartphone, bin which is at position of 209 is less than zero. Hence, i used bin at position of 304 Do you have any ideas related to this? – giang.ngo May 16 '13 at 16:46

1 Answers1

0

At 18 kHz, microphone type, position and direction, as well as sound reflections from the nearby acoustic environment will strongly influence the sound level.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • i have tested and realized that the frequency of noise of environment is often less than 18khz a lot. In this project, some problems such as position, reflections and direction, i have not paid attention. Both of position and direction, i didnt change in times of measuring. Do you have any ideas related to this? – giang.ngo May 16 '13 at 16:58