From 88adb6513ea5c40436709bbf485823175cd73d22 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 13 Oct 2022 22:49:24 +0300 Subject: [PATCH] Detect Wine and disable unsupported IAudioClient3 interface. --- drivers/wasapi/audio_driver_wasapi.cpp | 23 +++++++++++++++++++++++ drivers/wasapi/audio_driver_wasapi.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index fb90b776cfc0..d6636606d225 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -127,6 +127,11 @@ static bool default_capture_device_changed = false; #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" #endif +#if defined(__GNUC__) +// Workaround GCC warning from -Wcast-function-type. +#define GetProcAddress (void *)GetProcAddress +#endif + class CMMNotificationClient : public IMMNotificationClient { LONG _cRef = 1; IMMDeviceEnumerator *_pEnumerator = nullptr; @@ -201,6 +206,20 @@ public: static CMMNotificationClient notif_client; +typedef const char *(CDECL *PWineGetVersionPtr)(void); + +bool AudioDriverWASAPI::is_running_on_wine() { + HMODULE nt_lib = LoadLibraryW(L"ntdll.dll"); + if (!nt_lib) { + return false; + } + + PWineGetVersionPtr wine_get_version = (PWineGetVersionPtr)GetProcAddress(nt_lib, "wine_get_version"); + FreeLibrary(nt_lib); + + return (bool)wine_get_version; +} + Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool reinit) { WAVEFORMATEX *pwfex; IMMDeviceEnumerator *enumerator = nullptr; @@ -285,6 +304,10 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c } using_audio_client_3 = !p_capture; // IID_IAudioClient3 is only used for adjustable output latency (not input) + if (using_audio_client_3 && is_running_on_wine()) { + using_audio_client_3 = false; + print_verbose("WASAPI: Wine detected, falling back to IAudioClient interface"); + } if (using_audio_client_3) { hr = device->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client); if (hr != S_OK) { diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index c30a54c042d7..e9f2794e971d 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -79,6 +79,8 @@ class AudioDriverWASAPI : public AudioDriver { SafeFlag exit_thread; + static bool is_running_on_wine(); + static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample); static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i); static void thread_func(void *p_udata);