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 3969

Summary: Distorted MIDI playback with FluidSynth if Windows sample rate set to 192kHz
Product: SDL_mixer Reporter: Fabian Greffrath <fabian+debian>
Component: miscAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: sezeroz
Version: 2.0.2   
Hardware: x86_64   
OS: Windows 10   
Attachments: patch for bug #3969

Description Fabian Greffrath 2017-11-17 21:09:44 UTC
Hi there,

someone has set the sample rate for my sound driver in Windows to 192kHz (which Windows calls "Studio Quality") as depicted in this preferences window (not my own picture):

http://cdn.howto-connect.com/wp-content/uploads/Set-the-bit-rate-as-per-devices-capacity.png

This means that any MIDI file is played back too fast and too high whenever SDL2_mixer with its fluidsynth backend is involved, either in-game or with playmus.exe. Interestingly, the same MIDI file plays back fine with the same soundfont with fluidsynth's own command line frontend.

Well, what happens here? Let's have a look at libfluidsynth's API documentation:

http://www.fluidsynth.org/api/

We find that the synth.sample-rate setting is capped at 96kHz, i.e. half of the Windows driver's fixed sample rate. Now, when Mix_OpenAudio() is used to initialize the mixer API with the desired sample rate of, say, 22050Hz it returns successfully. Mix_QuerySpec() then reveals that the sample rate is actually set to the driver's fixed 192kHz. All is fine so far, but the bad thing is about to happen now. The MIDI file is played back with libfluidsynth's maximum sample rate of 96kHz but mixed by SDL2_mixer with the 196kHz sample rate that was just set. The result is distorted music playback.

So, how could we better deal with this issue? I think, SDL2_mixer should detect that the sample rate is set higher than what libfluidsynth can deal with and either return an error or fall back to an alternative MIDI backend (but print a fat debug message in the latter case).

Thank you!

 - Fabian
Comment 1 Ozkan Sezer 2021-02-06 15:38:55 UTC
Created attachment 4766 [details]
patch for bug #3969

The attached patch against current development tree does the following:

- calls fluid_settings_getnum() to learn the actual samplerate, as set
  by the library, and passes that to SDL_NewAudioStream() as 'src_rate'
  instead of music_spec.freq:  This _should_ fix the original issue as
  reported by Fabian Greffrath.

- frees the audio stream in FLUIDSYNTH_Delete() which, I think has been
  an oversight for some time.

This is compile-tested only: please review and test. The brace-matching
ordeal in FLUIDSYNTH_Load() was a tough one, i.e.:  I could easily have
made a mistake there. ('hg diff -w' would give you a more readable diff
ignoring whitespace changes.)
Comment 2 Ozkan Sezer 2021-02-07 00:11:02 UTC
Patch now run-tested on Linux and push to current hg
as  https://hg.libsdl.org/SDL_mixer/rev/8def6444de8a

Closing as fixed.