Platform SDK: DirectX |
DirectX for C++ では、マスタ クロックによって返されるタイムは、REFERENCE_TIME 型で定義される 64 ビット値である。基準タイムはおよそ 100 ナノ秒 (ns) 単位で測定されるので、クロックのティック (目盛り) は 1 秒間におよそ 10,000,000 個存在する。IReferenceClock::GetTime メソッドは、任意の開始タイム以降に経過した時間を返す。
ミュージック タイムは、MUSIC_TIME 型として定義される 32 ビット値である。これは時間の絶対的な測定値ではなく、テンポに基づく相対値である。クロックは、パフォーマンスが初期化されるときに開始され、4 分音符当たり DMUS_PPQ の時間が経過する (DMUS_PPQ は、現在 768 に定義されている)。
パフォーマンスが初期化されるときに、内部クロックの維持が開始される。IDirectMusicPerformance::GetTime メソッドを使って、現在のパフォーマンスタイムを基準タイムとミュージック タイムの両方で取得することができる。
IDirectMusicPerformance::AdjustTime メソッドを使うと、パフォーマンス タイムをわずかに変更することができる。ほとんどのアプリケーションでは、この操作を実行する必要はない。ただし、ほかのソースに同期させる場合には、この処理が役に立つ。
パフォーマンス内でこれら 2 種類のタイムを変換するには、IDirectMusicPerformance::MusicToReferenceTime と IDirectMusicPerformance::ReferenceToMusicTime の各メソッドを使う。
IDirectMusicPerformance::PlaySegment を呼び出して、演奏したいセグメントを挿入する際に、基準タイムを使って開始タイムを指定する。その時点でプライマリ セグメントが演奏されていない場合、このタイムは現在のテンポに従って直ちにミュージック タイムに変換される。ほかのプライマリ セグメントが演奏されている場合は、挿入されたセグメントの開始タイムに達した時点で、その開始タイムがミュージック タイムに変換される。
セグメントの演奏が開始される前にテンポが変更された場合は、開始タイムが影響を受けたり、セグメントが希望した境界で開始されない場合がある。前者の状況では、直ちにミュージック タイムへの変換が行われる。テンポの速度が上昇した場合は (基準タイムでの) 開始タイムは早まり、テンポの速度が低下した場合は遅れる。後者の状況では、開始タイムに変換が行われるので、テンポの変更が発生すると、正確な分解能の境界でセグメントが始まらないことを意味する。たとえば、セグメントがある小節境界 (PlaySegment の dwFlags パラメータで指示) で開始される場合、基準タイムでの開始タイムは、セグメントがキューに格納されるときに計算される。その後でテンポが変更されると、小節境界が計算したタイムどおりにならない可能性がある。
プライマリ セグメントが DMUS_SEGF_QUEUE フラグと共に PlaySegment に渡されるときに (DMUS_SEGF_FLAGS を参照)、i64StartTime パラメータは無視され、セグメントは、既に開始タイムが変換されているプライマリ セグメントの後で演奏されるように、キューに格納される。これは、基準タイムを指定して現在キューに置かれているセグメントが、DMUS_SEGF_QUEUE セグメントに割り込む可能性があることを意味する。
次の例で、この動作を説明する。3 つのセグメントがあり、それぞれの長さが 10 秒であるとする。セグメント A を、今から 5 秒後に演奏するようにキューに格納する。現在演奏されているプライマリ セグメントはないため、開始タイムは直ちにミュージック タイムに変換される。6 秒経過した時点で、セグメント B を 20 秒から演奏するようにキューに格納する。この場合、既に音楽が演奏中で、テンポが変更されている可能性があるため、ミュージック タイムへの変換はすぐには行われない。次に、DMUS_SEGF_QUEUE フラグを設定したセグメント C を、セグメント A が終了しだい、つまり 15 秒から演奏するようにキューに格納する。20 秒の時点で、セグメント B の演奏が開始され、セグメント C が中断される。
DirectX for Visual Basic では、マスタ クロックによって返されるタイムは Long であり、およそ 1 ミリ秒の単位で表される。DirectMusicPerformance.GetClockTime によって返される値は、任意の開始タイム以降に経過した時間である。
ミュージック タイムも Long であり、時間の絶対的な測定値ではなく、テンポに基づく相対値である。クロックは、パフォーマンスが初期化されるときに開始され、4 分音符当たり 768 の時間が経過する。現在のタイムは、DirectMusicPerformance.GetMusicTime を使って取得することができる。
パフォーマンスで 2 種類のタイムを変換するには、DirectMusicPerformance.MusicToClockTime および DirectMusicPerformance.ClockToMusicTime メソッドを使用する。
DirectMusicPerformance.PlaySegment の呼び出しによってセグメントがキューに格納され、開始タイムがクロック タイムで与えられる場合、DirectMusic は開始タイムをミュージック タイムに変換しなければならない。その時点でプライマリ セグメントが演奏されていない場合、このタイムは現在のテンポに従って直ちにミュージック タイムに変換される。ほかのプライマリ セグメントが演奏されている場合は、挿入されたセグメントの開始タイムに達した時点で、その開始タイムはミュージック タイムに変換される。
セグメントの演奏が開始される前にテンポが変更された場合は、開始タイムが影響を受ける可能性があり、セグメントが希望した境界で開始されない場合がある。前者の状況では、直ちにミュージック タイムへの変換が行われる。テンポの速度が上昇した場合は (基準タイムでの) 開始タイムは早まり、テンポの速度が低下した場合は遅れる。後者の状況では、開始タイムに変換が行われるので、テンポの変更が発生すると、正確な分解能の境界でセグメントが始まらないことを意味する。たとえば、セグメントがある小節境界 (PlaySegment の lFlags パラメータで指示) で始まる場合、セグメントが挿入された時点で実際の開始タイム (クロック タイムで表現) が計算されるが、その後テンポが変更されると、小節境界は当初予定されていた時点と一致しない可能性がある。
プライマリ セグメントが DMUS_SEGF_QUEUE フラグと共に PlaySegment に渡されるときに (CONST_DMUS_SEGF_FLAGS を参照)、startTime パラメータは無視され、セグメントは、既に開始タイムが変換されているプライマリ セグメントの後で演奏されるように、キューに格納される。これは、基準タイムを指定して現在キューに置かれているセグメントが、DMUS_SEGF_QUEUE セグメントに割り込む可能性があることを意味する。
次の例で、この動作を説明する。3 つのセグメントがあり、それぞれの長さが 10 秒であるとする。セグメント A を、今から 5 秒後に演奏するようにキューに格納する。現在演奏されているプライマリ セグメントはないため、開始タイムは直ちにミュージック タイムに変換される。6 秒経過した時点で、セグメント B を 20 秒から演奏するようにキューに格納する。この場合、既に音楽が演奏中で、テンポが変更されている可能性があるため、ミュージック タイムへの変換はすぐには行われない。次に、DMUS_SEGF_QUEUE フラグを設定したセグメント C を、セグメント A が終了しだい、つまり 15 秒から演奏するようにキューに格納する。20 秒の時点で、セグメント B の演奏が開始され、セグメント C が中断される。