代码之家  ›  专栏  ›  技术社区  ›  02fentym

使用CoreMidi的MIDI文件的速度

  •  1
  • 02fentym  · 技术社区  · 8 年前

    我想知道如何使用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 回复  |  直到 8 年前
        1
  •  1
  •   Kurt Revis    8 年前

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