Detect Wine and disable unsupported IAudioClient3 interface.

This commit is contained in:
bruvzg 2022-10-13 22:49:24 +03:00
parent 926429392a
commit 88adb6513e
No known key found for this signature in database
GPG key ID: 7960FCF39844EC38
2 changed files with 25 additions and 0 deletions

View file

@ -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) {

View file

@ -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);