我有一台不断推出PCM数据的设备。在某些情况下,我想记录此输出。为此,我有一个等待信号记录的过程,当它得到它时,它启动一个线程(通过pthread_create
)。该线程打开PCM设备并使用snd_async_add_pcm_handler
开始录制。此处理程序fn使用pcm_readi
获取PCM流中的任何可用信息并将其写入磁盘。
一切都很好 - 除了
一旦开始运行,我的调用过程将停止任何循环。它应该继续听取下一个发出停止录音的事件。看着执行我看到它很慢,然后一旦PCM录音开始就停止。如果我没有开始录制,应用程序会正常运行并继续响应。
所以看起来我有两条途径:
- 在录制过程中发现空白并
usleep
(或类似)给予调用应用时间回复- 尝试使用其他方式退出录音
醇>
我没有使用#1取得任何进展,所以我正在研究#2。众所周知,音频采样将以低幅度开始,高电平持续一两秒,然后再次变为低电平。我正在使用滚动平均值来捕获这个低 - 高 - 低并试图关闭异步IO。
它的位置:一旦IO应该被停止,我已经尝试调用snd_async_del_handler
但是这会使用简单的“IO可能”消息使应用程序崩溃。我也尝试过调用snd_pcm_drop
,但这并没有关闭async io,因此下次尝试读取时会崩溃。将这两者组合在一起会产生类似的反应。
我错过了哪些步骤?
答案 0 :(得分:2)
snd_async_
*功能被强烈弃用,因为它们不适用于所有类型的设备,难以使用,并且在实践中没有任何优势。
请注意,ALSA API is not thread safe,即呼叫一个PCM设备必须全部来自一个线程,或同步。
你应该做的是在你的线程中有一个事件循环(使用poll
)来处理PCM设备和来自主线程的退出消息。
为此,PCM设备应以非阻塞模式运行(使用snd_pcm_poll_descriptors
*功能)。
要向线程发送消息,请使用具有poll
文件句柄的任何机制,例如管道或eventfd
。