DirectSoundの再生時間とWindows時間の誤差
DirectSoundで音楽を長時間(30秒以上)再生すると、Windowsの時間経過との誤差がどれぐらい増えていくかを検証したいと思います。
音楽再生開始時点で少なからず多少の誤差がありますが、その辺の誤差は許容範囲とします。
『時間が進むにつれてその誤差が徐々に広がっていくのかどうか?』というのが今回の議題です。間違わないでね。
Windowsの時間取得は、TimeGetTimeで行うものとします。
OSの経過時間をmsで返します。なので、スタート時の時間を記憶しておけば、差分で経過時間が分かるはずです。
■Play Start StartTime = timeGetTime(); ■Get PlayTime result = timeGetTime()-StartTime;
(このコードだと起動後数日すると数値がループするので、そのタイミングでおかしくなりますが今回は必要ないので)
さて、適当な3分ぐらいの動機が分かりやすい動画を、映像と音楽に分離して、時間経過によってどれぐらい誤差が発生するか適当にサンプルを取ってみます。
■マシン1 サウンド:UA-1G(96kHz/24bit) 2分:2秒ぐらい 3分:3秒ぐらい 20秒に一回Windows経過時間でシーク再生をする:ノイズ、巻戻り現象発生 ■マシン2 サウンド:SoundBlaster Audigy2 1分:誤差なし 2分:誤差なし 20秒に一回Windows経過時間でシーク再生をする:ノイズ無し、正常 ■マシン3 サウンド:SigmaTel High definiton Audio 1分:誤差なし 2分:誤差なし 20秒に一回Windows経過時間でシーク再生をする:ノイズ無し、正常
耳で聞いて数値を拾うのでいい加減ではありますが、流石に1秒以上遅れると映像と同期しないので丸わかりです。
一応、20秒に1回ずつWindowsの経過時間でシークして再生し直すテストもやっておきました。
結果、重要なのは、マシン環境(サウンド)によって遅れる場合と遅れない場合があると言うことでしょうか。
つまり『ハードウェア依存性がある』ということで、Windowsの経過時間とDirectSoundの再生経過時間は必ずしも一致しないみたいです。
もし、単発で音を鳴らして同期を取る場合は、短時間に収めないと酷いことになるので注意が必要でしょう。
(ちょっと前までは音楽と映像を分けて動画を再生しているところがありましたが、その場合は同期補正処理をしていない場合はズレちゃういますね)
どうしてもWindows時間に音楽を合わせたいというのであれば、対策として1〜2秒に一回、シークして再生をし直すのも悪くないかも知れません。
(3秒以上だとノイズとして聞き取れました。人間の耳って凄いよね。目は結構いい加減なのに)
こういう誤差が出るのはなんとなく予想はしていましたが、ハードウェアによってかなり差が出るというのは新しい収穫でしょうか。
最終的なハードウェアが出力するHz数によっても誤差が左右したりするのでしょうね、きっと。
とりあえず、DirectSoundを用いた同期は、音楽側の時間軸で処理を進めるか(動画再生のセオリーはこっち)、なにかしらの同期補正が必要のようです。