FNA-XNA / FAudio

FAudio - Accuracy-focused XAudio reimplementation for open platforms
https://fna-xna.github.io/
Other
534 stars 72 forks source link

Assertion failed: !FAILED(hr) && "Failed to get default audio endpoint!" when there are no audio devices #347

Closed alexhenrie closed 1 month ago

alexhenrie commented 1 month ago

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