From c7e43665300913a6df0beabffc4dab35240ae8a5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 21 Feb 2018 21:34:06 -0500 Subject: [PATCH] wasapi: let Windows do the resampling for us if possible. --- src/audio/wasapi/SDL_wasapi.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c index 65445dabe..80795257d 100644 --- a/src/audio/wasapi/SDL_wasapi.c +++ b/src/audio/wasapi/SDL_wasapi.c @@ -527,6 +527,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) SDL_AudioFormat wasapi_format = 0; SDL_bool valid_format = SDL_FALSE; HRESULT ret = S_OK; + DWORD streamflags = 0; SDL_assert(client != NULL); @@ -548,9 +549,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) SDL_assert(waveformat != NULL); this->hidden->waveformat = waveformat; - /* WASAPI will not do any conversion on our behalf. Force channels and sample rate. */ this->spec.channels = (Uint8) waveformat->nChannels; - this->spec.freq = waveformat->nSamplesPerSec; /* Make sure we have a valid format that we can convert to whatever WASAPI wants. */ if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) { @@ -588,7 +587,21 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret); } - ret = IAudioClient_Initialize(client, sharemode, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, duration, sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : duration, waveformat, NULL); + /* favor WASAPI's resampler over our own, in Win7+. */ + if (this->spec.freq != waveformat->nSamplesPerSec) { + /* RATEADJUST only works with output devices in share mode, and is available in Win7 and later.*/ + if (WIN_IsWindows7OrGreater() && !this->iscapture && (sharemode == AUDCLNT_SHAREMODE_SHARED)) { + streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST; + waveformat->nSamplesPerSec = this->spec.freq; + waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8); + } + else { + this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in. */ + } + } + + streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK; + ret = IAudioClient_Initialize(client, sharemode, streamflags, duration, sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : duration, waveformat, NULL); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't initialize audio client", ret); }