craffel / pretty-midi

Utility functions for handling MIDI data in a nice/intuitive way.
MIT License
874 stars 151 forks source link

End of track rounding #250

Closed audiomax-ai closed 1 month ago

audiomax-ai commented 1 month ago

Is there a reason for adding an extra tick to the appended "end of track" text event? This seems to add a few milliseconds to the end time when rendering audio from MIDI in Fluidsynth.

For example, assuming a 96 ticks per quarter note resolution, a 4-bar MIDI loop at 120 BPM should have an end time of 1536 ticks, or precisely 8 seconds, but the appended text event extends it to 1537 ticks, making the total duration 8.007 seconds. It may not seem like much, but it's problematic for those trying to render seamless audio loops that need to stay precisely on tempo.

craffel commented 1 month ago

You mean here? https://github.com/craffel/pretty-midi/blob/main/pretty_midi/pretty_midi.py#L1561 Probably to ensure that an end of track event doesn't clobber some other event that's meant to appear. But if this is unnecessary/erroneous, it could be fixed.

audiomax-ai commented 1 month ago

Yeah, on line 1561. I'm not sure what the MIDI standards are for writing end_of_track events, but I think the +1 is creating an imprecise end time based on the tick resolution. So with some programs like FluidSynth, it's impossible to render an audio file exactly on tempo (or by bars). You can see in the image below how it's just a bit longer than 4 bars or 8 seconds.

If +1 has no specific purpose, maybe consider removing it.

extra_tick