mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-04-15 20:30:49 +00:00
Ensure the reverb engine is initialized after synth creation
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.
This commit is contained in:
parent
9793c0def3
commit
44453ff232
1 changed files with 6 additions and 31 deletions
|
@ -131,11 +131,6 @@ static void fluid_synth_handle_reverb_chorus_int(void *data, const char *name, i
|
|||
static void fluid_synth_reset_basic_channel_LOCAL(fluid_synth_t *synth, int chan, int nbr_chan);
|
||||
static int fluid_synth_check_next_basic_channel(fluid_synth_t *synth, int basicchan, int mode, int val);
|
||||
static void fluid_synth_set_basic_channel_LOCAL(fluid_synth_t *synth, int basicchan, int mode, int val);
|
||||
static int fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize,
|
||||
double damping, double width, double level);
|
||||
|
||||
static int fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double level,
|
||||
double speed, double depth_ms, int type);
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
@ -896,7 +891,7 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
fluid_settings_getnum(settings, "synth.reverb.width", &width);
|
||||
fluid_settings_getnum(settings, "synth.reverb.level", &level);
|
||||
|
||||
fluid_synth_set_reverb_full_LOCAL(synth,
|
||||
fluid_synth_set_reverb_full(synth,
|
||||
FLUID_REVMODEL_SET_ALL,
|
||||
room,
|
||||
damp,
|
||||
|
@ -912,7 +907,7 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
fluid_settings_getnum(settings, "synth.chorus.speed", &speed);
|
||||
fluid_settings_getnum(settings, "synth.chorus.depth", &depth);
|
||||
|
||||
fluid_synth_set_chorus_full_LOCAL(synth,
|
||||
fluid_synth_set_chorus_full(synth,
|
||||
FLUID_CHORUS_SET_ALL,
|
||||
i,
|
||||
level,
|
||||
|
@ -5044,6 +5039,7 @@ fluid_synth_set_reverb_full(fluid_synth_t *synth, int set, double roomsize,
|
|||
double damping, double width, double level)
|
||||
{
|
||||
int ret;
|
||||
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
|
||||
|
||||
fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
|
||||
/* if non of the flags is set, fail */
|
||||
|
@ -5052,16 +5048,6 @@ fluid_synth_set_reverb_full(fluid_synth_t *synth, int set, double roomsize,
|
|||
/* Synth shadow values are set here so that they will be returned if querried */
|
||||
|
||||
fluid_synth_api_enter(synth);
|
||||
ret = fluid_synth_set_reverb_full_LOCAL(synth, set, roomsize, damping, width, level);
|
||||
FLUID_API_RETURN(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize,
|
||||
double damping, double width, double level)
|
||||
{
|
||||
int ret;
|
||||
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
|
||||
|
||||
if(set & FLUID_REVMODEL_SET_ROOMSIZE)
|
||||
{
|
||||
|
@ -5093,7 +5079,7 @@ fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize
|
|||
fluid_rvoice_mixer_set_reverb_params,
|
||||
synth->eventhandler->mixer,
|
||||
param);
|
||||
return ret;
|
||||
FLUID_API_RETURN(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5259,6 +5245,7 @@ fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double level,
|
|||
double speed, double depth_ms, int type)
|
||||
{
|
||||
int ret;
|
||||
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
|
||||
|
||||
fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
|
||||
/* if non of the flags is set, fail */
|
||||
|
@ -5267,18 +5254,6 @@ fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double level,
|
|||
/* Synth shadow values are set here so that they will be returned if queried */
|
||||
fluid_synth_api_enter(synth);
|
||||
|
||||
ret = fluid_synth_set_chorus_full_LOCAL(synth, set, nr, level, speed, depth_ms, type);
|
||||
|
||||
FLUID_API_RETURN(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double level,
|
||||
double speed, double depth_ms, int type)
|
||||
{
|
||||
int ret;
|
||||
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
|
||||
|
||||
if(set & FLUID_CHORUS_SET_NR)
|
||||
{
|
||||
synth->chorus_nr = nr;
|
||||
|
@ -5315,7 +5290,7 @@ fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double
|
|||
synth->eventhandler->mixer,
|
||||
param);
|
||||
|
||||
return (ret);
|
||||
FLUID_API_RETURN(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue