Question

I have an application that uses the AudioRecord API to capture audio on Android devices and it repeatedly fails on Galaxy S4 devices. This also occurs in other applications that try to record audio with both AudioRecord and MediaRecorder (AudioRec HQ for example). I was able to reproduce it in a test application using the code below:

final int bufferSize = AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_RECOGNITION, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize << 2);
mAudioRecord.startRecording();

mRecordThread = new Thread(new Runnable() {
    @Override
    public void run() {
        BufferedOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new BufferedOutputStream(new FileOutputStream(String.format(Locale.US, "/sdcard/%1$d.pcm", System.currentTimeMillis())));
            final byte[] buffer = new byte[bufferSize];
            int bytesRead;
            do {
                bytesRead = mAudioRecord.read(buffer, 0, buffer.length);
                if (bytesRead > 0) {
                    fileOutputStream.write(buffer, 0, bytesRead);
                }
            }
            while (bytesRead > 0);
        } catch (Exception e) {
            Log.e("RecordingTestApp", e.toString());
        }
    }
});
mRecordThread.start();

These are the relevant logcat entries:

02-03 15:36:10.913: W/AudioRecord(20986): obtainBuffer timed out (is the CPU pegged?) user=001699a0, server=001699a0
02-03 15:36:11.394: E/alsa_pcm(208): Arec: error5
02-03 15:36:11.394: W/AudioStreamInALSA(208): pcm_read() returned error n -5, Recovering from error
02-03 15:36:11.424: D/ALSADevice(208): close: handle 0xb7730148 h 0x0
02-03 15:36:11.424: D/ALSADevice(208): open: handle 0xb7730148, format 0x2
02-03 15:36:11.424: D/ALSADevice(208): Device value returned is hw:0,0
02-03 15:36:11.424: V/ALSADevice(208): flags 11000000, devName hw:0,0
02-03 15:36:11.424: V/ALSADevice(208): pcm_open returned fd 39
02-03 15:36:11.424: D/ALSADevice(208): handle->format: 0x2
02-03 15:36:11.434: D/ALSADevice(208): setHardwareParams: reqBuffSize 320 channels 1 sampleRate 8000
02-03 15:36:11.434: W/AudioRecord(20986): obtainBuffer timed out (is the CPU pegged?) user=001699a0, server=001699a0
02-03 15:36:11.444: D/ALSADevice(208): setHardwareParams: buffer_size 640, period_size 320, period_cnt 2
02-03 15:36:20.933: W/AudioRecord(20986): obtainBuffer timed out (is the CPU pegged?) user=0017ade0, server=0017ade0
02-03 15:36:21.394: E/alsa_pcm(208): Arec: error5
02-03 15:36:21.394: W/AudioStreamInALSA(208): pcm_read() returned error n -5, Recovering from error
02-03 15:36:21.424: D/ALSADevice(208): close: handle 0xb7730148 h 0x0
02-03 15:36:21.424: D/ALSADevice(208): open: handle 0xb7730148, format 0x2
02-03 15:36:21.424: D/ALSADevice(208): Device value returned is hw:0,0
02-03 15:36:21.424: V/ALSADevice(208): flags 11000000, devName hw:0,0
02-03 15:36:21.424: V/ALSADevice(208): pcm_open returned fd 39
02-03 15:36:21.424: D/ALSADevice(208): handle->format: 0x2
02-03 15:36:21.434: D/ALSADevice(208): setHardwareParams: reqBuffSize 320 channels 1 sampleRate 8000
02-03 15:36:21.434: D/ALSADevice(208): setHardwareParams: buffer_size 640, period_size 320, period_cnt 2
02-03 15:36:21.454: W/AudioRecord(20986): obtainBuffer timed out (is the CPU pegged?) user=0017ade0, server=0017ade0

Here is the full logcat: http://pastebin.com/y3XQ1rMf

No exceptions are thrown when this happens, AudioRecord.read just blocks until the hardware has recovered and started recording again, but loses 2-4 seconds of audio data so it is very annoying for users that their audio files are missing large areas without any explanation as to why.

Is this a known hardware issue or are there things I should be doing differently to record more reliably? Is there any way to detect that this issue has occurred

Was it helpful?

Solution

After trying a wide variety of frequencies, buffer sizes, and audio sources with the AudioRecord and several formats with the MediaRecorder I was not able to record audio without these pcm errors. These same errors happen with several audio recording applications I have downloaded from the play store.

I followed this tutorial to create an OpenSL ES jni library and it has been working well, I would reccomend this approach to anyone who is seeing these errors on the Galaxy S4

OTHER TIPS

I don't have a galaxy at hand, but I see a couple of things wrong with your example.

new AudioRecord(MediaRecorder.AudioSource.VOICE_RECOGNITION, 8000,

First you initialize the AudioRecord at a samplerate of 8000 Hz. As per documentation, only 44100 is guaranteed available. The 8000 Hz samplerate might simply not be there. So you should check whether the AudioRecord is in a correct state by. That is:

mAudioRecord.getState()==STATE_INITIALIZED

You also might want to check the return from getMinimumBufferSize. If it is ERROR_BAD_VALUE then the parameters you passed were incorrect.

Then once done, you might want to start recording within the thread that will read the data. This is very likely not the cause of your problem, but it is often unclear what happens with audiodrivers when an overflow occured. E.g: the hardware might have produced too much data any you didn't read it fast enough. Often alsa drviers behave different depending on who made them. So, to avoid that problem, it is better to write startRecording directly before you start recording, thus in this case, within the runnable.

Once that is done you might want to check the

mAudioRecord.getRecordingState()==RECORDING_RECORDING

if it is not recording, then the driver already tells you there is a problem.

Once you're finished with recording you should also stop the device. Again, some alsa drivers have a timeout to close if you don't close them yourself, meaning that the next time you try to open them, you might simply have no access (this is of course very Linux specific).

So, at a first glance these are the avenues I would take, and my guess is that the combination samplerate/channel configuration is just not available.

Lastly, I also have a feeling that the parameter VOICE_RECOGNITION might be off. Maybe just replace it with DEFAULT. I have had some problems with this myself in the past.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top