pythonmidimusic21

reading MIDI file using music21 with partitionByInstrument() to get notes and chords returning empty list


I'm trying to use the code from this github repository's .py file (the get_notes() function) to extract the notes and chords data from this midi file. Here is the exact code copied from the repo I'm using:

def get_notes():
    """ Get all the notes and chords from the midi files in the ./midi_songs directory """
    notes = []

    for file in glob.glob("midi_songs/*.mid"):
        midi = converter.parse(file)

        print("Parsing %s" % file)

        notes_to_parse = None

        try: # file has instrument parts
            s2 = instrument.partitionByInstrument(midi)
            notes_to_parse = s2.parts[0].recurse() 
        except: # file has notes in a flat structure
            notes_to_parse = midi.flat.notes

        for element in notes_to_parse:
            if isinstance(element, note.Note):
                notes.append(str(element.pitch))
            elif isinstance(element, chord.Chord):
                notes.append('.'.join(str(n) for n in element.normalOrder))

    with open('data/notes', 'wb') as filepath:
        pickle.dump(notes, filepath)

    return notes

My midi file has multiple instruments, which I believe for some reason is causing nothing to be appended to the notes list. Seeing as I've just cloned the repository's code and run it on my own midi file, I'm not sure why it isn't working. I've looked through the documentation for music21's partitionByInstrument(), and tried to iterate through the different instruments by changing:

notes_to_parse = s2.parts[0].recurse()

to

 notes_to_parse = s2.parts[1].recurse()

as different parts should be different instruments from the file, but it still returns an empty list. What do I do?


Solution

  • It was simply the fact that it was taking the first instrument it found, which had no data for notes, durations or offsets. Iterating through the instruments I got different ones returning full lists.