centos - ALSA - 管理异步 IO

标签 centos alsa

我有一个不断输出 PCM 数据的设备。在某些情况下我想记录这个输出。为此,我有一个等待信号记录的进程,当它收到信号时,它会启动一个线程(通过 pthread_create)。此线程打开 PCM 设备并使用 snd_async_add_pcm_handler 开始录制。此处理程序 fn 使用 pcm_readi 获取 PCM 流中的任何可用信息并将其写入磁盘。

一切都很好 - 除了

一旦开始运行,我的调用进程将停止获取任何周期。它应该继续监听下一个发出停止记录信号的事件。观察执行过程,我发现它很慢,然后在 PCM 记录开始后停止。如果我不开始录制,应用程序会正常运行并继续响应。

看来我有两条路:

  1. find gaps in the recording process and usleep (or similar) to give the calling app time to respond
  2. attempt to exit the recording using other means

我使用 #1 没有取得任何进展,所以我正在研究 #2。众所周知,音频样本将从低振幅开始,在一两秒内变高,然后再次变低。我正在使用滚动平均值来捕获这个 low-high-low 并试图关闭异步 IO。

目前的情况:一旦 IO 应该停止,我尝试调用 snd_async_del_handler 但这会使应用程序崩溃并显示一条简单的“IO 可能”消息。我也试过调用 snd_pcm_drop 但这不会关闭异步 io,所以它在下次尝试读取时崩溃。以任一顺序将两者结合起来会得到类似的响应。

我错过了什么步骤?

最佳答案

snd_async_* 函数已被强烈反对,因为它们不适用于所有类型的设备,难以使用,并且在实践中没有任何优势。

请注意 ALSA API is not thread safe ,即对一个 PCM 设备的调用必须全部来自一个线程,或者是同步的。

你应该做的是在你的线程中有一个事件循环(使用poll)来处理PCM设备和来自主线程的退出消息。 为此,PCM 设备应以非阻塞模式运行(使用 snd_pcm_poll_descriptors* 函数)。 要向线程发送消息,请使用任何具有可轮询文件句柄的机制,例如管道或 eventfd

关于centos - ALSA - 管理异步 IO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14882433/

相关文章:

bash - CentOS,将 ipV6 短格式转换为长格式

linux - ALSA 中的 DAPM 路由

ssh - 在没有 Tomcat 的情况下运行 Jenkins,尝试 SSH

centos - 如何在不使用 Apache 和 PHP 的情况下在一台 VM 上安装 Nagios 以检查另一台 VM(客户端)的特定统计信息?

node.js - cron运行Nodejs不工作

Android、msm_pcm_out 设备和 ALSA 库

linux - 阿尔萨 : How to do stop and resume audio?

c - Alsa 库 32 位

c++ - 奇怪的 PulseAudio 监控设备行为

centos - Apache CloudStack : No templates showing when adding instance