Reputation: 1792
I was wondering how to find the tempo of a midi file using the CoreMidi framework. As I understand it, the MusicSequence
class is used for opening a midi file. It contains a number of tracks including a tempo track which is of type MusicTrack
. Upon inspecting the MusicTrack class, there doesn't seem to be any parameter or method for actually getting the tempo. I got the following code from this site...here's the code:
-(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);
}
}
Upvotes: 1
Views: 382
Reputation: 27994
Each eventType
has a corresponding structure for its data, described in MusicPlayer.h
.
You are probably looking for events of type kMusicEventType_ExtendedTempo
, which will have data of type ExtendedTempoEvent
, which is just:
/*!
@struct ExtendedTempoEvent
@discussion specifies the value for a tempo in beats per minute
*/
typedef struct ExtendedTempoEvent
{
Float64 bpm;
} ExtendedTempoEvent;
So your code might be:
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);
}
Keep in mind: a MIDI file may have more than one tempo in it. You can use the event timestamps to find out when it changes tempo.
Upvotes: 1