midilib
midilib copied to clipboard
Keep unusual note off event in input
Summary
The proposal to keep the unusual note off event as input. Because the current implementation drops such note-offs and breaks the time of following events.
How to Reproduce Issue
Note: I included the test in this PR.
- Copy a sample MIDI file (Auld Lang Syne) with midilib using the following code.
- Play both of the original
hotaru.mid
and the outputoutput.mid
. So you'll find the obvious error.
require "midilib"
def read_midifile(infile)
MIDI::Sequence.new().tap do |seq|
File.open(infile, 'rb') { |file|
seq.read(file)
}
end
end
def write_midifile(outfile, seq)
File.open(outfile, 'wb') { |file|
seq.write(file)
}
end
# Download a midi file.
system "curl -O 'http://yasashiiorgel.jp/midi/hotaru.mid'"
# Just copy the SMF data as is using midilib.
write_midifile('output.mid', read_midifile('hotaru.mid'))
Detail
The above sample MIDI file has unusual note-off events like this:
[From output of midi-dump https://g200kg.github.io/midi-dump/]
0000a0 00 4f 00 +0 = 0 : NoteOn (ch:1 note:79 velo:0)
0000a3 00 4f 40 +0 = 0 : NoteOn (ch:1 note:79 velo:64)
0000a6 58 3c 00 +88 = 88 : NoteOn (ch:1 note:60 velo:0)
0000a9 00 3c 40 +0 = 88 : NoteOn (ch:1 note:60 velo:64)
Why that? The MIDI is produced by a composer software for DIY hand crank music boxes. To reproduce the instrument's damper behavior, any note-off events always appear just before the corresponding note-on.
As for the above four events, midilib drops the third note-off event because the corresponding note-on event is not found. Therefore the time of the forth note-on event breaks.