我正在设计一个由MIDI音轨驱动的节奏游戏。 MIDI消息触发屏幕元素的释放。我正在从文件加载MIDI数据,然后使用MusicSequence和MusicPlayer播放它。
据我所知,MIDI文件包含时间和密钥签名信息,作为文件开头的元消息。但是我没有找到从MusicPlayer或MusicSequence中检索此信息的方法。
我需要的信息是玩quaver,crotchet等所需的秒数......我希望这会受到时间签名和MusicPlayerPlayRateScalar值的影响。
看起来这些信息可以在CoreAudio clock中找到,但我无法解决如何访问特定音乐序列的问题。
有没有知道如何做到这一点的CoreAudio专家?
答案 0 :(得分:4)
您需要获取midi文件的速度轨道,然后迭代它以获得速度。
要获得序列长度,您需要找到最长的音轨:
(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, ×tamp, &eventType, &eventData, &eventDataSize);