Skip to content

Commit

Permalink
Make failing test for reading tracks with overlapping notes.
Browse files Browse the repository at this point in the history
Make two tracks using mido - one good with correct note-on/note-off order,
second (bad) with another note-on before note-off at the same tick.
Current code fails on the latter.

Then read it via PrettyMidi, write it and read it back. It should be the same
according to expected values, but due to a bug it differs.
  • Loading branch information
bzamecnik committed Jul 18, 2017
1 parent b85eb16 commit 65b91f4
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions tests/test_pretty_midi.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pretty_midi
import numpy as np
import mido


def test_get_beats():
Expand Down Expand Up @@ -272,3 +273,56 @@ def simple():
for ks, t, k in zip(pm.key_signature_changes, ks_times, ks_keys):
assert ks.time == t
assert ks.key_number == k

def test_properly_order_overlapping_notes():
def make_mido_track(notes_str, path):
track = mido.MidiTrack()
for line in notes_str.split('\n'):
line = line.strip()
if line:
track.append(mido.Message.from_str(line))
mido_file = mido.MidiFile()
mido_file.tracks.append(track)
mido_file.save(path)

# two notes with pitch 72 open at once
bad_track = """
note_on channel=0 note=72 velocity=88 time=0
note_on channel=0 note=72 velocity=88 time=48
note_on channel=0 note=72 velocity=0 time=0
note_on channel=0 note=74 velocity=88 time=48
note_on channel=0 note=72 velocity=0 time=0
note_on channel=0 note=72 velocity=88 time=48
note_on channel=0 note=74 velocity=0 time=0
note_on channel=0 note=72 velocity=0 time=48
"""

# the 72 note is first closed, then another one opened
good_track = """
note_on channel=0 note=72 velocity=88 time=0
note_on channel=0 note=72 velocity=0 time=48
note_on channel=0 note=72 velocity=88 time=0
note_on channel=0 note=74 velocity=88 time=48
note_on channel=0 note=72 velocity=0 time=0
note_on channel=0 note=72 velocity=88 time=48
note_on channel=0 note=74 velocity=0 time=0
note_on channel=0 note=72 velocity=0 time=48
"""

for kind, track in (('good', good_track), ('bad', bad_track)):
midi_path = 'overlapping_notes_%s_track.mid' % kind
make_mido_track(track, midi_path)

pm_song = pretty_midi.PrettyMIDI(midi_path)

def extract_notes(pm_track):
return np.array([(note.pitch, note.end-note.start) for note in pm_track.notes])

expected = np.array([[72, 0.05], [72, 0.05], [74, 0.05], [72, 0.05]])
assert np.allclose(expected, extract_notes(pm_song.instruments[0]))

midi_written_path = 'overlapping_notes_%s_track_written.mid' % kind
pm_song.write(midi_written_path)
pm_song_written = pretty_midi.PrettyMIDI(midi_written_path)

assert np.allclose(expected, extract_notes(pm_song_written.instruments[0]))

0 comments on commit 65b91f4

Please sign in to comment.