Add warnings and extend documentation for issue #1120 (#1126)

This commit is contained in:
Tom M 2022-06-27 17:26:15 +02:00 committed by GitHub
parent 3a3ed4f783
commit a50680aafa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 3 deletions

View file

@ -418,7 +418,7 @@ and commit the results. Refresh with the following command:
<min>64</min>
<max>8192</max>
<desc>
The size of the audio buffers (in frames).
This is the number of audio samples most audio drivers will request from the synth at one time. In other words, it's the amount of samples the synth is allowed to render in one go when no state changes (events) are about to happen. Because of that, specifying too big numbers here may cause MIDI events to be poorly quantized (=untimed) when a MIDI driver or the synth's API directly is used, as fluidsynth cannot determine when those events are to arrive. This issue does not matter, when using the MIDI player or the MIDI sequencer, because in this case, fluidsynth does know when events will be received.
</desc>
</setting>
<setting>

View file

@ -331,6 +331,18 @@ FLUIDSYNTH_API int fluid_synth_tuning_dump(fluid_synth_t *synth, int bank, int p
* render real-time audio, ensure that you call these functions from a high-priority
* thread with little to no other duties other than calling the rendering functions.
*
* @warning
* If a concurrently running thread calls any other sound affecting synth function
* (e.g. fluid_synth_noteon(), fluid_synth_cc(), etc.) it is unspecified whether the event triggered by such a call
* will be effective in the recently synthesized audio. While this is inaudible when only requesting small chunks from the
* synth with every call (cf. fluid_synth_get_internal_bufsize()), it will become evident when requesting larger sample chunks:
* With larger sample chunks it will get harder for the synth to react on those spontaneously occurring events in time
* (like events received from a MIDI driver, or directly made synth API calls).
* In those real-time scenarios, prefer requesting smaller
* sample chunks from the synth with each call, to avoid poor quantization of your events in the synthesized audio.
* This issue is not applicable when using the MIDI player or sequencer for event dispatching. Also
* refer to the documentation of \setting{audio_period-size}.
*
* @{
*/
FLUIDSYNTH_API int fluid_synth_write_s16(fluid_synth_t *synth, int len,

View file

@ -323,7 +323,20 @@ new_fluid_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
if(def)
{
fluid_audio_driver_t *driver = (*def->new)(settings, synth);
fluid_audio_driver_t *driver;
double srate, midi_event_latency;
int period_size;
fluid_settings_getint(settings, "audio.period-size", &period_size);
fluid_settings_getnum(settings, "synth.sample-rate", &srate);
midi_event_latency = period_size / srate;
if(midi_event_latency >= 0.05)
{
FLUID_LOG(FLUID_WARN, "You have chosen 'audio.period-size' to be %d samples. Given a sample rate of %.1f this results in a latency of %.1f ms, which will cause MIDI events to be poorly quantized (=untimed) in the synthesized audio (also known as the 'drunken-drummer' syndrome). To avoid that, you're strongly advised to increase 'audio.periods' instead, while keeping 'audio.period-size' small enough to make this warning disappear.", period_size, srate, midi_event_latency*1000.0);
}
driver = (*def->new)(settings, synth);
if(driver)
{

View file

@ -3717,7 +3717,8 @@ fluid_synth_get_active_voice_count(fluid_synth_t *synth)
* @param synth FluidSynth instance
* @return Internal buffer size in audio frames.
*
* Audio is synthesized this number of frames at a time. Defaults to 64 frames.
* Audio is synthesized at this number of frames at a time. Defaults to 64 frames. I.e. the synth can only react to notes,
* control changes, and other audio affecting events after having processed 64 audio frames.
*/
int
fluid_synth_get_internal_bufsize(fluid_synth_t *synth)