RSSフィード用のモールス信号を再生するC#プロジェクトがあります。Managed DirectXを使用して記述しましたが、Managed DirectXが古く、廃止されていることがわかりました。私が持っているタスクは、持続時間に関して正確にタイミングが調整された無音期間(コード)が点在する純粋な正弦波バーストを再生することです。純音を何ミリ秒も再生する関数を呼び出してから、Thread.Sleep()を呼び出してから、別の関数を再生する必要があります。最速では、音とスペースを40ミリ秒まで短くすることができます。
これは、ManagedDirectXで非常にうまく機能しています。正確なタイミングのトーンを得るために、私は1秒を作成します。正弦波を2次バッファーに入れてから、特定の持続時間のトーンを再生するために、バッファーの終わりからxミリ秒以内に前方にシークしてから再生します。
System.Media.SoundPlayerを試しました。任意のトーンの長さに対してPlay()、Sleep()、Stop()の順に実行する必要があるため、これは敗者です[編集-以下の私の答えを参照] 。その結果、トーンが長すぎて、CPU負荷によって変化します。実際に音を止めるには不確定な時間がかかります。
次に、NAudio1.3を使用するための長い試みに着手しました。最終的には、メモリ常駐ストリームがトーンデータを提供し、ストリームに必要な長さのトーンを残して前方に移動し、再生することになりました。これはしばらくの間DirectSoundOutクラスで問題なく機能しましたが(以下を参照)、WaveOutクラスは、PlayerStopped = trueにもかかわらず、バッファーがまだキューにあることを示す内部アサートですぐに終了します。トーンの終わりから次のトーンの始まりまで同じ時間待機するので、これは奇妙です。40ミリ秒のトーンの再生を開始してから80ミリ秒後に、キューにバッファがないと思うでしょう。
DirectSoundOutはしばらくの間はうまく機能しますが、問題は、トーンバーストPlay()ごとに個別のスレッドをスピンオフすることです。最終的に(5分程度)動作を停止します。VS2008 IDEでプロジェクトを実行している間、出力ウィンドウでスレッドが終了した後のスレッドを確認できます。再生中に新しいオブジェクトを作成することはありません。トーンストリームをSeek()してから、Play()を何度も呼び出すだけなので、孤立したバッファや、チョークされるまで積み重なるものに問題はないと思います。
私はこれに我慢できていないので、ここの誰かが同様の要件に直面し、可能性のある解決策のある方向に私を導くことができることを願っています。