The functions for handling the audio clock are discussed in the audio chapter Playing Instruments. The one piece of new information you need is where to get the score's MIDI clock rate. It is stored in the MIDIFileParser
data structure used to import the MIDI score, in the mfp_Rate
element after executing MFLoadCollection()
.
The code fragment in Example 4 shows how a task resets the audio clock rate. MFParser
is a pointer to the MIDIFileParser
data structure used to import the MIDI score.
Example 1: Resetting the audio clock rate.
Note that the audio clock is often used by other tasks such as audio and video streaming tasks, so changing the audio clock rate can sometimes wreak great havoc on those other tasks. Be sure that your task gets ownership of the clock before it changes the rate. That way, if it screws up other tasks, your task did the right thing by inquiring about ownership first.
Owner = OwnAudioClock();
OriginalRate = GetAudioRate();
SetAudioRate(Owner, MFParser.mfp_Rate);
A timestamp is the number of MIDI ticks that have passed between the beginning of the score and the beginning of the MIDI event associated with the timestamp. If you look at the tempo stored with the score and compare it with the current clock rate (usually set to 240 ticks per minute), you can create a scalar that you can use to simply multiply each timestamp value. The result is a score that plays at the appropriate tempo.
For example, consider a MIDI score set to play at 120 ticks per minute. To play it back with an audio clock rate of 240 ticks per minute, you create a scalar of 2 (double the MIDI tick rate). You then multiply each timestamp by the scalar, which doubles the value of each stamp. When you play the score using the audio clock, it comes out at the original tempo because the doubled time values are played back with a clock that plays twice as fast.
The example program playmf.c shown at the end of this chapter contains a function designed to scale MIDI timestamps.