Android API Bugs - AudioRecord
10 December 2011
When asking android to record from the mic to a buffer you have to do something like:
mRecorder = new AudioRecord(AudioSource.MIC, RATE, CHANNEL_MODE,
ENCODING, BUFFER_SIZE);
if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
// fail and bail
}
mRecorder.startRecording();
bytesRead = mRecorder.read(audioBuffer, offsetInBuffer, readSize);
mRecorder.stop();
mRecorder.release();
Now the bug that drove me mad was that read() returned zero when I left the application (using the home button) and immediately returned to it. Luckily I was toying around with BUFFER_SIZE when I noticed
mRecorder.getState()
failed when BUFFER_SIZE was set to 0x100, I guessed it was too small and indeed one must call getMinBufferSize() to find out
the limits of AudioRecord instantiation as documented.
Don't use getMinBufferSize() + 1 btw as that throws an IllegalArgumentException at AudioRecorder construction:
12-10 21:49:33.359: E/AndroidRuntime(28950): java.lang.IllegalArgumentException: Invalid audio buffer size.
Using something like
getMinBufferSize() + 100 does work at first but when you use the home-button to leave and return it
causes the read() returning zero bug from time to time. Not always, but from time to time. Also make sure you release() the recorder because forgetting that will also allow you to construct the recorder but reads will fail.
I can't begin to describe how frustrating finding that bug was.
Now audio programmers should know they're supposed to read a size that's a divisor of the buffer size, yes. This doesn't excuse the API from behaving itself and throwing relevant exceptions and errors that are debuggable and documented. This was SdkLevel 8 btw. Things like this make you feel as though these are the guys that wrote the api:
Eventually the working code will be pushed to the
android tuner google code project for your enjoyment.