0

スレッドのプールを使用して、リアルタイムよりもはるかに高速なレートで出力を生成するオーディオ DSP アプリケーションがあります。これはゲームでの使用を目的としており、オーディオはかなり低いレイテンシーでストリーミングする必要があります。完成した各バッファーは、最終的にメイン ミキサー スレッドに送られ、そこからアプリケーション プログラマーに渡す必要があります。メイン クラスに read_samples メソッドがあり、バッファ ポインタと読み取るサンプル数を受け取り、実際に読み取ったサンプル数を返す可能性があると考えました。

ロックフリーの fifo、つまり、boost.lockfree からのシングル プロデューサー/シングル コンシューマー キューを調べています。私の現在の設計目標は次のとおりです。

  1. データが fifo に非常に迅速にプッシュインおよびプッシュアウトされることが重要であるため、ブロッキング操作をできるだけ少なくしたいと考えています。多くのオーディオ I/O サブシステムが (コールバックなどを介して) データを受信するため、ほとんどの場合、アプリケーション プログラマーはメイン クラスの read_samples メソッドを割り込みレベル優先スレッド内で呼び出します。したがって、ポイント 2 と 3 に行き着きます。

  2. read_samples が呼び出され、要求された量を配信するのに十分なサンプルが fifo にない場合は、(もしあれば) 持っているものを取り、ブロックせずにすぐに返す必要があります。ロックして待機すると、割り込みレベルのスレッド コールバックが関与する可能性のある他の多くのオーディオ再生に影響を与える可能性があります。

  3. プロデューサーがフル バッファーに書き込もうとした場合、すべてのサンプルが書き込まれるまで待ちます。ただし、書き込みを待っている間、ユーザーに読み取りを許可して、バッファー内のスペースを空けることができるようにしたいと考えています。プロデューサーが待機しても問題ないため、その部分をロックフリーにする必要はありません。予想されるレイテンシーにほぼ対応するリング バッファーのサイズを設定することで、再生の停止を回避するのに十分なデータをプロデューサーが提供するようにすることができますが、それ以上のデータは提供されません。

ポイント 1 と 2 は、ブロックするタイミングとブロックしないタイミングに関する私の設計上の決定が合理的であるとすれば、実際に実装するのは簡単です。ちょっと困ったのが3点目です。バッファがいっぱいになるまでロックし、さらに書き込めるようになったときにのみ起動する効率的な方法はありますか? バッファのサイズは簡単に検出できます。ありがたいことに、これはアトミック操作です。しかし、適切にロックおよびロック解除する方法は私を困惑させます。特に、たとえばシャットダウンするときが来たら、ロックを途中で中断できるようにしたいからです。これには何を使用しますか?条件変数?もしそうなら、誰かが疑似コードを提供してくれたら本当にうれしいです。バリアの使用方法は理解していますが、条件変数についてはまだ詳しく調べていないため、理解しているかどうかはわかりません。特に、条件を満たさなくても覚醒できるらしいから不思議。どんな提案でも大歓迎です。

4

1 に答える 1