2013-07-22 29 views
6

Ricevo buffer overflow mentre RECORDING con la mia app. La registrazione viene eseguita in un Service. Non riesco a capire perché sto ricevendo questo messaggio da AudioFlinger.AudioRecord: buffer overflow?

Sotto istanziare l'oggetto AudioRecord e impostarne le richiamate.

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

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

Ho il sospetto che il problema è legato alla: aRecorder.setPositionNotificationPeriod(framePeriod); - forse il periodo è troppo grande per questo bufferSiz e ed una più veloce (più piccolo) periodo risolverà il problema .

Qualcuno potrebbe dirmi come sbarazzarsi del buffer overflow?

risposta

8

Per risolvere questo problema, modificare la dimensione del buffer di AudioRecord a 2 volte il buffer minima dimensione.

È possibile utilizzare il metodo statico AudioRecord.getMinBufferSize(). Questo ti darà la dimensione minima del buffer da utilizzare per il tuo formato corrente.

La sintassi di getMinBufferSize() metodo:

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

Qualsiasi cosa meno di questo numero può causare un errore durante la creazione dell'oggetto AudioRecord.

Si avrebbe dovuto ridurre la dimensione del buffer, in modo da non sovraccaricare il sottosistema audio con richieste di dati.

Ricordatevi di mettere i metodi di override (@Override) per audioRecord callback come segue:

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

vi consiglio di leggere il post: Android audio recording, part 2

Una cosa che si potrebbe provare è quella di utilizzare le discussioni su registrazione e l'altro processo sui byte registrati, evitando così troppo sovraccarico sul thread principale dell'interfaccia utente.

La fonte codice di esempio aperto per questo approccio: musicg_android_demo

controllare questo post per di più - android-audiorecord-class-process-live-mic-audio-quickly-set-up-callback-func

+0

Grazie per la risposta, tutta l'elaborazione dei dati avviene in un thread secondario. bufferSize viene utilizzato con il metodo statico di AudioRecord (getMinBufSize). il @overwrite mancava davvero. –

+0

e ho provato ieri a moltiplicare minBufSize con 2, ma riducevo la frequenza del msg "BufferOverlow" a ~ 30 sec. Ad ogni modo, moltiplicando con 2 fino ad ora è stata la migliore variante che ho provato, ma voglio eliminarla completamente, poiché la mia registrazione si interrompe dopo 1: 3 ore. –

+0

Quindi questo significa che dopo aver moltiplicato con 2, non c'è alcun problema di overflow del buffer ma la registrazione si sta fermando dopo un certo periodo di tempo? Potresti provare a resettare il registratore prima di rilasciarlo. –

1

Ecco perché:

framePeriod = bufferSize/bytesPerFrame; 

è necessario moltiplicare e non dividere il buffersize.

Prova con:

framePeriod = bufferSize * bytesPerFrame; 

E se avete bisogno di un campione: here is a complete audio capture class

Speranza che aiuta

+0

grazie. Il buffer dovrebbe essere istanziato come segue: buffer = new byte [framePeriod * bytesPerFrame]? –

+0

Proverò a seguire il collegamento che hai fornito.Ho visto lì che utilizza un thread secondario per registrare al posto della variante di callback (onPeriodicNotification) –