python-midi
python-midi copied to clipboard
Is there any way to locate the chord track?
I'm doing research on MIDI files. And I need a collection of Midi tabs that include both the melody and chord sequences of multiple measures. So how can I know which track is melody and which track is the chord? I want to extract the chord sequences and melody sequences from some MIDI files. How can I do it?
It depends on how the MIDI file has been written. If, for example, the melody is only in a track, with the others being used for accompaniment, that's easy: just extract the melody track to a midi file, then the others to another one. The same goes for channels. If, instead, everything is on a single track (or the track with the melody also has chords), it's a bit tricky. You could try to write a script that "detects" only the higher notes in a polyphonic track, with any new highest note taking precedence over the previous (that's how monophonic synths usually work), but it is highly probable that you will find yourself with some notes which are just part of the harmony, because in that particular moment there was a rest within the melody. Something like this, maybe:
pattern = midi.read_midifile('example.mid')
melody = midi.Track()
current = None
for event in in pattern[0]:
# note: I'm assuming that everything is on the first track
if isinstance(event, midi.NoteOnEvent):
if current is None:
# no note is playing, we suppose it *might* be the melody
melody.append(event)
current = event
elif event.pitch > current.pitch:
# we have a new higher note, so we stop the previous one and start the new one
melody.append(midi.NoteOffEvent(tick=event.tick - 1, channel=current.channel, data=current.data))
melody.append(event)
current = None
elif isinstance(event, midi.NoteOffEvent) and current is not None and event.pitch == current.pitch:
melody.append(event)
current = None
melody.append(midi.EndOfTrackEvent(tick=event.tick)
melody_pattern = midi.Pattern()
melody_pattern.append(melody)
midi.write_midifile('melody.mid', melody_pattern)
As you can see, this only tracks the melody, so you'd have to track the melody track notes for duplicates, otherwise add them to the chord pattern if you need that too. I haven't actually tried this one, so I'm not sure it will work as expected (for sure, it won't work properly if notes of the melody overlap while they are descending), but at least it is a concept to start with.