ALSA-管理异步IO [英] ALSA - managing async IO

查看:93
本文介绍了ALSA-管理异步IO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a device that is continuously putting out PCM data. Under certain circumstances I want to record this output. To this end I have a process that waits for the signal to record and when it gets it, it starts a thread (via pthread_create). This thread opens the PCM device and starts recording using snd_async_add_pcm_handler. This handler fn uses pcm_readi to get any available info in the PCM stream and write it to disk.

一切都很好-除了

一旦开始运行,我的调用进程将停止任何周期.它应该继续监听下一个将停止录制的信号.看着执行过程,我发现它运行缓慢,然后在PCM录制开始后就停止了执行.如果我不开始录音,则该应用程序将正常运行并继续响应.

Once this starts running my calling process stops getting any cycles. It should be continuing to listen for the next event that would signal to stop recording. Watching the execution I see it slow and then halt once the PCM recording starts. If I don't start the recording the app runs normally and continues to respond.

所以看来我有两种途径:

So it seems like I'm left with two avenues:

  1. 找到录音过程中的空白和 usleep (或类似方法)以给调用应用程序时间做出响应
  2. 尝试通过其他方式退出录音
  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.众所周知,音频采样将从低振幅开始,先升高一到两秒,然后再降低.我正在使用滚动平均值来捕获此低-高-低,并试图关闭异步IO.

I've failed to make any headway using #1 so I'm working on #2. It's known that the audio sample will start with low amplitude, go high for a second or two and then go low again. I'm using a rolling average to trap this low-high-low and am attempting to close the async IO.

它的位置:应该停止IO后,我尝试调用 snd_async_del_handler ,但这会使应用程序崩溃,并显示一条简单的可能的IO"消息.我也尝试调用 snd_pcm_drop ,但这不会关闭异步io,因此在下次尝试读取时会崩溃.两者按任何顺序组合都会得到相似的响应.

Where it stands: Once the IO is supposed to be stopped I've tried calling snd_async_del_handler but this crashes the app with a simple 'IO possible' message. I've also tried calling snd_pcm_drop but this doesn't close the async io so it crashes the next time it tries to read. Combining the two in either order gives similar responses.

我错过了哪些步骤?

推荐答案

强烈建议不要使用 snd_async _ *函数,因为它们不能与所有类型的设备一起使用,难以使用,并且在实践中没有任何优势.

The snd_async_* functions are strongly deprecated, because they don't work with all kinds of devices, are hard to use, and don't have any advantages in practice.

请注意,ALSA API 不是线程安全的,即,对一个PCM设备的调用必须全部来自一个线程,或者必须是同步的.

Please note that the ALSA API is not thread safe, i.e., calls for one PCM device must all be from one thread, or synchronized.

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

What you should do is to have an event loop (using poll) in your thread that handles both the PCM device and the exit message from the main thread. For this, the PCM device should be run in non-blocking mode (using the snd_pcm_poll_descriptors* functions). To send a message to the thread, use any mechanism with a pollable file handle, such as a pipe or eventfd.

这篇关于ALSA-管理异步IO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆