2013-02-14 102 views
1

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

一切都很好 - 除了

一旦开始运行我的呼唤进程停止得到任何周期。它应该继续倾听下一个会停止录音的事件。看着执行,我看到它缓慢,然后一旦PCM录制开始就停下来。如果我没有开始录音,那么应用程序正常运行并继续响应。

所以好像我离开有两个途径:

  1. 在录制过程中寻找差距和usleep(或类似)给调用应用程序时间来响应
  2. 试图退出使用其他方式录制

我没有使用#1的任何进展,所以我正在#2工作。众所周知,音频采样将以较低的幅度开始,高一些或两秒,然后再降低。我使用滚动平均值来捕获这个低 - 高 - 低,并试图关闭异步IO。

它的立场:一旦IO应该停止,我已经尝试调用snd_async_del_handler,但这会使应用程序崩溃,并带有一个简单的“IO可能”消息。我也尝试过拨打snd_pcm_drop,但这并没有关闭异步io,因此下次尝试读取时会崩溃。以任何一种顺序组合这两种结果都可以得出类似的结果

我错过了哪些步骤?

回答

2

snd_async_ *函数强烈弃用,因为它们不适用于各种设备,很难使用,并且在实践中没有任何优势。

请注意,ALSA API is not thread safe,即要求一个PCM设备必须全部来自一个线程或同步。

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

+0

我试过一些其他的ALSA fns,看起来像ASYNC_ *是唯一给我可靠数据的。我没有意识到他们不是线程安全的。伊克。我可能必须将ALSA代码与我的信号代码esp结合起来,因为两者都是从同一设备读取的。哎呀。 – ethrbunny 2013-02-14 21:06:14