2013-07-22 15 views
6

Otrzymuję przepełnienie bufora podczas RECORDING z moją aplikacją. Nagrywanie odbywa się w Service. Nie mogłem zrozumieć, dlaczego otrzymuję tę wiadomość od AudioFlinger.AudioRecord: przepełnienie bufora?

Poniżej przedstawiam obiekt AudioRecord i ustawię jego wywołania zwrotne.

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 zwrotna:

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

Podejrzewam, że problem jest związany z: aRecorder.setPositionNotificationPeriod(framePeriod); - może okres ten jest zbyt duży dla tego bufferSiz e i szybszy (mniejszy) okres rozwiąże problemu .

Czy ktoś może mi powiedzieć, jak pozbyć się przepełnienia bufora?

Odpowiedz

8

Aby rozwiązać ten problem, należy zmienić rozmiar bufora AudioRecord do 2-krotności minimalnego bufora rozmiar.

Można zastosować metodę statyczną AudioRecord.getMinBufferSize(). Zapewni to minimalny rozmiar bufora do użycia w bieżącym formacie.

Składnia getMinBufferSize(), sposób jest następujący:

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

Wszystko mniejsza niż liczba ta będzie powodować uszkodzenia podczas tworzenia przedmiotu AudioRecord.

Powinieneś zmniejszyć rozmiar bufora, aby nie przytłoczyć podsystemu audio wymaganiami dotyczącymi danych.

Pamiętaj, aby umieścić metod przesłonięte (@Override) dla audioRecord zwrotnego następująco:

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

polecam przeczytać post: Android audio recording, part 2

Jeszcze jedno, że można spróbować jest użycie wątki na nagrywanie i inny proces na zapisanych bajtach, unikając w ten sposób zbyt dużego przeciążenia głównego wątku UI.

Otwarta przykładowy kod źródłowy dla tego podejścia: musicg_android_demo

Zobacz ten post dla więcej - android-audiorecord-class-process-live-mic-audio-quickly-set-up-callback-func

+0

Dzięki za odpowiedź, wszystkie przetwarzanie danych odbywa się w wątku dodatkowym. bufferSize jest pobierany za pomocą statycznej metody AudioRecord (getMinBufSize). @overwrite rzeczywiście brakowało. –

+0

i próbowałem wczoraj, aby pomnożyć minBufSize z 2, ale po prostu zmniejszałem częstotliwość "BufferOverlow" msg do ~ 30 sekund. W każdym razie, pomnożenie z 2 było do tej pory najlepszym wariantem, którego próbowałem, ale chcę się go całkowicie pozbyć, ponieważ moje nagranie kończy się po 1: 3 godzinach. –

+0

Oznacza to, że po pomnożeniu przez 2, nie ma problemu z przepełnieniem bufora, ale nagrywanie zatrzymuje się po określonym czasie? Możesz spróbować zresetować nagrywarkę przed jej zwolnieniem. –

1

Ów, ponieważ:

framePeriod = bufferSize/bytesPerFrame; 

trzeba mnożyć i nie podzielić BUFFERSIZE.

spróbuj:

framePeriod = bufferSize * bytesPerFrame; 

A jeśli potrzebujesz próbkę: here is a complete audio capture class

nadzieję, że pomoże

+0

dzięki. Bufor powinien być utworzony w następujący sposób: buffer = new byte [framePeriod * bytesPerFrame]? –

+0

Postaram się podążać za podanym linkiem.Zobaczyłem tam, że używa on dodatkowego wątku do zapisu zamiast wariantu oddzwaniania (onPeriodicNotification). –

Powiązane problemy