gpt4 book ai didi

android - 如何正确停止 Android openSLES 录音机?

转载 作者:行者123 更新时间:2023-11-29 21:03:46 28 4
gpt4 key购买 nike

我有一个在 Android 中使用 openSLES 的 native 录音机。记录器可以工作,但是当调用停止方法时,它似乎继续写入缓冲区,因为我继续获取日志:

...
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
...

我正在使用线程锁定方法记录缓冲区,但是为什么我在停止记录器后得到这些日志,如下所示:

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

在尝试按上述方式停止录音机后,我仍然收到 AudioRecord(6194): Overrun user 日志,这意味着缓冲区已读取但未使用。如何正确停止录制?

最佳答案

首先,您应该在销毁记录器之前将其停止,但这还不够。

由于 OpenSL 回调是从其自己的线程调用的,因此从另一个线程停止记录器并不意味着所有回调都会立即停止。 (或者不会调用新的回调。)因此您必须“计算”您排队的缓冲区数量,因此在回调中您可以计算处理了多少回调。

所以伪代码看起来像这样:

  • 通过将记录状态设置为 SL_RECORDSTATE_STOPPED 来停止记录器,不要排队更多的缓冲队列。
  • 等待所有排队的缓冲区队列通过检查您的计数器来处理。
  • 销毁记录器,并释放您的回调可能使用的其他资源(内存)。

当排队缓冲区时,在 opensl 回调结束时,您必须以线程安全的方式自己计算排队/处理的缓冲区队列。

您可以在等待所有处理发生时使用 pthread 互斥/条件/广播。 (或者您可以使用一个简单的 while 循环,其中一些在内部休眠。)

关于android - 如何正确停止 Android openSLES 录音机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25172180/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com