1

PCMデータを継続的に出力しているデバイスがあります。特定の状況下で、この出力を記録したいと思います。この目的のために、シグナルが記録されるのを待ち、シグナルを受け取ると、スレッドを開始するプロセスがあります(経由pthread_create)。このスレッドはPCMデバイスを開き、を使用して記録を開始しsnd_async_add_pcm_handlerます。このハンドラーfnはpcm_readi、PCMストリームで利用可能な情報を取得し、それをディスクに書き込むために使用します。

すべてうまくいっています-を除いて

これが実行を開始すると、呼び出しプロセスはサイクルの取得を停止します。録音を停止するように信号を送る次のイベントを引き続きリッスンする必要があります。実行を見ると、速度が遅く、PCM記録が開始されると停止します。録音を開始しない場合、アプリは正常に実行され、応答を続けます。

ですから、私には2つの道が残っているようです。

  1. 録音プロセスおよび(または同様の)ギャップを見つけusleepて、呼び出し元のアプリに応答する時間を与えます
  2. 他の手段を使用して記録を終了しようとします

#1を使って前進できなかったので、#2に取り組んでいます。オーディオサンプルは低振幅で始まり、1〜2秒間ハイになり、その後再びローになることが知られています。この低-高-低をトラップするために移動平均を使用しており、非同期IOを閉じようとしています。

現状:IOが停止することになったら、呼び出しを試みましsnd_async_del_handlerたが、これによりアプリがクラッシュし、単純な「IO可能」メッセージが表示されます。私も呼び出してみましsnd_pcm_dropたが、非同期ioが閉じないため、次に読み込もうとしたときにクラッシュします。2つをいずれかの順序で組み合わせると、同様の応答が得られます。

どのステップを逃しましたか?

4

1 に答える 1

3

*関数は、snd_async_すべての種類のデバイスで機能するわけではなく、使いにくく、実際には利点がないため、非推奨になっています。

ALSA APIはスレッドセーフではないことに注意してください。つまり、1つのPCMデバイスの呼び出しは、すべて1つのスレッドからのものであるか、同期されている必要があります。

実行する必要があるのはpoll、PCMデバイスとメインスレッドからの終了メッセージの両方を処理するイベントループ(を使用)をスレッドに含めることです。このため、PCMデバイスは非ブロッキングモードで実行する必要があります(snd_pcm_poll_descriptors*関数を使用)。スレッドにメッセージを送信するにはpoll、パイプや。など、ファイルハンドルが可能なメカニズムを使用しますeventfd

于 2013-02-14T20:12:25.540 に答える