fluidsynth
fluidsynth copied to clipboard
Default synth.gain for 2.4.0 and higher of 0.6 is too high
FluidSynth version
master (as of Sun. Oct. 13th, 2024) to become 2.4.0
Describe the bug
Default "synth.gain" for 2.4.0 and higher of 0.6 is too high
Expected behavior
Some midi files run into clipping now with "audio.driver", "file"
Steps to reproduce
Use Dance.mid from https://schristiancollins.com/generaluser.php which is part of the GeneralUser GS 2.0.0. Clipping happens at ~40 sec.
Additional context
For 2.4.0 and higher the default synth gain is planned to change from 0.2 to 0.6 (see https://www.fluidsynth.org/api/settings_synth.html#settings_synth_gain). I have been doing intensive testing with the upcoming 2.4.0 and ran into this issue. Of course, the gain can be initialized with fluid_synth_set_gain. But going from 2.6.3 to 2.4.0 requires a code change now. It took me quite some time to find out why Dance.mid is now clipping in audio export files but is not in 2.6.3. Of course, using fluid_synth_set_gain to initialize the gain is always a good idea.
I meant 2.3.6 composer to 2.4.0
ogg format does not clip with 0.6 but for wav, flac, mp3 clipping happens
Thanks Reinhold for investigating! It seems that using 0.3 wouldn't clip.
@es20490446e You have introduced the new gain in #1287, any preference of using 0.2 or 0.3? A more solid solution for this may lie in #1302.
ogg format does not clip with 0.6
OGG is a special case as it uses floats inside libsndfile, which are scaled as postprocessing step to prevent most clippings.
Thanks for the immediate response.
Yes, 0.3 is fine (0.35 may still work but 0.4 clips). 0.3 is on the safe side.
I chose 0.6 because it provided a good balanced between foreground dialogs and effects, and background music, when using Fluidsynth on old games.
The previous setting of 0.2 made the background music mostly inaudible, and weirdly low when played through the media played compared with non midi music.
So I made the volume just a bit lower than non midi files. That didn't result in any clipping I could perceive. Either in the VLC media player, DosBox or Wine.
This is by using GeneralUserGs, which samples are a bit quieter than those from the Fluid sound-font.
I took GeneralUserGs as reference because I think it's more balanced, realistic and intended for a broader user case.
I have tried reproducing the clipping, but I have been unable to. See the used code here: Fluidsynth.zip
I have tried:
- audio-driver: alsa vs file
- midi-driver: alsa vs alsa_raw vs oss
- audio-bufsize: default vs 1024
- sample-rate: 44000 vs 48000
- audio-file-type: oga vs flac (32-bit) vs wav (16-bit)
- Playing output files: vlc vs terminal vs android-vlc vs android-mi-player
- Recording files vs Playing them through the terminal
My system is:
- Arch Linux
- Linux Zen 6.11.3
- Fluidsynth 2.3.6 + Fluidsynth-git settings
- GeneralUserGS 2.0
- Pipewire 1.2.5
- Realtek ALC257
- i7-10750H 12-cores 2.6GHz
I suspect that my audio processor (Pipewire) or my sound chip (Realtek) prevent the clipping all together. We would need to bisect this.
Please:
- Try if you can hear clipping in my audio samples.
- Share the audio samples created in your system.
- Tell me in what kind of system and configuration you are experiencing the clipping.
Also I think that lowering the gain to a very quiet level is really solving nothing.
It's just a work-around, and many consumer software will raise the gain to a louder level anyway.
As said, clipping with gain 0.6 only happens for "audio.driver", "file". Clipping only happens for the audio formats wav, and wav converted to mp3 (with lame), flac (with libFLAC etc). No clipping for ogg (libogg etc). Any other driver like Directsound, WASAPI + exclusive, portaudio + ASIO, Jack is OK. For these other ones I use 0.7 w/o clipping.
Arch: Windows 10 latest update Processor: Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz with 10 cores ("synth.cpu-cores" is used) Sountfont: GeneralUserGS 2.0 + recommended fluidsynth settings, but other soundfont like FluidR3_GM2-2 create clippng with 0.6 as well Sample rate: for both 44100 KHz + 48000 kHz
With regards to sharing the Dance.mid audio samples I have my concerns. Not sure that these are w/o property rights.
In order to be on the safe side I now use the gain setting for "synth.gain" to be initialized for my needs. The problem is now solved for me.
My point is that 0.2 has been the default value since ever, at least for the past 10 years. Increasing the default now to 0.6 - all of a sudden with 2.4.0 - causes clipping where I ran into. This could have been avoided.
I have tested it with:
- audio-driver: file
- midi-driver: file
- sample-rate: 44000
- audio-file-type: wav (16-bit)
But the clipping didn't occur. I will need to keep discarding factors.
By the way, what is your sound card?
I did not mention the sound card because for "audio.driver", "file" IMHO the sound card is irrelevant.
We hear clipping by a gain of 0.6 on all of the different PC types in our lab: from a 2008 old Intel Core 2 P8400 PC with Windows, on the PC mentioned above, on Linux Wine installations as well as on a Mac with macOS Sequoia running our x64 app on top of Wine on an Apple M-processor where the object code is converted by Rosetta 2 (which is still unbelievable fast).
We have our app in thousands of installations in the market since almost 10 years and never had any complain by a customer with the default gain 0.2. Of course, the gain can be modified. But 0.6 is definitely to high. @es20490446e : I respectfully disagree your point that "...lowering the gain to a very quiet level is really solving nothing." It resolves the clipping, definitely. In my view 0.2 is not "very quiet". It is more quiet than 0.6. For me, 0.3 is a very good value.
To me a "default value" should cover most of the cases. Changing a default value which is in place for so long due to a special configuration (old games, Linux, Pipewire etc.) is not the right step. In such as case the gain should be set by
fluid_settings_setnum(s_settings, "synth.gain", 0.6f); or by the command parameter option -g
as you did it in your examples (when I read them correctly) but not by changing the "default value" in the fluidsynth code.
As said above, the problem is resolved for us. We initialize the value in the future for our needs.
@derselbst: in case of a change from 0.2 to something new please do not forget to change print_help in fluidsynth.c "Set the master gain [0 < gain < 10, default = 0.2]"
That's why I'm asking you if you could provide some recorded file where you hear clipping, and that I can try rendering on my machine too.
So if I notice a difference between the two resulting files, to figure out why I'm not hearing any clipping at all.
In general I'm against changing anything that will break retrocompatibility, but I suspect that in this instance we are rather exposing a defect that needs to be addressed in a different fashion.
For the moment being I have been unable to reproduce it on Arch Linux with pipewire, or Ubuntu with PulseAudio.
I tried testing it on Windows, but it took several hours to set up and I finally gave up.
To reproduce, just grab GeneralUser v2 and exec:
fluidsynth -g 0.6 -F clipping-test.wav 'GeneralUser_GS_v2.0.0--doc_r2/demo MIDIs/Dance.mid' 'GeneralUser_GS_v2.0.0--doc_r2/GeneralUser GS v2.0.0.sf2'
No, the clipping isn't really audible, yet it's there at around 40s:
I can confirm that the sound card doesn't play a role in case of file rendering.
@derselbst: in case of a change from 0.2 to something new please do not forget to change print_help in fluidsynth.c "Set the master gain [0 < gain < 10, default = 0.2]"
Oh, it's hardcoded - good point!
By using these:
- Presonus Eris 4.5 Studio Monitors + Presonus Sub8 Studio Subwoofer
- Audacity
- Breakout.mid.zip + slayer_dance_2.mid.zip
I got this:
-
Clipping will be reduced, but not eliminated, when using an audio driver different than "file", or a codec different than "oga".
-
A gain of 0.22 will prevent clipping in all circumstances, a gain of 0.26 will cause clipping only in extremely noisy tracks, and a gain of 0.6 will cause clipping in deep bass frequencies that are not audible.
-
A gain of 0.26 or less results in the music not being audible while played through DosBox or Wine. You can only hear the most predominant instruments, and nothing more, even when there is no foreground sounds.
Hence my opinion is:
-
Even if we set the default gain to volumes that don't cause clipping, people will still use louder levels. For the simple fact that the music is just too low to be noticed, which is a worse outcome than clipping that isn't audible.
-
As result lowering the gain won't work, even as a work-around.
-
The only viable solution is to prevent clipping in some other fashion, like automatic gain control.
Even if we set the default gain to volumes that don't cause clipping, people will still use louder levels. For the simple fact that the music is just too low to be noticed, which is a worse outcome than clipping that isn't audible.
The point is that doing so would be a conscious user decision. And if clipping is audible, the user will know how to mitigate it. I consider it more important to set the gain to a default value that will work in all circumstances rather than producing a rendered file that contains potentially clipped audio. I don't think it's worth to haggle about 0.3, 0.26 or 0.22. I'll be resetting it to 0.2 for backward compatibility.
Yet, thanks to both of you @es20490446e and @ReinholdH for looking into this!
The only viable solution is to prevent clipping in some other fashion, like #1302.
Agreed. PR welcome.
Well, the difference between 0.22 and 0.20 won't really matter.
What I see is that:
-
There is no way for anyone to know that the default value is the one that doesn't cause clipping, specially when the gain is so low. People will just assume it's for some other random reason.
-
People will favor a higher gain nowadays, because the music is not audible and the clipping is not audible on a high end system like mine. For instance I will keep a gain of
0.60on exeCute despite of the choice made here.
This is all I have to say. The choice is yours.
I always use a gain of 0.4 or 0.5, and have been recommending people set their gain to 0.5 when using GeneralUser GS as a compromise between volume and clipping. I find the clipping at 0.5 to not be audibly noticeable, and the reality is that MIDI files vary wildly in their overall dynamic output, so I try to find a reasonable middle ground. When rendering to audio, I always use 32-bit floating point which avoids actually clipping the audio—I just need to attenuate and trim the file a bit before exporting to its final format.
Do you notice problems with 0.6?
Do you notice problems with 0.6?
Just more clipping. In the past I always used 0.4, but when testing for recommended values for GeneralUser GS, 0.5 seemed the best compromise for casual MIDI playback. It results in a good volume level, and any clipping isn't really noticeable to the ear, though I'm sure there's some MIDI file out there that will slam all CC7 = 127, all velocity = 127 & a bazillion notes, which will lead to significant clipping. On the other hand, I found many MIDI files that run rather quiet even at 0.5 gain.
One other thought: adding a properly-configured limiter to the end of the audio signal path would be one way to avoid clipping, acknowledging that the dynamic range would be affected by the use of a limiter. As an example of how this would sound, have a listen to the audio renderings of the MIDI files included with GeneralUser GS 2.0, which are in a subfolder of the MIDI files. All of these files were rendered to 32-bit FP WAV using FluidSynth, in some cases amplified a bit, and then a limiter was applied to tame the peaks to -0.5 dB (to allow dynamic headroom for conversion to OGG), allowing the volume of each MIDI file to be enjoyably loud.
I would say that slightly compressing the dynamic range is even desirable, as it allows sounds to be noticeable at not so loud volumes.
In the last months I have been working on an audio system. After plenty of listening sessions what I noticed is that it was better to configure the audio processor to have a subtly compressed dynamic range, rather than a sound that was as deep and natural as real life.
Because a slightly compressed audio allows you to listen to content without disturbing your family and neighbors.
Personally, I wouldn't implement more than a peak limiter, as many people would be averse to messing too much with the dynamic range of the MIDI files (myself included). For good results, a compressor really should be set up differently depending on the type and level of the music playing (this is why you can't really automate the mastering process). A peak limiter, however, could be set to a reasonable default and would have minimal impact on the dynamic range of the music, only serving to prevent clipping in those moments where the sound is too hot to handle.
In some sense, GeneralUser GS uses a different form of "compression", as the bottom dynamic range of most instruments is reduced from the default 96 dB velocity-to-attenuation curve to 70-80 dB instead, allowing for a more controlled dynamic experience than you usually get with General MIDI playback. This also helps offset some of the volume lost due to the lowpass filter used on many instruments at lower velocities (to simulate how most real instruments get mellower when played quietly).
I mean that if the peak limiter generates a slight compression, probably it won't be a major concern.
Thanks for your input guys! I have reverted the default gain to its previous safe value 0.2 .