0

I wrote this class, to acquire audio data. I want to use the audio input to sample realtime RF signals. I sample @ 44kHz, and I expect to know the elapsed time by measuring the total acquired samples, knowing the sample frequency.

I don't know why I found a delta time between elapsed time measured by system.nanoTime and acquired samples divided by frequency. Why this delta of about 170ms changing each time I start/stop acquisition? Am I losing samples from acquired signal?

Basically, what I do, is to call this class with the started boolean set to true, then after few seconds I set this boolean to false, then the class exits from the while loop, then I measure the elapsed time and extract the delta.

This is my testing code:

 public class RecordAudio extends AsyncTask<Void, Long, Void> {

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

        try {
            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
            double aquiredSignalLen=0;
            long elapsedTime = System.nanoTime();

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

                double tmpElTime1=(double)bufferReadResult/(double)44000;
                aquiredSignalLen=aquiredSignalLen+tmpElTime1;
            }

            //when i stop the acquisition, i calculate the elapsed time,
            //and i compare the result with the elapsed time measured counting
            //the total number of samples

            elapsedTime = System.nanoTime() - elapsedTime;
            double elapsedTimeDouble=(double)elapsedTime/1000000000;
            double delta=elapsedTimeDouble-aquiredSignalLen;
            audioRecord.stop();


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

I asked this question, to solve this problem: I need to calculate the precise elapsed time between 2 particular signals waveform, received on the microphone input. I would like to have at least 1mS precision, better if higher precision is achievable.. this code was just a starting test. may be counting the samples i can achieve high precision? my fear is that i can lose some samples due to processing time?

Gaucho
  • 1,328
  • 1
  • 17
  • 32

1 Answers1

0

Depending on how the hardware of your device is set up, you may be measuring time using two asynchronous clocks.

The audio codec is quite possibly using its own local oscillator as the word-clock for sampling audio and will be delivering samples at this rate. Meanwhile nanoTime() is derived from the CPU clock. Neither is likely to be a hugely accurate timing reference.

marko
  • 9,029
  • 4
  • 30
  • 46
  • wait @marko, I need to calculate the precise elapsed time between 2 particular signals waveform, received on the microphone input. If your assumptions are correct, The number of samples should be a really accurate timing reference. My only fear is that between a chunk and the next one, some samples are lost (for a reason that now I don't know, in example due to a long signal processing routine). I edited my question, could you update your answer? – Gaucho Oct 29 '13 at 19:10
  • Yes. You definitely ought to do this with sample clock. If you want to verify that you are not dropping samples (which can happen due to buffer overrun), record a pure sinusoid and analyse the recorded signal for discontinuities - or simply example its spectrogram and look for anything that appears at any frequency other than the one you sent to the input. – marko Oct 29 '13 at 22:51