Microsoft DirectX 9.0

Ensuring Timely Band Changes

A consideration in playing band segments is the randomness in the timing of notes played by a style track. For instance, a note that is on measure 1, beat 1 might actually play somewhat earlier than the beat boundary. If you make a band change at the beat boundary, the note might play with the incorrect instrument.

To prevent this problem, an application should cue the band segment early. Suppose, for example, that you have a style-based segment pStyleSeg and a band segment pBandSeg. You want to play both the style segment and the band segment on the next measure boundary of the performance pPerf. You know that the style contains notes that could go out up to 30 ticks earlier, in music time, than the start time of the segment. The following example code ensures that the band segment is played 31 ticks before the style segment, so that all instruments are in place before any note is played:

HRESULT CueSegmentAfterBand(IDirectMusicPerformance8* pPerf,
                            IDirectMusicSegment8* pBandSeg,
                            IDirectMusicSegment8* pStyleSeg)
{
  REFERENCE_TIME rtResolved;
  MUSIC_TIME mtResolved;
  HRESULT hr;
 
  hr = pPerf->GetResolvedTime(0, &rtResolved, DMUS_TIME_RESOLVE_MEASURE);
  if (SUCCEEDED(hr))
  {
    hr = pPerf->ReferenceToMusicTime(rtResolved, &mtResolved);
   if (SUCCEEDED(hr))
   {
      mtResolved -= 31; 
      hr = pPerf->PlaySegment(pBandSeg, 0, mtResolved, NULL);
      if (SUCCEEDED(hr))
      {
        pPerf->PlaySegment(pStyleSeg, DMUS_TIME_RESOLVE_MEASURE, 0, NULL);
      }
    }
  }
  return hr;
}

Note   If there is no randomness in the notes played by a segment (for example, one loaded from a MIDI file), you don't need to worry about the timeliness of a band segment played at the same time. By default, all band segments start 1 tick early.