This fixes a regression introduced in 907ec27a9e
When rendering a voice, there are 3 cases to consider: silent, playing,
and finished. When optimizing away the memset, I incorrectly assumed that
a voice cannot switch between playing and silence (like crazy) while
rendering FLUID_MIXER_MAX_BUFFERS_DEFAULT. Apparently this does not
hold true, esp. when rendering at sample rates ~96kHz.
- memset should clear all the memory
- end position should be at the end of sample data
Closes#576
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
The parameters (roomsize, level, etc.) of the reverb effects unit are initialized at the very end of `new_fluid_synth()` with `fluid_synth_set_reverb_full_LOCAL()`.
This however only adds an update-event to the `rvoice_mixer` queue.
The call to `fluid_synth_process_event_queue()` in `new_fluid_synth()` should make sure, that this event is dispatched and triggers the actual update.
However, the event is not dispatched immediately, because the rvoice event queue has not been committed yet, that is, a call to `fluid_rvoice_eventhandler_flush()` is missing.
So, although a reverb param initialization event has been queued, the reverb params still are garbage initialized (on Windows to some `-6.2774385622041925e+66`).
The next call to through the synth's public API will flush the queue and finally dispatch the update event, but when will it happen?
1. If the soundfont is specified as command-line argument, this call will happen before the audio driver starts rendering.
2. If the soundfont is loaded via shell command `load`, the audio driver will first start rendering audio, after updating the reverb.
Case 1. is trivial, everything works as it should.
Case 2. is interesting. Since the synth already started rendering audio by using that uninitialized reverb unit, the reverb engine's internal buffer is completely filled up with noise. Before outputting that signal to sound card, the sound is clipped to `1.0f`. That's the click we hear at the beginning. And because the reverb is so loud, the rendered audio signal stays 1.0f for quite a long time (...or always, can't tell).
Why is it not reproducible on Linux? Because GCC and Clang (AFAIK) leave all values uninitialized after allocating memory. And because malloc() often return zero-initialized memory, the reverb params seem to be nicely zero-initialized. MSVC however, always initializes memory with garbage, which is why we "hear" this resonance disaster.
Solution: Just update the reverb params via public API, which implicitly calls `fluid_rvoice_eventhandler_flush()`.
Fixes#563.
Fixes a use-after-free when the MIDI player is deleted before the audio
driver, because the synthesis thread is still actively making callbacks
on the sample timer, which is deleted by the player though.
Previously, sample timers were deleted in fluid_player_stop() which caused a use-after-free when at the same time the sample timers were advanced by the synthesizer thread. This was incorrectly addressed in 5d3f727547 . Deleting sample timers is now done in delete_fluid_player(). A broken application could still crash if it does not respect the order of object creation though. At least now, this issue is properly documented.
In an out of memory situation, fluid_synth_t::voice and fluid_synth_t::channel may not be fully initialized, causing a NULL dereference and heap corruption in delete_fluid_synth().
Vorbis compressed SF3 samples are always loaded individually and stored
in the sample cache in uncompressed form. When dynamic-sample-loading is
not active (the default), then the uncompressed samples did not get
unloaded when unloading the SF3 font.
This fix makes sure that those samples are also freed. For bulk loaded
samples, the sample->data pointer is always the same as the
font->sampledata pointer. For individually loaded samples, the sample->data
pointer always points to a different memory region. So we can use that
information to determine if and when to unload the samples one by one.
Fixes#530Fixes#528
The old buffering code assumes that synth->cur is between 0 and FLUID_BUFSIZE.
However since fluid_synth_process() can render more than one buffer at a time
this isn't always true, and the new code handles other values properly.
Closes#527
When fluidsynth is run as a service using systemd, make sure
the service is considered started only when it is ready to process events.
In order to do so:
- Add an optional runtime dependency to libsystemd to the fluidsynth executable
- Change the systemd service type to "notify"
- Have fluidsynth notify systemd that the service is started after the server is started
- Have fluidsynth notify systemd that the service is stopping after joining the server thread
possibly due to glibc-2.29 commit 424c4f60ed6190e2ea0e72e0873bf3ebcbbf5448
pow is using fused-multiply-add (fma) if available.
That caused the fluidsynth binaries to differ depending on
the build machine's CPU.
This was visible among others in
grep '7.58577575029183[56]e-04' fluidsynth-2.0.3/build/fluid_conv_tables.c
See https://reproducible-builds.org/ for why this is matters.
Closes#512.