CoreMIDI отслеживает доступ к информации о времени подписи - PullRequest
1 голос
/ 30 марта 2012

Я разрабатываю ритмическую игру, основанную на MIDI-треке. MIDI-сообщения запускают высвобождение экранных элементов. Я загружаю данные MIDI из файла, а затем воспроизводю их с помощью MusicSequence и MusicPlayer.

Я понимаю, что MIDI-файлы содержат информацию о времени и ключевой подписи в виде мета-сообщений в начале файла. Однако я не нашел способа получить эту информацию ни из MusicPlayer, ни из MusicSequence.

Мне нужна информация о количестве секунд, которое требуется для воспроизведения квавера, крючка и т. Д. Я ожидаю, что на это повлияют сигнатура времени и значение MusicPlayerPlayRateScalar.

Похоже, эту информацию можно найти в часах CoreAudio , но я не смог понять, как к ней обращаться для определенной музыкальной последовательности.

Есть ли специалисты CoreAudio, которые знают, как это сделать?

1 Ответ

4 голосов
/ 30 марта 2012

Вам нужно получить дорожку темпа миди-файла, а затем выполнить итерацию по нему, чтобы получить темп (ы).

Чтобы получить длину последовательности, вам нужно найти самую длинную дорожку:

 (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;
}

// - получить дорожку темпа:

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);
...