I had a program crash in Wine today and discovered that it was because the computer was a virtual machine with no audio hardware and FAudio does not handle that situation gracefully. Here is a small test program that behaves similarly to the program I was running. It runs fine on Windows if compiled to use XAudio instead of FAudio.
Test program
/*
GetDeviceDetails-test.c
Copyright 2024 Alex Henrie
This work is marked with CC0 1.0. To view a copy of this license, visit
https://creativecommons.org/publicdomain/zero/1.0/
Testing on Wine
---------------
Compile FAudio with:
mkdir build
cd build
i686-w64-mingw32-cmake -DPLATFORM_WIN32=1 ..
make
Compile the test with:
i686-w64-mingw32-cc GetDeviceDetails-test.c -Iinclude -Lbuild -lFAudio.dll -o GetDeviceDetails-test.exe
Run the test with:
cp build/FAudio.dll .
cp /usr/i686-w64-mingw32/bin/libssp-0.dll .
WINEDLLOVERRIDES=winepulse.drv,winealsa.drv=n wine GetDeviceDetails-test.exe
Testing on Windows
------------------
Compile the test with:
i686-w64-mingw32-cc GetDeviceDetails-test.c -Iinclude -DUSE_XAUDIO -lole32 -o GetDeviceDetails-test.exe
Run the test with:
GetDeviceDetails-test.exe
*/
#include <FAudio.h>
#include <stdio.h>
#ifdef USE_XAUDIO
#define COBJMACROS
#include <initguid.h>
#include <xaudio2.h>
#define FAudio IXAudio27
#define FAudio_Initialize IXAudio27_Initialize
#define FAudioDeviceDetails XAUDIO2_DEVICE_DETAILS
#define FAudio_GetDeviceCount IXAudio27_GetDeviceCount
#define FAudio_GetDeviceDetails IXAudio27_GetDeviceDetails
#endif
int main()
{
uint32_t hr;
FAudio *fa;
uint32_t device_count;
FAudioDeviceDetails device_details;
#ifndef USE_XAUDIO
hr = FAudioCreate((void*)&fa, 0, FAUDIO_DEFAULT_PROCESSOR);
printf("AudioCreate returned 0x%x\n", hr);
#else
CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_XAudio27, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio27, (void**)&fa);
printf("CoCreateInstance returned 0x%x\n", hr);
hr = IXAudio27_Initialize(fa, 0, XAUDIO2_ANY_PROCESSOR);
printf("Initialize returned 0x%x\n", hr);
#endif
hr = FAudio_GetDeviceCount(fa, &device_count);
printf("GetDeviceCount returned 0x%x, device_count=%d\n", hr, device_count);
hr = FAudio_GetDeviceDetails(fa, 0, &device_details);
printf("GetDeviceDetails returned 0x%x\n", hr);
return 0;
}
Expected output
AudioCreate returned 0x0
GetDeviceCount returned 0x0, device_count=0
GetDeviceDetails returned 0x88960001
Actual output
AudioCreate returned 0x0
GetDeviceCount returned 0x0, device_count=0
0024:err:msvcrt:_wassert (L"!FAILED(hr) && \"Failed to get default audio endpoint!\"",L"/home/alex/workspace/faudio/src/FAudio_platform_win32.c",454)
Assertion failed: !FAILED(hr) && "Failed to get default audio endpoint!", file /home/alex/workspace/faudio/src/FAudio_platform_win32.c, line 454
I had a program crash in Wine today and discovered that it was because the computer was a virtual machine with no audio hardware and FAudio does not handle that situation gracefully. Here is a small test program that behaves similarly to the program I was running. It runs fine on Windows if compiled to use XAudio instead of FAudio.
Test program
Expected output
Actual output