Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

voice with high filter Q killed too early, causing audible click #1427

Open
mrbumpy409 opened this issue Nov 11, 2024 · 3 comments
Open

voice with high filter Q killed too early, causing audible click #1427

mrbumpy409 opened this issue Nov 11, 2024 · 3 comments
Labels

Comments

@mrbumpy409
Copy link

FluidSynth version

Affects 2.3 (and presumably older) and 2.4 versions of FluidSynth including current master and iir-tests branches.

Describe the bug

By default FluidSynth cuts off a voice after the volume envelope release has reached -96 dB (as I recall... I'm going off of memory here). Normally the volume envelope being at -96 dB would be an inaudible cutoff, but when high filter Q is used, the filter hasn't stopped "ringing" at this point, and so the still audible sound is abruptly cut off, resulting in a click.

Steps to reproduce

  1. Download and extract the following zip file:
    high_Q_note_cutoff_test.zip
  2. Load the .sf2 file into FluidSynth and play the .mid file. I have also included an audio file fluidsynth_iir-tests.flac showing the result of this test using FluidSynth's current iir-tests branch.

Current behavior

The voice cuts off while the filter is still resonating, causing an audible click. You can see this quite clearly by viewing the waveform in Audacity:
image

Expected behavior

The voice shouldn't be cut off until the filter output has also reached -96 dB.

Additional context

Related to bug #1415.

@spessasus
Copy link
Contributor

This is strange. It seems that the filter is not being affected by the final gain amplifier and instead is being sent directly to the final output.

According to Section 9.1.8 of the sf2 specification:
image

The gain should come after the filtered output, so the ringing should ramp to -96dB too. This happens when playing the Whistlewind in Polyphone.

@derselbst
Copy link
Member

Thanks again for the report. I didn't found time to look into this, but here are two thoughts:

By default FluidSynth cuts off a voice after the volume envelope release has reached -96 dB (as I recall... I'm going off of memory here)

We wanted to in #319, but it didn't happen. On the other hand, there is that logic around "noise floor" that might explain the effect observed here:

fluid_real_t amplitude_that_reaches_noise_floor;

It seems that the filter is not being affected by the final gain amplifier and instead is being sent directly to the final output.

Yes, because the SF spec asks for a gain compensation dependent on Q, which we currently do here:

/* SF 2.01 page 59:
*
* The SoundFont specs ask for a gain reduction equal to half the
* height of the resonance peak (Q). For example, for a 10 dB
* resonance peak, the gain is reduced by 5 dB. This is done by
* multiplying the total gain with sqrt(1/Q). `Sqrt' divides dB
* by 2 (100 lin = 40 dB, 10 lin = 20 dB, 3.16 lin = 10 dB etc)
* The gain is later factored into the 'b' coefficients
* (numerator of the filter equation). This gain factor depends
* only on Q, so this is the right place to calculate it.
*/
iir_filter->filter_gain /= FLUID_SQRT(q);

But it's amount is only half of Q's peaks.

I need to investigate how both are related to explain the observed effect here.

@spessasus
Copy link
Contributor

spessasus commented Nov 16, 2024

Yes, because the SF spec asks for a gain compensation dependent on Q, which we currently do here

That's an additional gain. it doesn't mention anywhere that only the Q Gain should be applied to the filter, but according to the diagram, it shows that the filter is affected both by Q and volEnv. It honestly makes sense and doing that does not cause any clicks since the ringing gets attenuated too.

Not to mention that:

9.1.4 Final Gain Amplifier
The final gain amplifier is a multiplier on the filter output, which is controlled by an initial gain in dB. This is added to the volume envelope. Additional modulation can also be added. The gain is always specified in dB.

It does explicitly state that the final gain amplifier is the Q Gain added to the volEnv gain from the filtered input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants