waveOut...
からのAPIを使用してオーディオを継続的に再生するアプリに取り組んでいますwinmm.dll
。このアプリは「リープフロッグ」バッファーを使用します。これは基本的に、オーディオキューにダンプするサンプルの配列の集まりです。Windowsはそれらを順番にシームレスに再生し、各バッファーが完了すると、Windowsはコールバック関数を呼び出します。この関数内で、次のサンプルセットをバッファーにロードし、それらを処理してから、バッファーをオーディオキューにダンプします。このようにして、オーディオは無期限に再生されます。
アニメーションの目的で、アプリケーションに組み込んwaveOutGetPosition
でいます(「バッファ完了」コールバックは不規則であるため、アニメーションがぎくしゃくします)。 waveOutGetPosition
再生の現在の位置を返すため、超高精度です。
問題は、私のアプリケーションで、を呼び出すと、waveOutGetPosition
最終的にアプリケーションがロックされることです。サウンドが停止し、呼び出しが戻らないということです。問題を示す簡単なアプリにまとめました。ここでアプリを実行できます:
http://www.musigenesis.com/SO/waveOut%20demo.exe
ほんの少しのピアノを何度も聞くだけなら、それは機能しています。問題を実証するためだけのものです。このプロジェクトのソースコードはここにあります(すべての肉はLeapFrogPlayer.csにあります):
http://www.musigenesis.com/SO/WaveOutDemo.zip
最初のボタンは、を呼び出さずにアプリをリープフロッグモードで実行しますwaveOutGetPosition
。これをクリックすると、アプリは中断することなく永久に再生されます(Xボタンで閉じてシャットオフします)。waveOutGetPosition
2番目のボタンは、リープフロガーを開始し、を呼び出して現在の位置を表示するフォームタイマーも開始します。これをクリックすると、アプリがしばらく実行されてからロックされます。私のラップトップでは、通常15〜30秒でロックされます。せいぜい1分かかります。
私はこれを修正する方法がわからないので、どんな助けや提案も大歓迎です。この問題に関する投稿はほとんど見つかりませんでしたが、複数の呼び出しから、waveOutGetPosition
またはそれへの呼び出しからwaveOutWrite
、同時に発生する潜在的なデッドロックがあるようです。これを頻繁に呼び出しているため、システムで処理できない可能性があります。
編集:言及するのを忘れました、私はこれをWindowsVistaで実行しています。これは、他のOSではまったく発生しない可能性があります。
編集2:これらの(未回答の)投稿を除いて、私はこの問題についてオンラインでほとんど見つけていません:
編集3:さて、私は今、この問題を自由に再現することができます。waveOutGetPosition
(次のコード行で)直後に呼び出すとwaveOutWrite
、アプリケーションは毎回ハングします。また、特にひどい方法でハングします。アプリ自体だけでなく、OS全体がしばらくの間ロックされているようです。したがって、文字通り同時にではなく、ほぼ同時にwaveOutGetPosition
デッドロックが発生した場合は、デッドロックが発生しているように見えます。これは、ロックが機能していない理由を説明している可能性があります。うん。waveOutWrite