Как получить ключевую подпись из файла MIDI (формат 0) - PullRequest
0 голосов
/ 08 июня 2018

Я адаптировал код, созданный Gene De Lisa , для извлечения информации о файле MIDI.Обратите внимание, я использую Objective C для этого, а не Swift.Я могу получить информацию о временной подписи, названии дорожки, ударов в минуту и ​​т. Д., Но по какой-то причине я не могу извлечь ключевую подпись из файла MIDI.

Вот мой код:

Сначала я открываю файл MIDI:

-(void) loadSequence {
    NSString *songTitle = [[NSUserDefaults standardUserDefaults] objectForKey:@"songTitle"];
    NewMusicSequence(&_sequence);

    //NSURL *midiFile = [[NSBundle mainBundle] URLForResource:songTitle withExtension:@"mid" subdirectory:@"Levels"];
    NSURL *midiFile = [[NSBundle mainBundle] URLForResource:songTitle withExtension:@"mid"];

    MusicSequenceFileLoad(_sequence, (__bridge CFURLRef)midiFile, 0, 0);
}

Насколько я понимаю, вы анализируете дорожку темпа файла MIDI в поисках kMusicEventType_Metaтипы событий, которые имеют значение 5. Подпись времени является одним из таких типов событий, как и подпись ключа.Вот код для этого:

-(void) parseTimeSignature {
    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;

    MusicEventIteratorHasCurrentEvent(iterator, &hasNext);

    MIDIMetaEvent *midiMetaEvent = NULL;
    int val = 0;

    //loop through events in the tempo track
    while (hasNext) {
        MusicEventIteratorGetEventInfo(iterator, &timestamp, &eventType, &eventData, &eventDataSize);
        if (eventType == kMusicEventType_Meta) { //gets the time signature (see http:\//www.somascape.org/midi/tech/mfile.html for info)
            midiMetaEvent = (MIDIMetaEvent*)eventData;
            val = (int)midiMetaEvent->metaEventType;

            if (val == 88) { //this is the value present if the metaEventType is a time signature type
                [[NSUserDefaults standardUserDefaults] setInteger:(int)midiMetaEvent->data[0] forKey:@"timeSignatureNumerator"];
                [[NSUserDefaults standardUserDefaults] setInteger:(int)pow(2, (int)midiMetaEvent->data[1]) forKey:@"timeSignatureDenominator"]; //2 represents quarter notes, 3 reps 8th notes, etc
                //break;
            }
            else if (val == 89) {
                NSLog(@"found key signature!");
            }
            else if (val == 3) { //this value represents the track's instrument name
                NSLog(@"%hhu",midiMetaEvent->data[0]);
            }
        }

        MusicEventIteratorNextEvent(iterator);
        MusicEventIteratorHasCurrentEvent(iterator, &hasNext);
    }
}

Когда я открываю MIDI-файл в Logic Pro X, я ясно вижу подпись ключа.Я попытался добавить несколько изменений сигнатур ключей в один файл MIDI, но он никогда не показывает, что такое событие имеет место.

Чего мне не хватает?

...