2013-02-14 126 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