We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2904

Summary: Mix_FadeOutGroup() : "stair effect" fadeout
Product: SDL_mixer Reporter: JosBas <eh.ouais>
Component: miscAssignee: Ryan C. Gordon <icculus>
Status: ASSIGNED --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: philipp.wiesemann, yv.sharma
Version: unspecified   
Hardware: All   
OS: All   

Description JosBas 2015-03-11 14:41:51 UTC
I've noticed this with headphones, and now it is confirmed, as I recorded the stereo output.

Mix_FadeOutGroup() is not a normal linear fadefout, but a step function ("staircase" function): see http://gget.it/e46s3stu/5.jpg

Input: http://gget.it/uk2oi63z/sine1.wav

Output with 200ms fadeout: http://gget.it/zjh61iz2/sine1_fadeout_with_pygame.wav
(You'll notice stair effect.)


Notes:
*Tested on both Win7/PC and RaspberryPi.
* The "width" of the constant pieces of the staircase function is exactly the audio buffer size (1024 samples in my example).
Comment 1 Ryan C. Gordon 2015-03-11 18:46:35 UTC
This happens because we change the channel volume during fading once per callback to feed the audio device, so you get stairs like that.

At the moment, it makes no attempt to interpolate the fade between samples in a single callback, so you get a more bigger staircase the larger your sample size.

This could be fixed without changing the API, but there aren't plans to do so at the moment (patches are welcome, though!). I'll leave this bug open for now, though.

--ryan.
Comment 2 JosBas 2015-03-11 18:56:47 UTC
Yes, the problem is that the volume change is just a "multiplication by a constant number" for each call of the callback. 
If B[i] is the current buffer (0<=i<=n), 
currently this is what happens:
Out[i] = B[i] * k       , and  k  will decrease only for next callback call.

Instead we could multiply the buffer by a linear function :

Out[i] = B[i] * L[i]     where L[i] is a linear decreasing function.

@RyanC.Gordon, can you point me in which file exactly this code happens (I don't know SDL source at all), I can maybe try to write a patch.

Thanks.
Comment 3 Philipp Wiesemann 2015-03-14 19:18:26 UTC
In SDL_mixer source it is "mixer.c" which uses SDL_MixAudio() from SDL.

In SDL source it is "src/audio/SDL_audio.c" for SDL_MixAudio() and "src/audio/SDL_mixer.c" for SDL_MixAudioFormat().

SDL_MixAudioFormat() applies the volume and would need to be copied or changed.
Comment 4 Yash 2015-08-10 08:31:53 UTC
Hi JosBas

You found a solution for this ?
Comment 5 Sam Lantinga 2017-10-21 19:24:11 UTC
Yeah, the fading should really be an interpolated volume application.