【问题标题】:AudioRecord: obtainBuffer timed outAudioRecord:获取缓冲区超时
【发布时间】:2012-09-17 08:33:22
【问题描述】:

我的应用程序经常出现以下错误:

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

我创建 AudioRecord 实例的代码是:

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 );

AudioRecord 实例如下:

@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);
        }
    });
}

如图所示,一个单独的线程不断处理音频输入(只要不调用 Activity 的onPause()

有人知道吗?

完整日志:

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

【问题讨论】:

  • 你用的是什么环境?你试过调试吗?
  • @BeQI,问题是间歇性的,难以重现=/。到目前为止,我得到的是:它肯定发生在我的 CM9 稳定 ROM 中,并且当手机重新启动时问题已“修复”。不过,它会在一段时间后再次发生。我的一些应用程序用户也会发生这种情况,但我不知道他们是否使用自定义 rom。
  • 这里:stackoverflow.com/questions/8503874/…,这家伙似乎已经通过更新他的设备固件解决了。我想知道的是是否有人知道如何修复/解决此错误,或者它是否是专门针对自定义 rom 的问题
  • 您能否提供更广泛的代码快照?例如,在您创建实例的方法中,您是否在沿线的其他地方循环使用它?或者是否有任何基于多线程/进程的模式?如果发生其中一种或类似情况,则可能是由于您的代码在运行 x 时间时发生内存泄漏。当我询问您的环境时,我的意思是,您在什么设备上运行它,您使用的是什么 ide,API 中创建的 AudioStreamInALSA 对象的位置,
  • 你到底在用什么记录功能,你在用什么其他库,并提供尽可能多的信息,这样也许我可以在那里找到一些东西

标签: android audio-recording android-audiorecord


【解决方案1】:

我有类似的问题。不幸的是,我不得不用 AudioRecord 创建多个线程,所以使用 while(recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING){ 没有帮助:(

最后我挖掘了这个话题:Android AudioRecord - Won't Initialize 2nd time 之后 audioRecord.release(); 工作正常 :)

也许它会在未来帮助某人......

【讨论】:

    【解决方案2】:

    有什么原因,为什么你不断地打开和关闭录音机? 我会这样说:

        // 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();
    

    我可以想象,记录器可以提供的不仅仅是缓冲区大小,但您总是只读取该数量的字节。

    在我的应用程序中,我有一些方法可以从我的 run() 方法之外启动和停止记录器(我认为您在设置 keepRunning 时也这样做)。在其他地方停止录音机时,您 只需要像这样调整你的while循环:

    while(recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING){
    

    【讨论】:

    • 到目前为止它已经奏效了。至少应用程序的响应也更好,所以当我在这里进一步测试时,我会将您的答案标记为已接受的答案。谢谢=]
    猜你喜欢
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 2012-11-09
    • 1970-01-01
    相关资源
    最近更新 更多