I'm having troubles using AudioRecord.
An example using some of the code derived from the splmeter project:
private static final int FREQUENCY = 8000;
private static final int CHANNEL = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private int BUFFSIZE = 50;
private AudioRecord recordInstance = null;
...
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, CHANNEL, ENCODING, 8000);
recordInstance.startRecording();
short[] tempBuffer = new short[BUFFSIZE];
int retval = 0;
while (this.isRunning) {
for (int i = 0; i < BUFFSIZE - 1; i++) {
tempBuffer[i] = 0;
}
retval = recordInstance.read(tempBuffer, 0, BUFFSIZE);
... // process the data
}
This works on the HTC Dream and the HTC Magic perfectly without any log warnings/errors, but causes problems on the emulators and Nexus One device.
On the Nexus one, it simply never returns useful data. I cannot provide any other useful information as I'm having a remote friend do the testing.
On the emulators (Android 1.5, 2.1 and 2.2), I get weird errors from the AudioFlinger and Buffer overflows with the AudioRecordThread. I also get a major slowdown in UI responsiveness (even though the recording takes place in a separate thread than the UI).
Is there something apparent that I'm doing incorrectly? Do I have to do anything special for the Nexus One hardware?
EDIT
I've partially solved the problem... The Documentation for AudioRecord says:
public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)
Returns the minimum buffer size required for the successful creation of an AudioRecord object. Note that this size doesn't guarantee a smooth recording under load, and higher values should be chosen according to the expected frequency at which the AudioRecord instance will be polled for new data.for new data.
So I changed the buffer length to
private static final int BUFFSIZE = AudioRecord.getMinBufferSize(FREQUENCY, CHANNEL, ENCODING);
And now the Emulators run well.
But
Hardware doesn't. While the emulators return a value of 640 from that call (giving 12.5 polls per second) based on 8khz, the HTC hardware returns 4096! Meaning roughly 2 polls per second and an audio delay of half a second! Furthermore, that same call on the Nexus One returns 8192! So a full second delay!
I wish it ended at that, but the nexus one still doesn't return any audio (still don't have one myself, so I can't get proper debugging information from one), even though the HTC devices and all emulators now work (even if some are more laggy than others).
Am I doing something horribly wrong here?