Skip to content

Commit bf03728

Browse files
committed
wasapi: workaround that AudioClientProperties->Options not being available in old SDKs
Closes: #15641.
1 parent 508450e commit bf03728

3 files changed

Lines changed: 34 additions & 10 deletions

File tree

src/audio/wasapi/SDL_wasapi.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ static const IID SDL_IID_IAudioClient3 = { 0x7ed4ee07, 0x8e67, 0x4cd4, { 0x8c, 0
6464
static bool immdevice_initialized = false;
6565
static bool supports_recording_on_playback_devices = false;
6666

67+
#ifdef __IAudioClient2_INTERFACE_DEFINED__
68+
#define SDL_AUDCLNT_STREAMOPTIONS_RAW 0x1
69+
typedef union SDL_AudioClientProperties {
70+
AudioClientProperties a;
71+
struct _SDL_AudioClientProperties {
72+
UINT32 cbSize;
73+
BOOL bIsOffload;
74+
AUDIO_STREAM_CATEGORY eCategory;
75+
int Options; // AUDCLNT_STREAMOPTIONS
76+
} s;
77+
} SDL_AudioClientProperties;
78+
#endif //
79+
6780
// WASAPI is _really_ particular about various things happening on the same thread, for COM and such,
6881
// so we proxy various stuff to a single background thread to manage.
6982

@@ -741,36 +754,39 @@ static bool mgmtthrtask_PrepDevice(void *userdata)
741754
IAudioClient2 *client2 = NULL;
742755
ret = IAudioClient_QueryInterface(client, &SDL_IID_IAudioClient2, (void **)&client2);
743756
if (SUCCEEDED(ret)) {
744-
AudioClientProperties audioProps;
757+
SDL_AudioClientProperties audioProps;
745758

746759
SDL_zero(audioProps);
747-
audioProps.cbSize = sizeof(audioProps);
760+
audioProps.a.cbSize = sizeof(audioProps);
748761

749762
// Setting AudioCategory_GameChat breaks audio on several devices, including Behringer U-PHORIA UM2 and RODE NT-USB Mini.
750763
// We'll disable this for now until we understand more about what's happening.
751764
#if 0
752765
const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_ROLE);
753766
if (hint && *hint) {
754767
if (SDL_strcasecmp(hint, "Communications") == 0) {
755-
audioProps.eCategory = AudioCategory_Communications;
768+
audioProps.a.eCategory = AudioCategory_Communications;
756769
} else if (SDL_strcasecmp(hint, "Game") == 0) {
757770
// We'll add support for GameEffects as distinct from GameMedia later when we add stream roles
758-
audioProps.eCategory = AudioCategory_GameEffects;
771+
audioProps.a.eCategory = AudioCategory_GameEffects;
759772
} else if (SDL_strcasecmp(hint, "GameChat") == 0) {
760-
audioProps.eCategory = AudioCategory_GameChat;
773+
audioProps.a.eCategory = AudioCategory_GameChat;
761774
} else if (SDL_strcasecmp(hint, "Movie") == 0) {
762-
audioProps.eCategory = AudioCategory_Movie;
775+
audioProps.a.eCategory = AudioCategory_Movie;
763776
} else if (SDL_strcasecmp(hint, "Media") == 0) {
764-
audioProps.eCategory = AudioCategory_Media;
777+
audioProps.a.eCategory = AudioCategory_Media;
765778
}
766779
}
767780
#endif
768781

769-
if (SDL_GetHintBoolean(SDL_HINT_AUDIO_DEVICE_RAW_STREAM, false)) {
770-
audioProps.Options = AUDCLNT_STREAMOPTIONS_RAW;
782+
if (WIN_IsWindows81OrGreater() &&
783+
SDL_GetHintBoolean(SDL_HINT_AUDIO_DEVICE_RAW_STREAM, false)) {
784+
audioProps.s.Options = SDL_AUDCLNT_STREAMOPTIONS_RAW;
785+
} else {
786+
audioProps.a.cbSize = sizeof (AudioClientProperties);
771787
}
772788

773-
ret = IAudioClient2_SetClientProperties(client2, &audioProps);
789+
ret = IAudioClient2_SetClientProperties(client2, (AudioClientProperties *)&audioProps);
774790
if (FAILED(ret)) {
775791
// This isn't fatal, let's log it instead of failing
776792
SDL_LogWarn(SDL_LOG_CATEGORY_AUDIO, "IAudioClient2_SetClientProperties failed: 0x%" SDL_PRIxSLONG, ret);

src/core/windows/SDL_windows.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,11 @@ BOOL WIN_IsWindows8OrGreater(void)
374374
CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0));
375375
}
376376

377+
BOOL WIN_IsWindows81OrGreater(void)
378+
{
379+
CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0));
380+
}
381+
377382
BOOL WIN_IsWindows11OrGreater(void)
378383
{
379384
return IsWindowsBuildVersionAtLeast(22000);

src/core/windows/SDL_windows.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ extern BOOL WIN_IsWindows7OrGreater(void);
193193
// Returns true if we're running on Windows 8 and newer
194194
extern BOOL WIN_IsWindows8OrGreater(void);
195195

196+
// Returns true if we're running on Windows 8.1 and newer
197+
extern BOOL WIN_IsWindows81OrGreater(void);
198+
196199
// Returns true if we're running on Windows 11 and newer
197200
extern BOOL WIN_IsWindows11OrGreater(void);
198201

0 commit comments

Comments
 (0)