我想知道如何使用CoreMidi框架找到midi文件的速度。据我了解,MusicSequence
类用于打开midi文件。它包含许多曲目,包括类型为MusicTrack
的速度曲目。在检查MusicTrack类时,似乎没有任何参数或方法来实际获得速度。我从这个site获得了以下代码......这是代码:
-(void) openMidiFile {
MusicSequence sequence;
NewMusicSequence(&sequence);
NSURL *midiFileURL = [[NSBundle mainBundle] URLForResource:@"bach-invention-01" withExtension:@"mid"];
MusicSequenceFileLoad(sequence, (__bridge CFURLRef)midiFileURL, 0,
kMusicSequenceLoadSMF_ChannelsToTracks); //needs to change later
MusicTrack tempoTrack;
MusicSequenceGetTempoTrack(sequence, &tempoTrack);
MusicEventIterator iterator;
NewMusicEventIterator(tempoTrack, &iterator);
Boolean hasNext = YES;
MusicTimeStamp timestamp = 0;
MusicEventType eventType = 0;
const void *eventData = NULL;
UInt32 eventDataSize = 0;
// Run the loop
MusicEventIteratorHasCurrentEvent(iterator, &hasNext);
while (hasNext) {
MusicEventIteratorGetEventInfo(iterator,
×tamp,
&eventType,
&eventData,
&eventDataSize);
// Process each event here
printf("Event found! type: %d\n", eventType); //tempo occurs when eventType is 3
printf("Event data: %d\n", (int)eventData); //data for tempo?
MusicEventIteratorNextEvent(iterator);
MusicEventIteratorHasCurrentEvent(iterator, &hasNext);
}
}
答案 0 :(得分:1)
每个eventType
都有相应的数据结构,如MusicPlayer.h
中所述。
您可能正在寻找kMusicEventType_ExtendedTempo
类型的事件,其类型为ExtendedTempoEvent
的数据,只是:
/*!
@struct ExtendedTempoEvent
@discussion specifies the value for a tempo in beats per minute
*/
typedef struct ExtendedTempoEvent
{
Float64 bpm;
} ExtendedTempoEvent;
所以你的代码可能是:
MusicEventIteratorGetEventInfo(iterator,
×tamp,
&eventType,
&eventData,
&eventDataSize);
if (eventType == kMusicEventType_ExtendedTempo &&
eventDataSize == sizeof(ExtendedTempoEvent)) {
ExtendedTempoEvent *tempoEvent = (ExtendedTempoEvent *)eventData;
Float64 tempo = tempoEvent->bpm;
NSLog(@"Tempo is %g", tempo);
}
请记住:MIDI文件中可能包含多个速度。您可以使用事件时间戳来查明它何时改变速度。