Segment Timing
When you cue a segment to play, you have a great deal of control over when the segment starts, what point in the segment is heard first, how the segment is aligned rhythmically with currently playing music, and whether any part of the segment plays more than once.
The following terms are used throughout this section to clarify the relationship between times within segments and times within the performance.
Start point
The first point in the segment that can be a segment start time. By default this value is 0, indicating the beginning of the segment. However, it can be changed by the application.
Segment start time
The point in a segment where it begins producing sounds. This time is usually the same as the start point, but can be later than the start point if the start point is deliberately aligned to a play time that is in the past.
Play time
The point in the performance where a segment's start point is cued. In the DirectMusic API, this time is sometimes called start time.
Resolved time
A specified time (such as the play time) adjusted to a specified boundary. For example, the resolved time could be the time of the next beat after the specified time.
Start marker
A marker indicating a valid segment start time in a segment. The marker can be an enter switch point in the marker track, or a variation switch point in a pattern .
Play marker
A marker in the marker track of a control segment indicating where another segment's start point can be cued.
Note Start markers and play markers are placed in a segment in DirectMusic Producer and cannot be changed by the application. They can, however, be retrieved by using the GUID_Valid_Start_Time and GUID_Play_Marker parameters.
Segments normally play from the beginning. You can make a segment start from another point by using the IDirectMusicSegment8::SetStartPoint method. The new start point remains valid until changed.
The play time is determined by two parameters of the IDirectMusicPerformance8::PlaySegment or IDirectMusicPerformance8::PlaySegmentEx methods:
- The i64StartTime parameter sets the earliest time at which the segment can start playing. If i64StartTime is 0, this time is as soon as possible. The actual time at which the segment can start depends on the type of segment. If it is a primary segment or a secondary control segment, the earliest play time is at queue (or flush) time. If it is a noncontrol secondary segment, the earliest play time is at latency time. For more information on queue time and latency time, see Latency and Bumper Time.
- The dwFlags parameter specifies how soon after the earliest possible play time the segment will actually start playing. Usually, you will want to wait for an appropriate point in the rhythm before introducing a new primary segment, transition, or motif. You control the delay by setting one or more flags from the DMUS_SEGF_FLAGS enumeration.
Repeating and Looping
If a repeat count is set by using IDirectMusicSegment8::SetRepeats, the entire segment repeats that number of times, unless a loop has been defined by a call to IDirectMusicSegment8::SetLoopPoints, in which case only the part of the segment between the loop points repeats.
Aligning a Segment to a Past Time
Rather than forcing the segment start time to the next grid, beat, or measure in the control segment, you might want the segment to start playing sooner, yet still match the rhythm of the current segment. You can make the segment do so by cuing its start point to a rhythmic boundary that has already passed. The rhythm in the cued segment is thus aligned with that in the current segment, and the new segment can start playing immediately.
To cue the segment in the past, use the DMUS_SEGF_ALIGN flag. Add one of DMUS_SEGF_GRID, DMUS_SEGF_BEAT, DMUS_SEGF_SEGMENTEND, or DMUS_SEGF_MEASURE to cue the start point of the segment at the appropriate rhythmic boundary. Alternatively, you can use DMUS_SEGF_MARKER to align the start point to the most recently played play marker in the control segment.
Note Combining DMUS_SEGF_ALIGN with DMUS_SEGF_SEGMENTEND causes the beginning of the cued segment to be aligned with the beginning of the current segment.
Of course, when the start point is in the past, the segment start time has to be adjusted to fall in the present or the future. The performance uses the following rules to determine the segment start time. In all cases, "next" means "next possible"—that is, within the part of the segment that does not fall in the past.
If a start marker appears in the cued segment before the next resolution boundary of the specified type, the segment start time falls at that point.
If there is no valid start marker, the segment start time is at the next start resolution boundary of the cued segment, as specified by one of the following flags:
Flag Effect DMUS_SEGF_VALID_START_BEAT Puts the segment start time on the next beat. DMUS_SEGF_VALID_START_GRID Puts the segment start time on the next grid. DMUS_SEGF_VALID_START_MEASURE Puts the segment start time on the next bar line. DMUS_SEGF_VALID_START_TICK Puts the segment start time at the earliest possible point. If there is no valid start marker and no start resolution flag is supplied, the segment start time is at the next play resolution boundary as specified by the DMUS_SEGF_GRID, DMUS_SEGF_BEAT, or DMUS_SEGF_MEASURE flag. If none of these flags is present, the segment start time is immediate.
Play markers and start markers allow greater flexibility in the cuing of segments, especially motifs. Suppose a motif is designed to sound best when it starts playing at the beginning of a measure in the primary segment. If the motif is cued with the DMUS_SEGF_MEASURE flag, there might be a significant delay before the next measure boundary is reached and the motif plays. But if the DMUS_SEGF_ALIGN flag is added, the motif can start playing sooner without violating the rhythm. Adding the DMUS_SEGF_MARKER flag ensures that the motif plays at an appropriate boundary within the control segment, rather than on just any measure, beat, or grid.
For information on how tempo changes can affect segment start times, see Clock Time and Music Time.
The following diagram shows how the timing is determined for a segment cued with the DMUS_SEGF_MEASURE, DMUS_SEGF_ALIGN, and DMUS_SEGF_VALID_START_BEAT flags. The solid vertical lines are measure boundaries, and the dotted lines are beat boundaries. The start point of the segment is aligned with the previous measure boundary in the current primary segment. The segment start time falls at the first beat in the cued segment after the unresolved play time.
Logical Time and Actual Time
Some events have both a logical time and an actual time. The actual time is when the event will take place, and the logical time represents the musical position where it belongs.
For example, a segment might contain a program change that belongs to the start of a beat. The logical time is the start of the beat. However, you want to make sure the program change takes place before the note on the beat is played, so you assign it a physical time that's a little earlier.
If the segment loops to the logical time (the start of that same beat), the program change will still go out.