2013-07-22 165 views
6

我得到緩衝區溢出,而我的應用程序RECORDING。記錄在Service中執行。我無法弄清楚爲什麼我從AudioFlinger收到此消息。AudioRecord:緩衝區溢出?

下面我實例化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); - 也許是那個時期是太大了,這bufferSiz e和更快的(小)期間將解決這個問題。

有人能告訴我如何擺脫緩衝區溢出?

回答

8

要解決這個問題,改變AudioRecord的緩衝區大小爲2倍,最低緩衝尺寸。

您可以使用AudioRecord.getMinBufferSize()靜態方法。這將爲您提供用於當前格式的最小緩衝區大小。

getMinBufferSize的()的語法的方法是:

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

任何低於這個數目將導致無法在創建AudioRecord對象。

您應該減小緩衝區大小,以免壓倒音頻子系統以滿足數據需求。

記得把爲audioRecord回調覆蓋的方法(@Override)如下:

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 audio recording, part 2

,你可以嘗試一件事是在使用多線程在記錄的字節上記錄另一個進程,從而避免主UI線程上的過載。

這種方法的開放源碼的示例代碼:musicg_android_demo

檢查這個職位更多 - android-audiorecord-class-process-live-mic-audio-quickly-set-up-callback-func

+0

感謝您的回答,所有數據處理都在輔助線程中完成。 bufferSize是使用靜態方法od AudioRecord(getMinBufSize)獲取的。 @overwrite確實缺失。 –

+0

,我昨天試圖將minBufSize乘以2,但只是將「BufferOverlow」味精的頻率降低到〜30秒。無論如何,與2相乘直到現在爲止我嘗試過的最佳變體,但我想徹底擺脫它,因爲我的記錄在1:3小時後停止。 –

+0

所以這意味着在乘以2之後,沒有緩衝區溢出的問題,但是記錄在一段時間之後停止?您可以在釋放之前嘗試重置記錄器。 –

1

那是因爲:

framePeriod = bufferSize/bytesPerFrame; 

你需要繁殖,而不是將你的緩衝區大小。

嘗試:

framePeriod = bufferSize * bytesPerFrame; 

如果你需要一個樣本:here is a complete audio capture class

希望它有助於

+0

感謝。緩衝區應該如下實例化:buffer = new byte [framePeriod * bytesPerFrame]? –

+0

我會嘗試關注你提供的鏈接。我看到它使用輔助線程來記錄而不是回調變體(onPeriodicNotification) –