2012-03-29 100 views
1

我正在設計一個由MIDI軌道驅動的節奏遊戲。 MIDI消息觸發屏幕元素的釋放。我從文件加載MIDI數據,然後使用MusicSequence和MusicPlayer播放它。CoreMIDI軌道訪問簽名信息

我知道MIDI文件在文件開始時包含時間和密鑰簽名信息作爲元信息。但是我還沒有找到從MusicPlayer或MusicSequence中檢索這些信息的方法。

我需要的信息是用來播放動畫,短片等的秒數......我期望這會受到拍號和MusicPlayerPlayRateScalar值的影響。

看起來像這個信息可以在CoreAudio clock找到,但我還沒有能夠工作如何訪問特定的音樂序列。

是否有任何CoreAudio專家知道如何做到這一點?

回答

4

您需要獲取midi文件的速度軌跡,然後遍歷它以獲取速度(s)。

爲了得到你需要找到最長軌道序列長度:

(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); 
+0

非常有幫助,謝謝! – 2012-04-11 15:36:39