So I am trying to parse a MIDI song using the Music21 library. This song notes of varying durations, chords, and rests. I want to be able to parse through the song and check to see whether the MIDI event is a note, if so store its MIDI number and duration (quarterLength) into a list. I also want to check to see if it is a chord, if so store the chord and its duration in the list.
The format that I've decided I want the chord to be is basically all of the MIDI notes that make it up, joined together by a "." At the end, I'd like the list which contains all of the chords, notes, and durations to look something like this:
["note/chord1 duration1",
"note/chord2 duration2",
...]
For example:
song =
["65 1.0", #(note, duration)
"65.71.66 0.5", #(chord, duration)
"59 2.0",
"59.60 1.5",
...]
Any help on this would be appreciated, or any explanation as to what is going wrong in my approach would also be appreciated.
Here's what I've attempted already. The real problem is with the second elif statement in the for loop; I'm getting some funky output that is undesired.
file = "song.mid"
midi_song = converter.parse(file)
print("Parsing %s" % file)
notes_to_parse = None
try: # file has instrument parts
s2 = instrument.partitionByInstrument(midi_song)
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):
midi_number.append(str(element.pitch.midi) + " " + str(element.quarterLength))
elif isinstance(element, chord.Chord):
midi_chord_number.append(".".join(str(n.pitch.midi) for n in element) + " " + str(element.quarterLength))
elif isinstance(element, note.Rest):
notes.append(str(element.name) + " " + str(element.quarterLength))
The output should have the MIDI number representation of the note or chord that has been encountered, but it seems to be duplicating a lot of the same notes:
['69.73.76',
'69.73.76',
'69.73.76 4/3',
'69.73.76 4/3',
'69.73.76 1.75',
'69.73.76 1.75',
'69.73.76 0.75',
'69.73.76 0.75',
'69.73.76 0.75',
'69.73.76 0.75',
'69.73.76 4/3',
'69.73.76 4/3',
'69.73.76 4/3',
'69.73.76 4/3',
'69.73.76 1.0',
'69.73.76 1.0',
'69.73.76 1.0',
'69.73.76 1.0',
'69.73.76 1.0',
'69.73.76 1.0',
'69.73.76 8/3',
'69.73.76 1.0',
'69.73.76 4/3',
'69.73.76 2.0',
'69.73.76 8/3',
'69.73.76 1.0',
'69.73.76 4/3',
'69.73.76 2.0',
'62.70 4/3',
'62.70 4/3',
'62.70 1.75',
'62.70 1.75',
'62.70 0.75',
'62.70 0.75',
'62.70 0.75',
'62.70 0.75',
'62.70 4/3',
'62.70 4/3',
'62.70 4/3',
'62.70 4/3',
'62.70 1.0',
'62.70 1.0',
'62.70 1.0',
'62.70 1.0',
'62.70 1.0',
'62.70 1.0',
'62.70 8/3',
'62.70 1.0',
'62.70 4/3',
'62.70 2.0',
'62.70 8/3',
'62.70 1.0',
'62.70 4/3',
'62.70 2.0',
'62.70 4/3',
'62.70 4/3',
'60.69 1.75',
'60.69 1.75',
'60.69 0.75',
'60.69 0.75',
'62.71 0.75',
'62.71 0.75',
'64.72 4/3',
'64.72 4/3',
'62.70 4/3',
'62.70 4/3',
'60.69 1.0',
'60.69 1.0',
'60.69 1.0',
'60.69 1.0',
'62.71 1.0',
'62.71 1.0',
'55.60 8/3',
'64.72.79 1.0',
'67.60 4/3',
'36.48 2.0',
'55.60 8/3',
'64.72.79 1.0',
'67.60 4/3',
'36.48 2.0',
'62.70 4/3',
'62.70 4/3',
'60.69 1.75',
'60.69 1.75',
'60.69 0.75',
'60.69 0.75',
'62.71 0.75',
'62.71 0.75',
'64.72 4/3',
'64.72 4/3',
'62.70 4/3',
'62.70 4/3',
'60.69 1.0',
'60.69 1.0',
'60.69 1.0',
'60.69 1.0',
'62.71 1.0',
'62.71 1.0',
'55.60 8/3',
'64.72.79 1.0',
'67.60 4/3',
'36.48 2.0',
'55.60 8/3',
'64.72.79 1.0',
'67.60 4/3',
'36.48 2.0',
'62.70 4/3',
'62.70 4/3',
'60.69 1.75',
'60.69 1.75',
'60.69 0.75',
'60.69 0.75',
'62.71 0.75',
'62.71 0.75',
'64.72 4/3',
'64.72 4/3',
'62.70 4/3',
'62.70 4/3',
'60.69 1.0',
'60.69 1.0',
'60.69 1.0',
'60.69 1.0',
'62.71 1.0',
'62.71 1.0',
'55.60 8/3',
'64.72.79 1.0',
'67.60 4/3',
'36.48 2.0',
'55.60 8/3',
'64.72.79 1.0',
'67.60 4/3',
'36.48 2.0']