This issue was brought up by Joel Ross on July 7 (http://lists.nongnu.org/archive/html/fluid-dev/2011-07/msg00000.html). He wrote:
I'm using the offline Fast Render option, and I find that the track
stops rendering at the moment the last midi event is received, cutting
off the last notes before the release time.
...
I'd like for it to wait until the End Track message when rendering offline.
I've experimented with this -- it's not just a problem with the Fast Render option. It affects all MIDI playing.
The problem is that the MIDI file loader in fluid_midi.c ignores (almost) the end-of-track (EOT) event. It uses it to figure out that it's time to read events from the next track, but it doesn't push it onto the event queue, so when the events are played back out, the "last event" on the queue is actually the last non-EOT event. This is typically a note-off event, which means that FS cuts off the recording as soon as it receives the final note-off event in whichever track is the longest.
The solution is simple: push the EOT event onto the event queue. When the player encounters the EOT event, just do nothing. That way, the existing logic for deciding when to stop playing will keep the track alive until the EOT event is encountered.
However, I'm not sure if this fully addresses the problem -- it depends on the MIDI file. If the MIDI file is set up so that the EOT occurs some seconds after the final note, then this will fix the "cutoff" issue. However, in some MIDI files, the EOT occurs exactly on the final note, so this won't help at all. Notably, the MIDI files created by Rosegarden seem to always set EOT at exactly the same time as the final note-off, and I can't find any way to tell it not to do that. We could decide that a) this is not FluidSynth's problem, or b) we do want to fix this (in which case, we'll have to dive deeper into the code and wait until all the notes have actually finished playing before we stop the song). Still, this is a good first step.
Attaching a patch against SVN trunk r435. This patch also modifies the binary MIDI file I put in the documentation under "Playing a MIDI file from memory" to add 480ms before the EOT event, to test this change out.
Reported by: mattgiuca
Original Ticket: fluidsynth/tickets/101
该提问来源于开源项目:FluidSynth/fluidsynth