3

I'm constantly getting the following error on my app:

09-25 15:52:24.875: E/AudioHardware(144): -----AudioStreamInALSA::read(0x42db0040, 512) END ERROR
09-25 15:52:24.875: E/AudioFlinger(144): Error reading audio input
09-25 15:52:24.882: D/AudioHardware(144): AudioStreamInALSA::setParameters() routing=0
09-25 15:52:25.394: W/AudioRecord(7359): obtainBuffer timed out (is the CPU pegged?) user=00000000, server=00000000
09-25 15:52:25.398: D/AudioHardware(144): AudioStreamInALSA::setParameters() input_source=1;routing=262144

My code to create the AudioRecord instance is:

int minValue = AudioRecord.getMinBufferSize(sampleRate,
        AudioFormat.CHANNEL_IN_MONO, 
        AudioFormat.ENCODING_PCM_16BIT);

// Gets a buffer size that is greater than the minimun required and is multiple of the chunk size
BUFFER_SIZE_IN_BYTES = getBufferSizeInChunks(minValue);

AudioRecord audioRecord =  new AudioRecord(
        MediaRecorder.AudioSource.MIC,
        sampleRate,
        AudioFormat.CHANNEL_IN_MONO,
        AudioFormat.ENCODING_PCM_16BIT ,
        BUFFER_SIZE_IN_BYTES );

And the AudioRecord instance like this:

@Override
public void run() {
    try{
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

        recorder = initAudioRecord();
        if (recorder.getState() != AudioRecord.STATE_INITIALIZED) {
            return;
        }

        // Audio input buffer
        byte[] audio_data = new byte[BUFFER_SIZE_IN_BYTES];

        while (!Thread.interrupted() && keepRunning) {
            recorder.startRecording();
            recorder.read(audio_data, 0, BUFFER_SIZE_IN_BYTES);


            recorder.stop();

                // Here I deal with the audio_data ...

                // UI feedback
                PostToUI(frequency);

            }

    }
    catch(Exception e){
        e.printStackTrace();
    }
}

private void PostToUI(final double frequency) {
    handler.post(new Runnable() {
        public void run() {
            uiHandler.updateUi(frequency);
        }
    });
}

A separated Thread constantly deals with the audio input as shown (as long as the Activity's onPause() is not called)

Does anybody have some clue?

FULL LOG:

09-27 14:05:29.246: D/AudioHardware(144): AudioStreamInALSA::setParameters() input_source=1;routing=262144
09-27 14:05:29.246: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
09-27 14:05:29.246: V/AudioHardware(144): setInputSource_l(1)
09-27 14:05:29.246: V/AudioHardware(144): closeMixer_l() mMixerOpenCnt: 1
09-27 14:05:29.246: D/AudioHardware(144): AudioHardware pcm capture is exiting standby.
09-27 14:05:29.246: V/AudioHardware(144): AudioStreamInALSA exit standby mNeedEchoReference 0 mEchoReference 0x0
09-27 14:05:29.246: V/AudioHardware(144): open pcm_in driver
09-27 14:05:29.312: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
09-27 14:05:29.312: V/AudioHardware(144): read() wakeup setting route Main Mic
09-27 14:05:41.593: D/Finsky(12273): [1] 5.onFinished: Installation state replication succeeded.
09-27 14:05:49.332: W/AudioHardware(144): read error: -1
09-27 14:05:49.332: D/AudioHardware(144): AudioHardware pcm capture is going to standby.
09-27 14:05:49.332: V/AudioHardware(144): closeMixer_l() mMixerOpenCnt: 1
09-27 14:05:49.375: E/AudioHardware(144): -----AudioStreamInALSA::read(0x42b2d040, 512) END ERROR
09-27 14:05:49.375: E/AudioFlinger(144): Error reading audio input
09-27 14:05:49.386: D/AudioHardware(144): AudioStreamInALSA::setParameters() routing=0
09-27 14:05:49.906: W/AudioRecord(13013): obtainBuffer timed out (is the CPU pegged?) user=00000000, server=00000000
09-27 14:05:49.910: D/AudioHardware(144): AudioStreamInALSA::setParameters() input_source=1;routing=262144
09-27 14:05:49.914: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
09-27 14:05:49.914: V/AudioHardware(144): setInputSource_l(1)
09-27 14:05:49.914: V/AudioHardware(144): closeMixer_l() mMixerOpenCnt: 1
09-27 14:05:49.921: D/AudioHardware(144): AudioHardware pcm capture is exiting standby.
09-27 14:05:49.921: V/AudioHardware(144): AudioStreamInALSA exit standby mNeedEchoReference 0 mEchoReference 0x0
09-27 14:05:49.921: V/AudioHardware(144): open pcm_in driver
09-27 14:05:50.000: V/AudioHardware(144): openMixer_l() mMixerOpenCnt: 0
slezadav
  • 6,104
  • 7
  • 40
  • 61
Alesqui
  • 6,417
  • 5
  • 39
  • 43
  • What kind of environment are you using? Did you try to debug? – sed Oct 03 '12 at 14:05
  • @BeQI, the problem is intermittent and difficult to reproduce =/. What I've got so far is: it certainly happens in my CM9 stable rom and the problem is "fixed" when the phone is rebooted. It happens again after some time, though. It also happens with some of my app's users, but I don't know it they are using custom roms or not. – Alesqui Oct 03 '12 at 15:00
  • Here: http://stackoverflow.com/questions/8503874/audiorecord-obtainbuffer-timed-out-with-audiorecorder-startrecording, the guy seems to have solved by updating his device firmware. What I wish to know is if someone knows how to fix/workaround this error, or if it is a problem specifically for custom roms – Alesqui Oct 03 '12 at 15:03
  • Can you provide a wider snapshot of your code? For example, in the method where you create the instance, do you use it in a loop somewhere else along the line? Or is there any multi thread/process based pattern along the? If one of these or something similar is happening it could be due to your code leaking memory when your code runs for x amount of time. When I asked for your environment I meant , what device are you running this in, what ide are you using, where in the API is AudioStreamInALSA object created at, – sed Oct 03 '12 at 21:36
  • what exactly are you using the record functionality for, what other libraries are you using with and provide as much possible information as possible so that maybe I could pick something up there – sed Oct 03 '12 at 21:36
  • @BeQI, I edited my post with more information. Basically, there is a thread that keeps reading the audio buffer and getting the most significative frequency, which is passed to an UI handler object. And the only audio related API that I use is the AudioRecord, which is instantiated as I showed. Many thanks for the feedback... hope things are more clear now. – Alesqui Oct 03 '12 at 23:04

2 Answers2

2

Is there any reason, why you continously turn recorder on and off? I would have put it like this:

    // Audio input buffer
    byte[] audio_data = new byte[BUFFER_SIZE_IN_BYTES];

    recorder.startRecording();
    while (!Thread.interrupted() && keepRunning) {
        recorder.read(audio_data, 0, BUFFER_SIZE_IN_BYTES);
            // Here I deal with the audio_data ...
            // UI feedback
            PostToUI(frequency);
    }
    recorder.stop();

I could imagine, that the recorder could deliver more than only buffer size, but you always just read that amount of bytes.

In my app, I have methods to start and stop the recorder from outside my run() method (I think you do similar with setting keepRunning). When stopping recorder somewhere else, you just have to adjust your while-loop like this:

while(recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING){
Schlangi
  • 1,135
  • 1
  • 9
  • 19
  • So far it has worked. At least the app's response is better as well, so while I test further here, I'll mark you answer as the accepted one. Thanks =] – Alesqui Oct 04 '12 at 14:37
0

I had similar problem. Unfortunately I had to create more than one thread with AudioRecord, so using while(recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING){ didnt help :(

Finaly I dig up this topic: Android AudioRecord - Won't Initialize 2nd time and after audioRecord.release(); works fine :)

Maybe it will help someone in future...

Community
  • 1
  • 1
Sirtarius
  • 128
  • 8