Quick answer: pygame.mixer.music.fadeout(500) cuts track instantly on Windows? The mixer’s buffer is bigger than 500ms — the fade resolution rounds to one buffer.
A scene transition fades music over 200ms; on Windows the music snaps off. SDL_mixer on Windows defaults to a large buffer to handle high-latency drivers.
Buffer Quantization
Mixer applies the fade per buffer. If buffer is 1024 samples at 44100Hz, that’s ~23ms per buffer. A 200ms fade has ~8 steps — fine. But on some Windows drivers, default buffer is 2048+ samples and durations get coarser.
Lower the Buffer
pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.mixer.init()Smaller buffer = finer fade resolution + lower latency. Trade-off: more CPU and risk of underruns on weak hardware.
Manual Fade
Drive volume from 1.0 to 0.0 in _process with pygame.mixer.music.set_volume(). Frame-rate-bound but smooth at typical game frame rates.
Per-Channel Fades
For SFX, use Channel.fadeout(). Channels use the same mixer buffer but typically have smaller effective fade times because of how SDL_mixer schedules.
Verifying
Fades sound smooth on Windows, Mac, Linux. No audible click or instant cut.
“Buffer size limits fade resolution. Lower buffer or fade manually.”
Set mixer pre-init globally at startup — once set up correctly, all subsequent fades behave smoothly without per-call work.