【问题标题】:Tempo of MIDI File Using CoreMidi使用 CoreMidi 的 MIDI 文件的速度
【发布时间】:2015-12-28 15:15:49
【问题描述】:

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

【问题讨论】:

    标签: objective-c macos coremidi


    【解决方案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 文件中可能有多个速度。您可以使用事件时间戳来了解它何时改变节奏。

    【讨论】:

    • 谢谢库尔特!我刚刚在您发布解决方案之前发现了该结构:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多