8

我在使用我的应用程序时出现缓冲区溢出RECORDING。录制在Service. 我无法弄清楚为什么我会从AudioFlinger.

下面我实例化AudioRecord对象并设置它的回调。

bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
aRecorder = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, bufferSize);

aRecorder.setRecordPositionUpdateListener(updateListener);

bytesPerSample = bitsPerSample / 8;
int bytesPerFrame = nChannels * bytesPerSample;
framePeriod = bufferSize / bytesPerFrame; // nr of frames that can be kept in a bufferSize dimension    
int result = aRecorder.setPositionNotificationPeriod(framePeriod);    
buffer = new byte[bufferSize];

audioRecord 回调:

private AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener(){
        public void onPeriodicNotification(AudioRecord recorder){
            int result = aRecorder.read(buffer, 0, buffer.length);
        }

        public void onMarkerReached(AudioRecord recorder)
        {}
    };

我怀疑这个问题与以下有关:aRecorder.setPositionNotificationPeriod(framePeriod);-也许这个 e 的周期太大了bufferSiz,一个更快(更小)的周期将解决这个问题。

有人可以告诉我如何摆脱缓冲区溢出吗?

4

2 回答 2

10

要解决该问题,请将 AudioRecord 的缓冲区大小更改为最小缓冲区大小的 2 倍。

您可以使用AudioRecord.getMinBufferSize()静态方法。这将为您提供用于当前格式的最小缓冲区大小。

getMinBufferSize() 方法的语法是:

public static int getMinBufferSize (
    int sampleRateInHz, int channelConfig, int audioFormat)

在创建 AudioRecord 对象时,任何小于此数字的内容都将导致失败。

您应该减少缓冲区大小,以免音频子系统因数据需求而不堪重负。

请记住将覆盖的方法 ( @Override) 用于 audioRecord 回调,如下所示:

private AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener(){

        @Override
        public void onPeriodicNotification(AudioRecord recorder){
            int result = aRecorder.read(buffer, 0, buffer.length);
        }

        @Override
        public void onMarkerReached(AudioRecord recorder)
        {}
    };

我推荐阅读这篇文章:Android 录音,第 2 部分

您可以尝试的另一件事是在录制时使用线程,在录制的字节上使用其他进程,从而避免主 UI 线程上的过多过载。

此方法的开源示例代码:musicg_android_demo

查看这篇文章了解更多信息 - android-audiorecord-class-process-live-mic-audio-quickly-set-up-callback-func

于 2013-07-26T08:40:28.753 回答
2

那是因为 :

framePeriod = bufferSize / bytesPerFrame;

您需要乘以而不是除以缓冲区大小。

尝试:

framePeriod = bufferSize * bytesPerFrame;

如果您需要一个示例:这是一个完整的音频捕获类

希望能帮助到你

于 2013-07-26T08:37:05.147 回答