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

Rapidly changing/extreme panning values result in audible clicks/pops #768

Closed
dwhinham opened this issue Feb 4, 2021 · 6 comments
Closed
Labels

Comments

@dwhinham
Copy link

dwhinham commented Feb 4, 2021

FluidSynth version

2.1.7

Describe the bug

Some MIDI soundtracks change the panning values to extreme values (i.e hard-left to hard-right) rapidly while notes are playing for effect. A good example is the bassline from the Descent Level 1 music (about 30 seconds into the song - examples attached).

With FluidSynth, this can result in audible clicks/pops. Tested mainly with GeneralUser GS, but other SoundFonts exhibit this behaviour too.

Expected behavior

The audio should be panned without audible artifacts.

Steps to reproduce

  1. Start FluidSynth with any GM/GS SoundFont (GeneralUser GS was used for testing).
  2. Play the attached MIDI (descent_pan_bass_only.mid) and notice clicks/pop.

Additional context

I'm guessing that the distortion is because the panning is instantaneous, maybe similar to the "click" you get when you truncate a sample. Maybe the behaviour could be mitigated by applying a very fast envelope to smoothly fade out the transition?

The archive attached below archive contains the following files:

  • D1-Level 1.mid - Complete Level 1 MIDI song from Descent 1. Panned bassline that triggers the behaviour starts at ~30 seconds into the song.
  • descent_pan_bass_only.mid - Just the panned bassline on its own.
  • descent_pan_gugs.wav - Recording of the above from FluidSynth using GeneralUser GS.
  • descent_pan_mu2000.wav - Recording of the above from a Yamaha MU2000, just for comparison.

descent.zip

@dwhinham dwhinham added the bug label Feb 4, 2021
@derselbst
Copy link
Member

I can confirm this. Looking at only one channel, we can see the clicks in a spectrogram:

left

When mixing both channels, the clicks average each other out:

mixed

Disabling panning also makes the clicks go away.

Looking at one of those clicks in more detail, we can see that the waveform makes a jump:

jump

This can be reproduced with fluidsynth 1.1.6 as well. We already interpolate the sample's amplitude (_fluid_rvoice_dsp_t::amp) between FLUID_BUFSIZE samples in a linear way:

/* Volume increment to go from voice->amp to target_amp in FLUID_BUFSIZE steps */
voice->dsp.amp_incr = (target_amp - voice->dsp.amp) / FLUID_BUFSIZE;

This is then considered, when the sample is actually rendered, see here (nearest neighbor interpolation for simplicity, 4th order cubic is default which you can find more to the bottom):

dsp_amp += dsp_amp_incr;

However, here is a different amplitude, namely _fluid_rvoice_buffers_t::amp. This one tells us the amplitude by which we want to mix that mono sample from above into the final left- and right-buffers. This amp is set here

buffers->bufs[bufnum].amp = value;

and later used here during mixing:

fluid_real_t amp = buffers->bufs[i].amp;

As we can see it is used without interpolation. Adding a simple linear interpolation between FLUID_BUFSIZE samples should solve this problem. However, we must pay attention: The loop in which it it used is currently vectorized by the compiler and I would like to keep it that way. So a simple amp+=incr; won't do it.

I will probably come back to this in a few days.

@dwhinham
Copy link
Author

dwhinham commented Feb 6, 2021

Thanks for the detailed investigation and confirming the issue, I appreciate the need to maintain vectorization - my project uses FluidSynth in a baremetal ARM environment and performance is important.

I look forward to a possible solution when you have some free time. 🙂

@derselbst
Copy link
Member

I just found some time, so here we go. Feel free to test: issue768

@dwhinham
Copy link
Author

dwhinham commented Feb 6, 2021

Thanks for this!

I gave it a shot - the clicks are definitely gone, which is great, although I think I'm hearing something new that wasn't there before - it's as if there's a chorus/phase shift effect being applied.

I've attached a recording, with the test phrase played through 2.1.7 and then through issue768.

pan_fix1.zip

Do you hear it? What do you think?


Scratch that, I was comparing the binary release .exe with issue768. I've now compiled my own 2.1.7 and compared it with issue768 - the chorus appears on both, so I think we're good!

I must have some different defaults being applied somewhere - apologies!

@derselbst
Copy link
Member

Thanks, glad to hear that it works fine!

FYI: This fix will be part of fluidsynth 2.1.8, not sure when it will be released though.

@dwhinham
Copy link
Author

dwhinham commented Feb 7, 2021

Thankyou so much for the quick fix!

dwhinham added a commit to dwhinham/mt32-pi that referenced this issue Feb 7, 2021
Temporary fix for FluidSynth/fluidsynth#768 until FluidSynth v2.1.8 is
released.
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

2 participants