Question

I'm designing a rhythm game which is driven by a MIDI track. The MIDI messages trigger the release of on-screen elements. I am loading the MIDI data from a file and then playing it using a MusicSequence and MusicPlayer.

I understand that MIDI files contain time and key signature information as meta messages at the start of the file. However I've not found a way to retrieve this information from either the MusicPlayer or the MusicSequence.

The information I need is the number of seconds it take to play a quaver, crotchet etc... I would expect this to be affected by the time signature and the MusicPlayerPlayRateScalar value.

It look like this information can be found in the CoreAudio clock but I've not been able to work how this is accessed for a particular music sequence.

Are there any CoreAudio experts out there who know how to do this?

Was it helpful?

Solution

You need to get the tempo track of the midi file and then iterate through it to get the tempo(s).

To get the sequence length you need to find the longest track:

 (MusicTimeStamp)getSequenceLength:(MusicSequence)aSequence {
    UInt32 tracks;
    MusicTimeStamp len = 0.0f;

    if (MusicSequenceGetTrackCount(sequence, &tracks) != noErr)
    return len;

    for (UInt32 i = 0; i < tracks; i++) {
        MusicTrack track = NULL;
        MusicTimeStamp trackLen = 0;

        UInt32 trackLenLen = sizeof(trackLen);

         MusicSequenceGetIndTrack(sequence, i, &track);
         MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength, &trackLen, &trackLenLen);

       if (len < trackLen)
           len = trackLen;
    }

  return len;
}

// - get the tempo track:

OSStatus result = noErr;

MusicTrack tempoTrack;
result = MusicSequenceGetTempoTrack(sequence, &tempoTrack);
if (noErr != result) {[self printErrorMessage: @"MusicSequenceGetTempoTrack" withStatus: result];}

MusicEventIterator iterator = NULL;
NewMusicEventIterator(tempoTrack, &iterator);

MusicTimeStamp timestamp = 0;
MusicEventType eventType = 0;
const void *eventData = NULL;
UInt32 eventDataSize = 0;

MusicEventIteratorGetEventInfo(iterator, &timestamp, &eventType, &eventData, &eventDataSize);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top