How to get the names of instruments and tracks in a MIDI file in iOS?

Question:

Using the code in this repository I was able to play a MIDI file with a default SoundFont source, the problem is that the code requires that the instruments to be used with each track be passed as parameters.

The information about which instrument each track uses is embedded in the MIDI file.

What I have tried so far is to iterate through the events of the file looking for meta-data but when the AudioToolbox Framework appears it omits that information when it is processing the file.

- (void)assignInstrumentsToTracks:(NSArray*)programs {
    //-------------------------------------------------
    // Set the AUSampler nodes to be used by each track
    //-------------------------------------------------
    MusicTrack tracks[[programs count]];

    for (NSInteger i = 0; i < [programs count]; i++) {
        MusicTrack track;
        MusicSequenceGetIndTrack(ms, (unsigned int)i, &track);
        tracks[i] = track;

        MusicEventIterator iterator;
        NewMusicEventIterator(track, &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("Eent type %i\n", (unsigned int)eventType);
            if (eventType == kMusicEventType_Meta) {
                printf("Meta-event found! ");
                for (int j=0; j<eventDataSize; j++) {
                    printf("%x", ((char *)eventData)[i]);
                }
                printf("\n");
            }

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

    AUNode nodes[[programs count]];
    for (NSInteger i = 0; i < [programs count]; i++) {
        AUNode node;
        AUGraphGetIndNode (self.processingGraph, (unsigned int)i, &node);
        nodes[i] = node;
    }

    for (NSInteger i = 0; i < [programs count]; i++) {
        MusicTrackSetDestNode(tracks[i], nodes[i]);
    }
}

Does anyone know what other way I can do this?

Answer:

The strategy of iterating the events of each track is correct, but the instrument assignments (Program Change events) are not meta-events, but channel events. That is: you would have to search for eventType=kMusicEventType_MIDIChannelMessage , and status with values ​​between 0xC0 and 0xCF . You can see an example in the MacMIDIObject::analyzeTrack() of this application in C ++: https://sourceforge.net/p/kmid2/code/HEAD/tree/trunk/mac/macmidiobject.cpp#l727

On the other hand, track names and instrument names are text meta-events. metaEventType property with TrackName=3 , and InstrumentName=4 . But this text information is purely informative and does not influence the sound.

Scroll to Top