fluidsynth icon indicating copy to clipboard operation
fluidsynth copied to clipboard

MIDI file player ends before all notes have been played.

Open derselbst opened this issue 14 years ago • 8 comments

Originally created by: David Henningsson

Two problems must be addressed:

  • [x] The MIDI player should wait for all voices to terminate after the last MIDI note, plus some extra time for reverb.
  • [ ] Client programs (like FluidSynth CLI) should wait for all audio buffers to be played before terminating, it's not enough that the player has finished.

Reference:
http://lists.gnu.org/archive/html/fluid-dev/2009-03/msg00040.html

Reported by: *anonymous

Original Ticket: fluidsynth/tickets/24

derselbst avatar May 26 '10 21:05 derselbst

Original comment author: diwic

Here are my thoughts about this issue.

For problem 1: I'm a little hesitant about this part. I think it's more important that we don't lose a predictable endpoint / song length. That is important when a song loops. It could be that somebody has written a beat that he wants to repeat over and over again and practice to it, then he don't want extra delays every time the beat starts over. Or it could be that FluidSynth is used for game background music, where the music should loop seamlessly.

For problem 2: This should be pretty straight forward to implement. I suggest a new driver public API function fluid_audio_stop(boolean immediately) is added. If immediately is false, it waits for all buffers to be played before it returns. For the ALSA driver, that is the same as calling snd_pcm_drain. I could do it for ALSA, but I don't know how to implement/test it in the other audio drivers.

Original comment by: elementgreen

derselbst avatar May 27 '10 00:05 derselbst

In regards to snd_pcm_drain with ALSA and such. That seems more like a function of the audio driver, in that it should flush out any data when the driver is closed. I think problem 2 is actually not directly related to that. The required functionality can probably be summarized as the following:

  1. Ability to determine when a MIDI song ends
  2. Ability to determine when audio playback is silent
  3. Audio drivers should flush out already sent audio when closed

When playing many MIDI songs back to back, perhaps the player could add a configurable amount of delay between the songs.

Original comment by: elementgreen

derselbst avatar May 27 '10 00:05 derselbst

I accidentally duplicated this bug in ticket #101. The patch there addressed problem 1 -- FluidSynth now detects when the song officially ends (the EOT event for the longest track, which may be much later than the final note ends). I think we have agreed that FS should not "second-guess" the EOT event and attempt to keep playing until the channel is silent. For one thing, this has the potential of non-termination if the MIDI file has a NoteOn event without a corresponding NoteOff.

I haven't looked into Problem 2 but I suspect this hasn't been addressed, so this ticket probably should remain open.

Original comment by: mattgiuca

derselbst avatar Sep 19 '11 01:09 derselbst

I found this task because I was listening to some rendered audio files on Wikipedia and I was annoyed about the abrupt way that they terminate. See e.g. https://en.wikipedia.org/wiki/Mozart%27s_starling . Our Score extension uses LilyPond to generate MIDI files which are then converted to Ogg using FluidSynth with the -F option. I suppose I could add 500ms of silence as a second MIDI file to the command line, although it's a bit of a hack since we don't know how long the sound will take to decay.

I appreciate that it's nice to have a way to generate files that end exactly on the beat, for looping. For our purposes, it would be fine to have a command line option or config setting.

tstarling avatar Jul 29 '20 23:07 tstarling

Hate to revive an old thread, but this is STILL HAPPENING in FluidSynth 2.1.7.

Foxy6670 avatar Aug 08 '22 10:08 Foxy6670

Hate to revive an old thread, but this is STILL HAPPENING in FluidSynth 2.1.7.

That's why this ticket is still open. I welcome your PR.

derselbst avatar Aug 08 '22 10:08 derselbst

Other than situations where FluidSynth reverb settings are high, I've alleviated big chunks of this issue in #1159 and #1167. They cause FluidSynth to wait for active voices to finish plus an additional two seconds (for effects like reverb) before stopping playback. Previously, FluidSynth would stop playback immediately once the last MIDI event was processed. The "wait two seconds" part would be better handled by a mechanism for detecting when audio actually drops below some minimum threshold, but I'm not equipped to implement such a feature at this time; ideas for that logic in particular are being captured in #1165.

topaz avatar Oct 01 '22 06:10 topaz

uname -a: Linux box 5.10.0-26-amd64 #1 SMP Debian 5.10.197-1 (2023-09-29) x86_64 GNU/Linux

Fluidsynth version 2.1.7.

These cases do work, reading directly: fluidsynth -a jack -g 1 TimGM6mb.sf2 download/Fur Elise.mid fluidsynth -F out.wav -g 1 TimGM6mb.sf2 download/Fur Elise.mid fluidsynth -a alsa -g 1 TimGM6mb.sf2 download/Fur Elise.mid

This works with alsa sequencer and alsa playback: fluidsynth -a alsa -m alsa_seq -g 1 TimGM6mb.sf2 pmidi -p 128:0 download/Fur Elise.mid

This don't (starting and configuring jack2 first with qjackctl): fluidsynth -a jack -m alsa_seq -g 1 TimGM6mb.sf2 pmidi -p 130:0 download/Fur Elise.mid

Same problem with other synthesizer playing via jack (connect synthesizers midi in with system capture midi out in qjackctl first) foo-yc20-cli pmidi -p 14:0 download/Fur Elise.mid In the foo-yc20-cli appers seversal time PANIC. I tryid it with setBfree and horgand with the same result (abort bevore EOF at the same position and PANIC in horgand).

I wonder how jack affects the alsa midi sequencer.

36000000 avatar Jan 19 '24 15:01 36000000