简体   繁体   中英

How to stop Android openSLES audio recorder properly?

I have a native audio recorder using openSLES in Android. The recorder works but when the stop method is called, it seems to continue write buffers, as I continue to get the logs:

...
08-07 01:36:43.229: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
08-07 01:36:43.239: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
08-07 01:36:43.249: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
...

I am using the thread lock method to record the buffers, but why am I getting these logs after stopping the recorder as follows:

typedef struct opensl_stream {
...
  SLObjectItf recorderObject;
  SLRecordItf recorderRecord;
  SLAndroidSimpleBufferQueueItf recorderBufferQueue;
...
} OPENSL_STREAM;

OPENSL_STREAM  *p;
//starting recorder
...
//stopping recorder
if (p->recorderObject != NULL) {
    (*p->recorderObject)->Destroy(p->recorderObject);
    p->recorderObject = NULL;
    p->recorderRecord = NULL;
    p->recorderBufferQueue = NULL;
  }

After trying to stop the recorder as above I still get the AudioRecord(6194): Overrun user log, which means buffer is read but not used. How can I stop recording properly?

First, you should stop the recorder before destroying it, but that's not enough.

Since OpenSL callbacks are called from its own thread, stopping the recorder from another thread does not mean immediately all callbacks halt. (Or no new callbacks will be called.) Therefore you have to 'count' how many buffers you enqueued, so in the callback you can count how many callbacks were processed.

So the pseudo code looks something like this:

  • stop the recorder by setting the record state to SL_RECORDSTATE_STOPPED , do not enqueue more buffer queues.
  • wait till all the enqueued buffer queues were processed by checking your counter(s).
  • destroy the recorder, and free up other resources (memory) that might be used by your callback.

When enqueueing bufferques, and at the end of opensl callbacks you have to count the enqueued / processed buffer queues yourself in a thread safe manner.

You can use pthread mutexes / conditions / broadcasting while waiting for all the processing happen. (Or you may use a simple while loop with some sleeping some inside.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM