Microsoft DirectX 9.0

Clock Time and Music Time

In DirectX for C++, the time returned by the master clock is a 64-bit value defined as type REFERENCE_TIME. Reference time is measured in units of approximately 100 nanoseconds, so the clock ticks about 10 million times each second. The value returned by the IReferenceClock::GetTime method is relative to an arbitrary start time.

Music time is a 32-bit value defined as type MUSIC_TIME. It is not an absolute measure of time but is relative to the tempo. The clock is started when the performance is initialized and ticks DMUS_PPQ times for each quarter-note. DMUS_PPQ is defined as 768.

When a performance is initialized, it starts keeping an internal clock. You can retrieve the current performance time in both reference time and music time by using the IDirectMusicPerformance8::GetTime method.

The IDirectMusicPerformance8::AdjustTime method can be used to make small changes to the performance time. Most applications don't need to do this, but it can be useful when synchronizing to another source.

To convert between the two kinds of time in a performance, you can use the IDirectMusicPerformance8::MusicToReferenceTime and IDirectMusicPerformance8::ReferenceToMusicTime methods. These methods convert between time offsets within the performance, taking into account all tempo changes that have taken place since the performance started.

When a segment is cued to play by a call to IDirectMusicPerformance8::PlaySegment or IDirectMusicPerformance8::PlaySegmentEx and the start time is given in reference time, DirectMusic must convert the start time to music time. If no primary segment is currently playing, the conversion is made immediately, based on the current tempo. Otherwise, if another segment is playing, the start time of the cued segment is not converted to music time until the start time has been reached.

If the tempo is changed before the segment starts playing, the actual start time can be affected, or the segment might not start on the desired boundary. In the first case, in which the conversion to music time is done immediately, the start time (in reference time) is advanced if the tempo speeds up and delayed if the tempo slows down. In the second case, in which conversion is made at start time, a change in tempo can mean that the segment does not start at correct resolution boundaries. For example, if the segment is supposed to start on a measure boundary (as indicated in the dwFlags parameter of PlaySegment or PlaySegmentEx), the actual start time (in reference time) is calculated when the segment is cued. However, if the tempo then changes, a measure boundary might not fall at that time.

When a primary segment is played with the DMUS_SEGF_QUEUE flag (see DMUS_SEGF_FLAGS), the i64StartTime parameter is ignored, and the segment is cued to play after any primary segments whose start times have already been converted. If a previously cued segment is still stamped in reference time, that segment will play at its designated time, perhaps interrupting another segment.

For example, suppose you have three segments, each 10 seconds in length. You cue segment A to play 5 seconds from now. Because no primary segment is currently playing, the start time is immediately converted to music time. At 6 seconds, you cue segment B to play at 20 seconds. In this case, because music is already playing and the tempo might change, the conversion to music time is not made immediately. Then you cue segment C with the DMUS_SEGF_QUEUE flag so that it starts immediately after segment A finishes, at 15 seconds. At 20 seconds, segment B starts playing and interrupts segment C.

See Also