Skip to content

Conversation

@vsariola
Copy link
Contributor

The higher quality resampler is enabled with the AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY flag. Without it, a 44100 Hz source played on a 48000 Hz device sounded really bad, especially in the bass frequencies.

More information about the flag: https://learn.microsoft.com/en-us/windows/win32/coreaudio/audclnt-streamflags-xxx-constants

@hajimehoshi
Copy link
Member

I have not expected the case when the source and the context sample rates don't match.

@hajimehoshi
Copy link
Member

And, the current Oto API cannot specify the source's sample rate, so I'm not sure what this PR will solve.

@vsariola
Copy link
Contributor Author

I need to have the context always at 44100 Hz, so I create the context with:

op := oto.NewContextOptions{}
op.SampleRate = 44100
op.ChannelCount = 2
op.Format = oto.FormatFloat32LE
context, readyChan, err := oto.NewContext(&op)

The sound is created by a synthesizer, which runs things like IIR-filters and such, which must be running at a specific frequency; I have no easy way to support multiple sample rates.

This gives me a 44100 Hz context. Now, in the fix to issue #215, the AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM flag was added so that if the underlying WASAPI audio driver is running at 48000 Hz, it still returns 44100 Hz stream and WASAPI automatically does the conversion for you.

The only problem with the fix to #215 was that WASAPI, by default, does the conversion very poorly (probably roughly something like output[i]=input[i*44100/48000]). This kind of brute-force conversion results in predictable buzz, related to the fact that periodically a sample is doubled. There are better ways to do the up conversion, but they are computationally slightly more costly: https://en.wikipedia.org/wiki/Sample-rate_conversion

AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY requests WASAPI to do better quality sample-rate conversion. As per Microsoft API documentation:

"When used with AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM, a sample rate converter with better quality than the default conversion but with a higher performance cost is used. This should be used if the audio is ultimately intended to be heard by humans as opposed to other scenarios such as pumping silence or populating a meter."

So what Microsoft is saying that if this stream is going to be heard by humans, AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY should be always together with AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM.

@hajimehoshi
Copy link
Member

Thank you for elaborating. LGTM!

The higher quality resampler is enabled with the
AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY flag. Without it, a 44100 Hz
stream played on a 48000 Hz device sounded really bad, especially in the
bass frequencies.
@hajimehoshi hajimehoshi merged commit bae718d into ebitengine:main Jan 19, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants