UPDATE: this bug in Android was fixed somewhere after 4.2.2 and before 5.01. At 5.01, callbacks work just like the documents say they should.
It seems that read blocked due to some shortsighted developers.
In principle, when the audio recorder is initialized, it allocates a kind of ring buffer, and when .start() reports .start() , it starts writing to this buffer.
Then, when .read() is called, it reads up to half the size of the buffer (or the requested size, whichever is smaller) and returns.
If he wants to read 1000 samples and only 900 are available, he needs to wait another 100 samples before returning. If, however, there are more than 1000 samples, he instantly reads them, and then immediately returns.
Ideally, they would either provide a non-blocking read so that the returned everything that is available is available, or provide an opportunity to know when full data availability is available so that a non-blocking read can be performed.
I do not think they support the first. It looks like they are trying to support the second one using the given period callback method, but so far I canβt get this call at the right time to make a quick non-blocking read.
I cloned the full source (8.5G bytes) of the C ++ source code, and I'm trying to execute functionality across all layers to see how it should work.
The trick for non-blocking .read(0) ing should only be read when ready-made samples are ready. But determining when this condition is true is something that I have not yet understood.
References: Here is the java code for .read (), which calls its own C ++ function:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.4_r1/android/Media/AudioRecord.java # AudioRecord.read% 28java.nio.ByteBuffer% 2Cint% 29
The above read () method calls native native_read_in_direct_buffer() , which is located in:
http://pdroid.googlecode.com/svn/android-2.3.4_r1/trunk/frameworks/base/core/jni/android_media_AudioRecord.cpp
which calls or points to android_media_AudioRecord_readInByteArray() , which in turn calls AudioRecord.read() in frameworks/base/media/libmedia/frameworks/base/media/libmedia/AudioRecord.cpp (as much as possible), and it looks like in this function has a do / while loop, which essentially blocks to the desired number (or half the buffering, whichever is less).
I tried to make the callbacks function well, but they only seemed to call back when read () had to wait for the sound buffer to fill before it could return - so thatβs the point.
My next goal is to try to track down the source code of the notification callback so that I can guess what exactly should and when.