使用CoreMidi的MIDI文件的速度

时间:2015-12-28 05:47:13

标签: objective-c macos coremidi

我想知道如何使用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,
                                   &timestamp,
                                   &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);
    }
}

1 个答案:

答案 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,
                               &timestamp,
                               &eventType,
                               &eventData,
                               &eventDataSize);

if (eventType == kMusicEventType_ExtendedTempo && 
    eventDataSize == sizeof(ExtendedTempoEvent)) {
    ExtendedTempoEvent *tempoEvent = (ExtendedTempoEvent *)eventData;
    Float64 tempo = tempoEvent->bpm;
    NSLog(@"Tempo is %g", tempo);
}

请记住:MIDI文件中可能包含多个速度。您可以使用事件时间戳来查明它何时改变速度。