Reputation:
I'm currently using the AudioRecord java object to receive audio from the microphone. Sometimes I don't pull data sufficiently fast (E.g, when an application switch occurs). Is there any method for me to know that the audiostream was interrupted with an audiobuffer underflow ?
Upvotes: 4
Views: 1107
Reputation: 807
From your question, I think you mean overflow, rather than underrun. I have the same question, but for an overflow. For underruns, the read method simply blocks until enough data is ready.
Upvotes: 0
Reputation: 40420
You might try using the MediaRecorder class instead of AudioRecord, which offers a few extra methods, including the ability to register an error callback method. I'm not sure if all versions of Android will call that in case of an underrun, though. If you get callbacks here, that would probably be the "cleaner" solution.
The other solution is that you can measure the time taken when polling for audio and determine if an underrun has occurred. Basically, you'd store the time in a local variable before calling read()
and then again afterwards:
long startTime = System.nanoTime();
int bytesRead = read(...);
long elapsedTime = System.nanoTime() - startTime;
You'll probably want to use System.nanoTime()
instead of System.currentTimeMillis()
, even though the time in nanoseconds is not very accurate it will be more accurate than the system's millisecond precision. Then, using the sample rate and the buffer size, you can calculate the expected number of milliseconds this call should take with:
long maxMilliseconds = (bufferSize / getSampleRate()) * 1000;
If the elapsed time is greater than this value, then an audio dropout has probably occurred and you can trigger your error handler.
Also note that the AudioRecord.read()
methods return the number of bytes actually read from the device. You should compare this to the number of bytes you expected to read, as that's a very easy way to detect buffer underruns as well.
Upvotes: 5