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 е и быстрее (меньше) период будет решить вопрос ,

Может ли кто-нибудь сказать мне, как избавиться от переполнения буфера?

ответ

8

Чтобы устранить эту проблему, измените размер буфера 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 audio recording, part 2

Еще одна вещь, которую вы могли бы попробовать это использовать потоки на запись и другой процесс на записанных байтах, что позволяет избежать слишком большой перегрузки основного потока пользовательского интерфейса.

Открытый исходный код образец для такого подхода: 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» msg до ~ 30 секунд. Во всяком случае, умножение на 2 было до сих пор лучшим вариантом, который я пробовал, но я хочу полностью избавиться от него, так как моя запись останавливается через 1: 3 часа. –

+0

Значит, после умножения на 2 проблема с переполнением буфера отсутствует, но запись останавливается через определенное время? Вы можете попытаться сбросить рекордер, прежде чем выпускать его. –

1

Это потому, что:

framePeriod = bufferSize/bytesPerFrame; 

Вы должны размножаться и не разделить размер буфера.

Try с:

framePeriod = bufferSize * bytesPerFrame; 

И если вам нужен образец: here is a complete audio capture class

надеюсь, что это помогает

+0

спасибо. Буфер должен быть создан следующим образом: buffer = new byte [framePeriod * bytesPerFrame]? –

+0

Я постараюсь выполнить приведенную вами ссылку.Я видел там, где вместо вторичного потока используется вторичный поток (onPeriodicNotification) –

Смежные вопросы