Oddly enough, the tempo trajectory does not seem to have this problem. The following code does not block me:
MusicTrack tempoTrack; OSSTATUS = MusicSequenceGetTempoTrack(self.sequence, &tempoTrack); SafeMusicTrackClear(tempoTrack); //calls into MusicTrackClear MusicTrackNewExtendedTempoEvent(tempoTrack, 0, self.tempo * self.tempoMultiplier); MIDIMetaEvent timeSignatureMetaEvent; timeSignatureMetaEvent.metaEventType = 0x58; timeSignatureMetaEvent.dataLength = 4; timeSignatureMetaEvent.data[0] = 1; timeSignatureMetaEvent.data[1] = 4; timeSignatureMetaEvent.data[2] = 0x18; timeSignatureMetaEvent.data[3] = 0x08; MusicTrackNewMetaEvent(tempoTrack, 0, &timeSignatureMetaEvent); MusicTrackLoopInfo loopInfo; loopInfo.loopDuration = 0.25f; loopInfo.numberOfLoops = 0; MusicTrackSetProperty(tempoTrack, kSequenceTrackProperty_LoopInfo, &loopInfo, sizeof(loopInfo));
Unfortunately, it does not seem that the tempo track can actually play notes.
UPDATE:
After several hours of work and finding the best solution to the problem, I settled on a manual loop, sending a custom event at the end of my sequence.
My sequence is created in a method ...
-(void) loadPacketsForLoopingSequence { SafeMusicTrackClear(loopingTrack);
... which is again called in the callback:
void sequenceCallback(void* inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData* inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat) { CSMidiMusicPlayer* musicPlayer = (CSMidiMusicPlayer*)inClientData; [musicPlayer loadPacketsForLoopingSequence]; }
The callback must be registered during the init sequence using MusicSequenceSetUserCallback .
It is possible that -0.5 kludge can be completely eliminated by examining the parameters in sequenceCallback and modifying loadPacketsForLoopingSequence to accept the parameter, but I have not received this yet.
I like this solution because it stays in MIDI time and does not change the MIDI file unexpectedly, with state preservation. (New notes are mostly transmitted when you approach the loop marker.)