audio: Port WASAPI to WinRT, remove XAudio2 backend.
authorRyan C. Gordon <icculus@icculus.org>
Wed, 06 Dec 2017 12:24:32 -0500
changeset 1172627d08f1aab80
parent 11725 5dc2ef223b08
child 11727 49f8fb4f6ce2
audio: Port WASAPI to WinRT, remove XAudio2 backend.

XAudio2 doesn't have capture support, so WASAPI was to replace it; the holdout
was WinRT, which still needed it as its primary audio target until the WASAPI
code code be made to work.

The support matrix now looks like:

WinXP: directsound by default, winmm as a fallback for buggy drivers.
Vista+: WASAPI (directsound and winmm as fallbacks for debugging).
WinRT: WASAPI
CMakeLists.txt
VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj
VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters
VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj
VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters
VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj
VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters
VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj
VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters
VisualC/SDL/SDL.vcxproj
VisualC/SDL/SDL.vcxproj.filters
configure.in
docs/README-winrt.md
include/SDL_config.h.cmake
include/SDL_config.h.in
include/SDL_config_windows.h
include/SDL_config_winrt.h
src/SDL_internal.h
src/audio/SDL_audio.c
src/audio/SDL_sysaudio.h
src/audio/wasapi/SDL_wasapi.c
src/audio/wasapi/SDL_wasapi.h
src/audio/wasapi/SDL_wasapi_win32.c
src/audio/wasapi/SDL_wasapi_winrt.cpp
src/audio/xaudio2/SDL_xaudio2.c
src/audio/xaudio2/SDL_xaudio2.h
src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
src/audio/xaudio2/SDL_xaudio2_winrthelpers.h
     1.1 --- a/CMakeLists.txt	Wed Dec 06 13:48:51 2017 -0500
     1.2 +++ b/CMakeLists.txt	Wed Dec 06 12:24:32 2017 -0500
     1.3 @@ -1180,11 +1180,10 @@
     1.4      check_include_file(ddraw.h HAVE_DDRAW_H)
     1.5      check_include_file(dsound.h HAVE_DSOUND_H)
     1.6      check_include_file(dinput.h HAVE_DINPUT_H)
     1.7 -    check_include_file(xaudio2.h HAVE_XAUDIO2_H)
     1.8      check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
     1.9      check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
    1.10      check_include_file(dxgi.h HAVE_DXGI_H)
    1.11 -    if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H OR HAVE_XAUDIO2_H)
    1.12 +    if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H)
    1.13        set(HAVE_DIRECTX TRUE)
    1.14        if(NOT CMAKE_COMPILER_IS_MINGW AND NOT USE_WINSDK_DIRECTX)
    1.15        # TODO: change $ENV{DXSDL_DIR} to get the path from the include checks
    1.16 @@ -1207,12 +1206,6 @@
    1.17        set(SOURCE_FILES ${SOURCE_FILES} ${DSOUND_AUDIO_SOURCES})
    1.18      endif()
    1.19  
    1.20 -    if(HAVE_XAUDIO2_H)
    1.21 -      set(SDL_AUDIO_DRIVER_XAUDIO2 1)
    1.22 -      file(GLOB XAUDIO2_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/xaudio2/*.c)
    1.23 -      set(SOURCE_FILES ${SOURCE_FILES} ${XAUDIO2_AUDIO_SOURCES})
    1.24 -    endif()
    1.25 -
    1.26      if(HAVE_AUDIOCLIENT_H AND HAVE_MMDEVICEAPI_H)
    1.27        set(SDL_AUDIO_DRIVER_WASAPI 1)
    1.28        file(GLOB WASAPI_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/wasapi/*.c)
     2.1 --- a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj	Wed Dec 06 13:48:51 2017 -0500
     2.2 +++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj	Wed Dec 06 12:24:32 2017 -0500
     2.3 @@ -84,8 +84,7 @@
     2.4      <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
     2.5      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
     2.6      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
     2.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2.h" />
     2.8 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
     2.9 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
    2.10      <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
    2.11      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    2.12      <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    2.13 @@ -175,8 +174,8 @@
    2.14      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
    2.15      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
    2.16      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
    2.17 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
    2.18 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    2.19 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
    2.20 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    2.21        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
    2.22        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    2.23        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
     3.1 --- a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters	Wed Dec 06 13:48:51 2017 -0500
     3.2 +++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters	Wed Dec 06 12:24:32 2017 -0500
     3.3 @@ -183,9 +183,6 @@
     3.4      <ClInclude Include="..\..\src\audio\SDL_wave.h">
     3.5        <Filter>Source Files</Filter>
     3.6      </ClInclude>
     3.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
     3.8 -      <Filter>Source Files</Filter>
     3.9 -    </ClInclude>
    3.10      <ClInclude Include="..\..\src\core\windows\SDL_directx.h">
    3.11        <Filter>Source Files</Filter>
    3.12      </ClInclude>
    3.13 @@ -390,7 +387,7 @@
    3.14      <ClInclude Include="..\..\src\video\winrt\SDL_winrtvideo_cpp.h">
    3.15        <Filter>Source Files</Filter>
    3.16      </ClInclude>
    3.17 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2.h">
    3.18 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h">
    3.19        <Filter>Source Files</Filter>
    3.20      </ClInclude>
    3.21      <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
    3.22 @@ -449,7 +446,7 @@
    3.23      <ClCompile Include="..\..\src\audio\SDL_wave.c">
    3.24        <Filter>Source Files</Filter>
    3.25      </ClCompile>
    3.26 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    3.27 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    3.28        <Filter>Source Files</Filter>
    3.29      </ClCompile>
    3.30      <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
    3.31 @@ -722,7 +719,7 @@
    3.32      <ClCompile Include="..\..\src\video\winrt\SDL_winrtvideo.cpp">
    3.33        <Filter>Source Files</Filter>
    3.34      </ClCompile>
    3.35 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
    3.36 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c">
    3.37        <Filter>Source Files</Filter>
    3.38      </ClCompile>
    3.39      <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
     4.1 --- a/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj	Wed Dec 06 13:48:51 2017 -0500
     4.2 +++ b/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj	Wed Dec 06 12:24:32 2017 -0500
     4.3 @@ -91,7 +91,7 @@
     4.4        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
     4.5        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
     4.6        <GenerateDebugInformation>true</GenerateDebugInformation>
     4.7 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
     4.8 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
     4.9      </Link>
    4.10    </ItemDefinitionGroup>
    4.11    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    4.12 @@ -108,7 +108,7 @@
    4.13        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    4.14        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    4.15        <GenerateDebugInformation>true</GenerateDebugInformation>
    4.16 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
    4.17 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
    4.18      </Link>
    4.19    </ItemDefinitionGroup>
    4.20    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
    4.21 @@ -126,7 +126,7 @@
    4.22        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    4.23        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    4.24        <GenerateDebugInformation>true</GenerateDebugInformation>
    4.25 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
    4.26 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
    4.27      </Link>
    4.28    </ItemDefinitionGroup>
    4.29    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
    4.30 @@ -143,7 +143,7 @@
    4.31        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    4.32        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    4.33        <GenerateDebugInformation>true</GenerateDebugInformation>
    4.34 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
    4.35 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
    4.36      </Link>
    4.37    </ItemDefinitionGroup>
    4.38    <ItemGroup>
    4.39 @@ -211,7 +211,7 @@
    4.40      <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    4.41      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    4.42      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
    4.43 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
    4.44 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
    4.45      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    4.46      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h" />
    4.47      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.h" />
    4.48 @@ -292,8 +292,8 @@
    4.49      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
    4.50      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
    4.51      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
    4.52 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
    4.53 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    4.54 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
    4.55 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    4.56        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    4.57        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
    4.58        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
     5.1 --- a/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters	Wed Dec 06 13:48:51 2017 -0500
     5.2 +++ b/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters	Wed Dec 06 12:24:32 2017 -0500
     5.3 @@ -168,7 +168,7 @@
     5.4      <ClInclude Include="..\..\src\audio\SDL_wave.h">
     5.5        <Filter>Source Files</Filter>
     5.6      </ClInclude>
     5.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
     5.8 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h">
     5.9        <Filter>Source Files</Filter>
    5.10      </ClInclude>
    5.11      <ClInclude Include="..\..\src\core\windows\SDL_windows.h">
    5.12 @@ -413,10 +413,10 @@
    5.13      <ClCompile Include="..\..\src\audio\SDL_wave.c">
    5.14        <Filter>Source Files</Filter>
    5.15      </ClCompile>
    5.16 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
    5.17 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c">
    5.18        <Filter>Source Files</Filter>
    5.19      </ClCompile>
    5.20 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    5.21 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    5.22        <Filter>Source Files</Filter>
    5.23      </ClCompile>
    5.24      <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
     6.1 --- a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj	Wed Dec 06 13:48:51 2017 -0500
     6.2 +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj	Wed Dec 06 12:24:32 2017 -0500
     6.3 @@ -76,7 +76,7 @@
     6.4      <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
     6.5      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
     6.6      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
     6.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
     6.8 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
     6.9      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    6.10      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_common.h" />
    6.11      <ClInclude Include="..\..\src\core\winrt\SDL_winrtapp_direct3d.h" />
    6.12 @@ -158,8 +158,8 @@
    6.13      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
    6.14      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
    6.15      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
    6.16 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
    6.17 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    6.18 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
    6.19 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    6.20        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
    6.21        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    6.22        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
    6.23 @@ -407,7 +407,7 @@
    6.24        <SubSystem>Console</SubSystem>
    6.25        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    6.26        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    6.27 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.28 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.29      </Link>
    6.30    </ItemDefinitionGroup>
    6.31    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    6.32 @@ -421,7 +421,7 @@
    6.33        <SubSystem>Console</SubSystem>
    6.34        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    6.35        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    6.36 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.37 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.38      </Link>
    6.39    </ItemDefinitionGroup>
    6.40    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
    6.41 @@ -435,7 +435,7 @@
    6.42        <SubSystem>Console</SubSystem>
    6.43        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    6.44        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    6.45 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.46 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.47      </Link>
    6.48    </ItemDefinitionGroup>
    6.49    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
    6.50 @@ -449,7 +449,7 @@
    6.51        <SubSystem>Console</SubSystem>
    6.52        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    6.53        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    6.54 -      <AdditionalDependencies>DXGI.lib;d3d11.lib;xaudio2.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.55 +      <AdditionalDependencies>DXGI.lib;d3d11.lib;%(AdditionalDependencies)</AdditionalDependencies>
    6.56      </Link>
    6.57    </ItemDefinitionGroup>
    6.58    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
     7.1 --- a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters	Wed Dec 06 13:48:51 2017 -0500
     7.2 +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters	Wed Dec 06 12:24:32 2017 -0500
     7.3 @@ -183,7 +183,7 @@
     7.4      <ClInclude Include="..\..\src\audio\SDL_wave.h">
     7.5        <Filter>Source Files</Filter>
     7.6      </ClInclude>
     7.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
     7.8 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h">
     7.9        <Filter>Source Files</Filter>
    7.10      </ClInclude>
    7.11      <ClInclude Include="..\..\src\core\windows\SDL_windows.h">
    7.12 @@ -420,10 +420,10 @@
    7.13      <ClCompile Include="..\..\src\audio\SDL_wave.c">
    7.14        <Filter>Source Files</Filter>
    7.15      </ClCompile>
    7.16 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
    7.17 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c">
    7.18        <Filter>Source Files</Filter>
    7.19      </ClCompile>
    7.20 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    7.21 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    7.22        <Filter>Source Files</Filter>
    7.23      </ClCompile>
    7.24      <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
     8.1 --- a/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj	Wed Dec 06 13:48:51 2017 -0500
     8.2 +++ b/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj	Wed Dec 06 12:24:32 2017 -0500
     8.3 @@ -37,8 +37,8 @@
     8.4      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
     8.5      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
     8.6      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
     8.7 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
     8.8 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
     8.9 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
    8.10 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    8.11        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    8.12        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
    8.13        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
    8.14 @@ -293,7 +293,7 @@
    8.15      <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    8.16      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    8.17      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
    8.18 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
    8.19 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
    8.20      <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
    8.21      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
    8.22      <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
    8.23 @@ -483,7 +483,7 @@
    8.24        <SubSystem>Console</SubSystem>
    8.25        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    8.26        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    8.27 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.28 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.29      </Link>
    8.30    </ItemDefinitionGroup>
    8.31    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    8.32 @@ -497,7 +497,7 @@
    8.33        <SubSystem>Console</SubSystem>
    8.34        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    8.35        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    8.36 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.37 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.38      </Link>
    8.39    </ItemDefinitionGroup>
    8.40    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
    8.41 @@ -511,7 +511,7 @@
    8.42        <SubSystem>Console</SubSystem>
    8.43        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    8.44        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    8.45 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.46 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.47      </Link>
    8.48    </ItemDefinitionGroup>
    8.49    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
    8.50 @@ -525,7 +525,7 @@
    8.51        <SubSystem>Console</SubSystem>
    8.52        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    8.53        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    8.54 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.55 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.56      </Link>
    8.57    </ItemDefinitionGroup>
    8.58    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    8.59 @@ -539,7 +539,7 @@
    8.60        <SubSystem>Console</SubSystem>
    8.61        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    8.62        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    8.63 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.64 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.65      </Link>
    8.66    </ItemDefinitionGroup>
    8.67    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    8.68 @@ -553,7 +553,7 @@
    8.69        <SubSystem>Console</SubSystem>
    8.70        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
    8.71        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
    8.72 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.73 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    8.74      </Link>
    8.75    </ItemDefinitionGroup>
    8.76    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
     9.1 --- a/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters	Wed Dec 06 13:48:51 2017 -0500
     9.2 +++ b/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters	Wed Dec 06 12:24:32 2017 -0500
     9.3 @@ -214,10 +214,10 @@
     9.4      <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
     9.5        <Filter>Source Files</Filter>
     9.6      </ClCompile>
     9.7 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
     9.8 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c">
     9.9        <Filter>Source Files</Filter>
    9.10      </ClCompile>
    9.11 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    9.12 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
    9.13        <Filter>Source Files</Filter>
    9.14      </ClCompile>
    9.15      <ClCompile Include="..\..\src\render\SDL_yuv_sw.c">
    9.16 @@ -618,7 +618,7 @@
    9.17      <ClInclude Include="..\..\src\core\windows\SDL_windows.h">
    9.18        <Filter>Source Files</Filter>
    9.19      </ClInclude>
    9.20 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
    9.21 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h">
    9.22        <Filter>Source Files</Filter>
    9.23      </ClInclude>
    9.24      <ClInclude Include="..\..\src\events\blank_cursor.h">
    10.1 --- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj	Wed Dec 06 13:48:51 2017 -0500
    10.2 +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj	Wed Dec 06 12:24:32 2017 -0500
    10.3 @@ -84,7 +84,7 @@
    10.4      <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    10.5      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    10.6      <ClInclude Include="..\..\src\audio\SDL_wave.h" />
    10.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
    10.8 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
    10.9      <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
   10.10      <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
   10.11      <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
   10.12 @@ -172,8 +172,8 @@
   10.13      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
   10.14      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
   10.15      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
   10.16 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
   10.17 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
   10.18 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
   10.19 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
   10.20        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
   10.21        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
   10.22        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
   10.23 @@ -484,7 +484,7 @@
   10.24        <SubSystem>Console</SubSystem>
   10.25        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
   10.26        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
   10.27 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.28 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.29      </Link>
   10.30    </ItemDefinitionGroup>
   10.31    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   10.32 @@ -498,7 +498,7 @@
   10.33        <SubSystem>Console</SubSystem>
   10.34        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
   10.35        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
   10.36 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.37 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.38      </Link>
   10.39    </ItemDefinitionGroup>
   10.40    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
   10.41 @@ -512,7 +512,7 @@
   10.42        <SubSystem>Console</SubSystem>
   10.43        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
   10.44        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
   10.45 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.46 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.47      </Link>
   10.48    </ItemDefinitionGroup>
   10.49    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
   10.50 @@ -526,7 +526,7 @@
   10.51        <SubSystem>Console</SubSystem>
   10.52        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
   10.53        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
   10.54 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.55 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.56      </Link>
   10.57    </ItemDefinitionGroup>
   10.58    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
   10.59 @@ -540,7 +540,7 @@
   10.60        <SubSystem>Console</SubSystem>
   10.61        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
   10.62        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
   10.63 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.64 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.65      </Link>
   10.66    </ItemDefinitionGroup>
   10.67    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
   10.68 @@ -554,7 +554,7 @@
   10.69        <SubSystem>Console</SubSystem>
   10.70        <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
   10.71        <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
   10.72 -      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.73 +      <AdditionalDependencies>xinput.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.74      </Link>
   10.75    </ItemDefinitionGroup>
   10.76    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
    11.1 --- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters	Wed Dec 06 13:48:51 2017 -0500
    11.2 +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters	Wed Dec 06 12:24:32 2017 -0500
    11.3 @@ -183,7 +183,7 @@
    11.4      <ClInclude Include="..\..\src\audio\SDL_wave.h">
    11.5        <Filter>Source Files</Filter>
    11.6      </ClInclude>
    11.7 -    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
    11.8 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h">
    11.9        <Filter>Source Files</Filter>
   11.10      </ClInclude>
   11.11      <ClInclude Include="..\..\src\core\windows\SDL_windows.h">
   11.12 @@ -440,10 +440,10 @@
   11.13      <ClCompile Include="..\..\src\audio\SDL_wave.c">
   11.14        <Filter>Source Files</Filter>
   11.15      </ClCompile>
   11.16 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
   11.17 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c">
   11.18        <Filter>Source Files</Filter>
   11.19      </ClCompile>
   11.20 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
   11.21 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_winrt.cpp">
   11.22        <Filter>Source Files</Filter>
   11.23      </ClCompile>
   11.24      <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
    12.1 --- a/VisualC/SDL/SDL.vcxproj	Wed Dec 06 13:48:51 2017 -0500
    12.2 +++ b/VisualC/SDL/SDL.vcxproj	Wed Dec 06 12:24:32 2017 -0500
    12.3 @@ -291,6 +291,7 @@
    12.4      <ClInclude Include="..\..\src\audio\directsound\SDL_directsound.h" />
    12.5      <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
    12.6      <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
    12.7 +    <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
    12.8      <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    12.9      <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
   12.10      <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
   12.11 @@ -389,9 +390,9 @@
   12.12      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
   12.13      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
   12.14      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
   12.15 +    <ClCompile Include="..\..\src\audio\winmm\SDL_winmm.c" />
   12.16      <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
   12.17 -    <ClCompile Include="..\..\src\audio\winmm\SDL_winmm.c" />
   12.18 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
   12.19 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
   12.20      <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
   12.21      <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
   12.22      <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
    13.1 --- a/VisualC/SDL/SDL.vcxproj.filters	Wed Dec 06 13:48:51 2017 -0500
    13.2 +++ b/VisualC/SDL/SDL.vcxproj.filters	Wed Dec 06 12:24:32 2017 -0500
    13.3 @@ -438,7 +438,8 @@
    13.4      <ClCompile Include="..\..\src\video\windows\SDL_windowsvideo.c" />
    13.5      <ClCompile Include="..\..\src\video\windows\SDL_windowswindow.c" />
    13.6      <ClCompile Include="..\..\src\audio\winmm\SDL_winmm.c" />
    13.7 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
    13.8 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
    13.9 +    <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
   13.10      <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
   13.11      <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
   13.12      <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
    14.1 --- a/configure.in	Wed Dec 06 13:48:51 2017 -0500
    14.2 +++ b/configure.in	Wed Dec 06 12:24:32 2017 -0500
    14.3 @@ -2978,7 +2978,6 @@
    14.4          AC_CHECK_HEADER(dsound.h, have_dsound=yes)
    14.5          AC_CHECK_HEADER(dinput.h, have_dinput=yes)
    14.6          AC_CHECK_HEADER(dxgi.h, have_dxgi=yes)
    14.7 -        AC_CHECK_HEADER(xaudio2.h, have_xaudio2=yes)
    14.8          AC_CHECK_HEADER(xinput.h, have_xinput=yes)
    14.9          AC_CHECK_HEADER(mmdeviceapi.h, have_wasapi=yes)
   14.10          AC_CHECK_HEADER(audioclient.h,,have_wasapi=no)
   14.11 @@ -3486,10 +3485,6 @@
   14.12                  AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
   14.13                  SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
   14.14              fi
   14.15 -            if test x$have_xaudio2 = xyes; then
   14.16 -                AC_DEFINE(SDL_AUDIO_DRIVER_XAUDIO2, 1, [ ])
   14.17 -                SOURCES="$SOURCES $srcdir/src/audio/xaudio2/*.c"
   14.18 -            fi
   14.19              if test x$have_wasapi = xyes; then
   14.20                  AC_DEFINE(SDL_AUDIO_DRIVER_WASAPI, 1, [ ])
   14.21                  SOURCES="$SOURCES $srcdir/src/audio/wasapi/*.c"
    15.1 --- a/docs/README-winrt.md	Wed Dec 06 13:48:51 2017 -0500
    15.2 +++ b/docs/README-winrt.md	Wed Dec 06 12:24:32 2017 -0500
    15.3 @@ -70,7 +70,10 @@
    15.4      SDL_GetPerformanceFrequency(), etc.)
    15.5    * file I/O via SDL_RWops
    15.6    * mouse input  (unsupported on Windows Phone)
    15.7 -  * audio, via a modified version of SDL's XAudio2 backend
    15.8 +  * audio, via SDL's WASAPI backend (if you want to record, your app must 
    15.9 +    have "Microphone" capabilities enabled in its manifest, and the user must 
   15.10 +    not have blocked access. Otherwise, capture devices will fail to work,
   15.11 +    presenting as a device disconnect shortly after opening it.)
   15.12    * .DLL file loading.  Libraries *MUST* be packaged inside applications.  Loading
   15.13      anything outside of the app is not supported.
   15.14    * system path retrieval via SDL's filesystem APIs
    16.1 --- a/include/SDL_config.h.cmake	Wed Dec 06 13:48:51 2017 -0500
    16.2 +++ b/include/SDL_config.h.cmake	Wed Dec 06 12:24:32 2017 -0500
    16.3 @@ -202,7 +202,6 @@
    16.4  #cmakedefine HAVE_DDRAW_H @HAVE_DDRAW_H@
    16.5  #cmakedefine HAVE_DSOUND_H @HAVE_DSOUND_H@
    16.6  #cmakedefine HAVE_DINPUT_H @HAVE_DINPUT_H@
    16.7 -#cmakedefine HAVE_XAUDIO2_H @HAVE_XAUDIO2_H@
    16.8  #cmakedefine HAVE_XINPUT_H @HAVE_XINPUT_H@
    16.9  #cmakedefine HAVE_DXGI_H @HAVE_DXGI_H@
   16.10  #cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
   16.11 @@ -259,7 +258,6 @@
   16.12  #cmakedefine SDL_AUDIO_DRIVER_SUNAUDIO @SDL_AUDIO_DRIVER_SUNAUDIO@
   16.13  #cmakedefine SDL_AUDIO_DRIVER_WASAPI @SDL_AUDIO_DRIVER_WASAPI@
   16.14  #cmakedefine SDL_AUDIO_DRIVER_WINMM @SDL_AUDIO_DRIVER_WINMM@
   16.15 -#cmakedefine SDL_AUDIO_DRIVER_XAUDIO2 @SDL_AUDIO_DRIVER_XAUDIO2@
   16.16  
   16.17  /* Enable various input drivers */
   16.18  #cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@
    17.1 --- a/include/SDL_config.h.in	Wed Dec 06 13:48:51 2017 -0500
    17.2 +++ b/include/SDL_config.h.in	Wed Dec 06 12:24:32 2017 -0500
    17.3 @@ -259,7 +259,6 @@
    17.4  #undef SDL_AUDIO_DRIVER_SUNAUDIO
    17.5  #undef SDL_AUDIO_DRIVER_WASAPI
    17.6  #undef SDL_AUDIO_DRIVER_WINMM
    17.7 -#undef SDL_AUDIO_DRIVER_XAUDIO2
    17.8  
    17.9  /* Enable various input drivers */
   17.10  #undef SDL_INPUT_LINUXEV
    18.1 --- a/include/SDL_config_windows.h	Wed Dec 06 13:48:51 2017 -0500
    18.2 +++ b/include/SDL_config_windows.h	Wed Dec 06 12:24:32 2017 -0500
    18.3 @@ -179,7 +179,6 @@
    18.4  /* Enable various audio drivers */
    18.5  #define SDL_AUDIO_DRIVER_WASAPI 1
    18.6  #define SDL_AUDIO_DRIVER_DSOUND 1
    18.7 -#define SDL_AUDIO_DRIVER_XAUDIO2    0
    18.8  #define SDL_AUDIO_DRIVER_WINMM  1
    18.9  #define SDL_AUDIO_DRIVER_DISK   1
   18.10  #define SDL_AUDIO_DRIVER_DUMMY  1
    19.1 --- a/include/SDL_config_winrt.h	Wed Dec 06 13:48:51 2017 -0500
    19.2 +++ b/include/SDL_config_winrt.h	Wed Dec 06 12:24:32 2017 -0500
    19.3 @@ -175,7 +175,7 @@
    19.4  #define HAVE__FSEEKI64 1
    19.5  
    19.6  /* Enable various audio drivers */
    19.7 -#define SDL_AUDIO_DRIVER_XAUDIO2    1
    19.8 +#define SDL_AUDIO_DRIVER_WASAPI 1
    19.9  #define SDL_AUDIO_DRIVER_DISK   1
   19.10  #define SDL_AUDIO_DRIVER_DUMMY  1
   19.11  
    20.1 --- a/src/SDL_internal.h	Wed Dec 06 13:48:51 2017 -0500
    20.2 +++ b/src/SDL_internal.h	Wed Dec 06 12:24:32 2017 -0500
    20.3 @@ -29,7 +29,7 @@
    20.4  /* This is for a variable-length array at the end of a struct:
    20.5      struct x { int y; char z[SDL_VARIABLE_LENGTH_ARRAY]; };
    20.6     Use this because GCC 2 needs different magic than other compilers. */
    20.7 -#if (defined(__GNUC__) && (__GNUC__ <= 2)) || defined(__CC_ARM)
    20.8 +#if (defined(__GNUC__) && (__GNUC__ <= 2)) || defined(__CC_ARM) || defined(__cplusplus)
    20.9  #define SDL_VARIABLE_LENGTH_ARRAY 1
   20.10  #else
   20.11  #define SDL_VARIABLE_LENGTH_ARRAY
    21.1 --- a/src/audio/SDL_audio.c	Wed Dec 06 13:48:51 2017 -0500
    21.2 +++ b/src/audio/SDL_audio.c	Wed Dec 06 12:24:32 2017 -0500
    21.3 @@ -71,9 +71,6 @@
    21.4  #if SDL_AUDIO_DRIVER_WASAPI
    21.5      &WASAPI_bootstrap,
    21.6  #endif
    21.7 -#if SDL_AUDIO_DRIVER_XAUDIO2
    21.8 -    &XAUDIO2_bootstrap,
    21.9 -#endif
   21.10  #if SDL_AUDIO_DRIVER_DSOUND
   21.11      &DSOUND_bootstrap,
   21.12  #endif
   21.13 @@ -234,6 +231,11 @@
   21.14  }
   21.15  
   21.16  static void
   21.17 +SDL_AudioBeginLoopIteration_Default(_THIS)
   21.18 +{                               /* no-op. */
   21.19 +}
   21.20 +
   21.21 +static void
   21.22  SDL_AudioWaitDevice_Default(_THIS)
   21.23  {                               /* no-op. */
   21.24  }
   21.25 @@ -353,6 +355,7 @@
   21.26      FILL_STUB(OpenDevice);
   21.27      FILL_STUB(ThreadInit);
   21.28      FILL_STUB(ThreadDeinit);
   21.29 +    FILL_STUB(BeginLoopIteration);
   21.30      FILL_STUB(WaitDevice);
   21.31      FILL_STUB(PlayDevice);
   21.32      FILL_STUB(GetPendingBytes);
   21.33 @@ -642,6 +645,7 @@
   21.34      SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
   21.35      void *udata = device->callbackspec.userdata;
   21.36      SDL_AudioCallback callback = device->callbackspec.callback;
   21.37 +    int data_len = 0;
   21.38      Uint8 *data;
   21.39  
   21.40      SDL_assert(!device->iscapture);
   21.41 @@ -655,7 +659,8 @@
   21.42  
   21.43      /* Loop, filling the audio buffers */
   21.44      while (!SDL_AtomicGet(&device->shutdown)) {
   21.45 -        const int data_len = device->callbackspec.size;
   21.46 +        current_audio.impl.BeginLoopIteration(device);
   21.47 +        data_len = device->callbackspec.size;
   21.48  
   21.49          /* Fill the current buffer with sound */
   21.50          if (!device->stream && SDL_AtomicGet(&device->enabled)) {
   21.51 @@ -754,6 +759,8 @@
   21.52          int still_need;
   21.53          Uint8 *ptr;
   21.54  
   21.55 +        current_audio.impl.BeginLoopIteration(device);
   21.56 +
   21.57          if (SDL_AtomicGet(&device->paused)) {
   21.58              SDL_Delay(delay);  /* just so we don't cook the CPU. */
   21.59              if (device->stream) {
    22.1 --- a/src/audio/SDL_sysaudio.h	Wed Dec 06 13:48:51 2017 -0500
    22.2 +++ b/src/audio/SDL_sysaudio.h	Wed Dec 06 12:24:32 2017 -0500
    22.3 @@ -68,6 +68,7 @@
    22.4      int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture);
    22.5      void (*ThreadInit) (_THIS); /* Called by audio thread at start */
    22.6      void (*ThreadDeinit) (_THIS); /* Called by audio thread at end */
    22.7 +    void (*BeginLoopIteration)(_THIS);  /* Called by audio thread at top of loop */
    22.8      void (*WaitDevice) (_THIS);
    22.9      void (*PlayDevice) (_THIS);
   22.10      int (*GetPendingBytes) (_THIS);
   22.11 @@ -193,7 +194,6 @@
   22.12  extern AudioBootStrap NACLAUDIO_bootstrap;
   22.13  extern AudioBootStrap NAS_bootstrap;
   22.14  extern AudioBootStrap WASAPI_bootstrap;
   22.15 -extern AudioBootStrap XAUDIO2_bootstrap;
   22.16  extern AudioBootStrap DSOUND_bootstrap;
   22.17  extern AudioBootStrap WINMM_bootstrap;
   22.18  extern AudioBootStrap PAUDIO_bootstrap;
    23.1 --- a/src/audio/wasapi/SDL_wasapi.c	Wed Dec 06 13:48:51 2017 -0500
    23.2 +++ b/src/audio/wasapi/SDL_wasapi.c	Wed Dec 06 12:24:32 2017 -0500
    23.3 @@ -37,14 +37,9 @@
    23.4  
    23.5  #include "SDL_wasapi.h"
    23.6  
    23.7 -static const ERole SDL_WASAPI_role = eConsole;  /* !!! FIXME: should this be eMultimedia? Should be a hint? */
    23.8 -
    23.9 -/* This is global to the WASAPI target, to handle hotplug and default device lookup. */
   23.10 -static IMMDeviceEnumerator *enumerator = NULL;
   23.11 -
   23.12  /* these increment as default devices change. Opened default devices pick up changes in their threads. */
   23.13 -static SDL_atomic_t default_playback_generation;
   23.14 -static SDL_atomic_t default_capture_generation;
   23.15 +SDL_atomic_t WASAPI_DefaultPlaybackGeneration;
   23.16 +SDL_atomic_t WASAPI_DefaultCaptureGeneration;
   23.17  
   23.18  /* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */
   23.19  typedef struct DevIdList
   23.20 @@ -55,173 +50,11 @@
   23.21  
   23.22  static DevIdList *deviceid_list = NULL;
   23.23  
   23.24 -/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */
   23.25 -#ifndef __WINRT__
   23.26 -static HMODULE libavrt = NULL;
   23.27 -#endif
   23.28 -typedef HANDLE (WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPWSTR,LPDWORD);
   23.29 -typedef BOOL (WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
   23.30 -static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
   23.31 -static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
   23.32 -
   23.33  /* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */
   23.34 -static const CLSID SDL_CLSID_MMDeviceEnumerator = { 0xbcde0395, 0xe52f, 0x467c, { 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e } };
   23.35 -static const IID SDL_IID_IMMDeviceEnumerator = { 0xa95664d2, 0x9614, 0x4f35, { 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6 } };
   23.36 -static const IID SDL_IID_IMMNotificationClient = { 0x7991eec9, 0x7e89, 0x4d85, { 0x83, 0x90, 0x6c, 0x70, 0x3c, 0xec, 0x60, 0xc0 } };
   23.37 -static const IID SDL_IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089, { 0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5 } };
   23.38 -static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
   23.39 -static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483, { 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
   23.40 -static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0, { 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
   23.41 -static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
   23.42 -static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
   23.43 -static const PROPERTYKEY SDL_PKEY_Device_FriendlyName = { { 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, } }, 14 };
   23.44 -
   23.45 -/* PropVariantInit() is an inline function/macro in PropIdl.h that calls the C runtime's memset() directly. Use ours instead, to avoid dependency. */ 
   23.46 -#ifdef PropVariantInit
   23.47 -#undef PropVariantInit
   23.48 -#endif
   23.49 -#define PropVariantInit(p) SDL_zerop(p)
   23.50 -
   23.51 -static void AddWASAPIDevice(const SDL_bool iscapture, IMMDevice *device, LPCWSTR devid);
   23.52 -static void RemoveWASAPIDevice(const SDL_bool iscapture, LPCWSTR devid);
   23.53 -
   23.54 -/* We need a COM subclass of IMMNotificationClient for hotplug support, which is
   23.55 -   easy in C++, but we have to tapdance more to make work in C.
   23.56 -   Thanks to this page for coaching on how to make this work:
   23.57 -     https://www.codeproject.com/Articles/13601/COM-in-plain-C */
   23.58 -
   23.59 -typedef struct SDLMMNotificationClient
   23.60 -{
   23.61 -    const IMMNotificationClientVtbl *lpVtbl;
   23.62 -    SDL_atomic_t refcount;
   23.63 -} SDLMMNotificationClient;
   23.64 -
   23.65 -static HRESULT STDMETHODCALLTYPE
   23.66 -SDLMMNotificationClient_QueryInterface(IMMNotificationClient *this, REFIID iid, void **ppv)
   23.67 -{
   23.68 -    if ((WIN_IsEqualIID(iid, &IID_IUnknown)) || (WIN_IsEqualIID(iid, &SDL_IID_IMMNotificationClient)))
   23.69 -    {
   23.70 -        *ppv = this;
   23.71 -        this->lpVtbl->AddRef(this);
   23.72 -        return S_OK;
   23.73 -    }
   23.74 -
   23.75 -    *ppv = NULL;
   23.76 -    return E_NOINTERFACE;
   23.77 -}
   23.78 -
   23.79 -static ULONG STDMETHODCALLTYPE
   23.80 -SDLMMNotificationClient_AddRef(IMMNotificationClient *ithis)
   23.81 -{
   23.82 -    SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis;
   23.83 -    return (ULONG) (SDL_AtomicIncRef(&this->refcount) + 1);
   23.84 -}
   23.85 -
   23.86 -static ULONG STDMETHODCALLTYPE
   23.87 -SDLMMNotificationClient_Release(IMMNotificationClient *ithis)
   23.88 -{
   23.89 -    /* this is a static object; we don't ever free it. */
   23.90 -    SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis;
   23.91 -    const ULONG retval = SDL_AtomicDecRef(&this->refcount);
   23.92 -    if (retval == 0) {
   23.93 -        SDL_AtomicSet(&this->refcount, 0);  /* uhh... */
   23.94 -        return 0;
   23.95 -    }
   23.96 -    return retval - 1;
   23.97 -}
   23.98 -
   23.99 -/* These are the entry points called when WASAPI device endpoints change. */
  23.100 -static HRESULT STDMETHODCALLTYPE
  23.101 -SDLMMNotificationClient_OnDefaultDeviceChanged(IMMNotificationClient *ithis, EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
  23.102 -{
  23.103 -    if (role != SDL_WASAPI_role) {
  23.104 -        return S_OK;  /* ignore it. */
  23.105 -    }
  23.106 -
  23.107 -    /* Increment the "generation," so opened devices will pick this up in their threads. */
  23.108 -    switch (flow) {
  23.109 -        case eRender:
  23.110 -            SDL_AtomicAdd(&default_playback_generation, 1);
  23.111 -            break;
  23.112 -
  23.113 -        case eCapture:
  23.114 -            SDL_AtomicAdd(&default_capture_generation, 1);
  23.115 -            break;
  23.116 -
  23.117 -        case eAll:
  23.118 -            SDL_AtomicAdd(&default_playback_generation, 1);
  23.119 -            SDL_AtomicAdd(&default_capture_generation, 1);
  23.120 -            break;
  23.121 -
  23.122 -        default:
  23.123 -            SDL_assert(!"uhoh, unexpected OnDefaultDeviceChange flow!");
  23.124 -            break;
  23.125 -    }
  23.126 -
  23.127 -    return S_OK;
  23.128 -}
  23.129 -
  23.130 -static HRESULT STDMETHODCALLTYPE
  23.131 -SDLMMNotificationClient_OnDeviceAdded(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId)
  23.132 -{
  23.133 -    /* we ignore this; devices added here then progress to ACTIVE, if appropriate, in 
  23.134 -       OnDeviceStateChange, making that a better place to deal with device adds. More 
  23.135 -       importantly: the first time you plug in a USB audio device, this callback will 
  23.136 -       fire, but when you unplug it, it isn't removed (it's state changes to NOTPRESENT).
  23.137 -       Plugging it back in won't fire this callback again. */
  23.138 -    return S_OK;
  23.139 -}
  23.140 -
  23.141 -static HRESULT STDMETHODCALLTYPE
  23.142 -SDLMMNotificationClient_OnDeviceRemoved(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId)
  23.143 -{
  23.144 -    /* See notes in OnDeviceAdded handler about why we ignore this. */
  23.145 -    return S_OK;
  23.146 -}
  23.147 -
  23.148 -static HRESULT STDMETHODCALLTYPE
  23.149 -SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId, DWORD dwNewState)
  23.150 -{
  23.151 -    IMMDevice *device = NULL;
  23.152 -
  23.153 -    if (SUCCEEDED(IMMDeviceEnumerator_GetDevice(enumerator, pwstrDeviceId, &device))) {
  23.154 -        IMMEndpoint *endpoint = NULL;
  23.155 -        if (SUCCEEDED(IMMDevice_QueryInterface(device, &SDL_IID_IMMEndpoint, (void **) &endpoint))) {
  23.156 -            EDataFlow flow;
  23.157 -            if (SUCCEEDED(IMMEndpoint_GetDataFlow(endpoint, &flow))) {
  23.158 -                const SDL_bool iscapture = (flow == eCapture);
  23.159 -                if (dwNewState == DEVICE_STATE_ACTIVE) {
  23.160 -                    AddWASAPIDevice(iscapture, device, pwstrDeviceId);
  23.161 -                } else {
  23.162 -                    RemoveWASAPIDevice(iscapture, pwstrDeviceId);
  23.163 -                }
  23.164 -            }
  23.165 -            IMMEndpoint_Release(endpoint);
  23.166 -        }
  23.167 -        IMMDevice_Release(device);
  23.168 -    }
  23.169 -
  23.170 -    return S_OK;
  23.171 -}
  23.172 -
  23.173 -static HRESULT STDMETHODCALLTYPE
  23.174 -SDLMMNotificationClient_OnPropertyValueChanged(IMMNotificationClient *this, LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
  23.175 -{
  23.176 -    return S_OK;  /* we don't care about these. */
  23.177 -}
  23.178 -
  23.179 -static const IMMNotificationClientVtbl notification_client_vtbl = {
  23.180 -    SDLMMNotificationClient_QueryInterface,
  23.181 -    SDLMMNotificationClient_AddRef,
  23.182 -    SDLMMNotificationClient_Release,
  23.183 -    SDLMMNotificationClient_OnDeviceStateChanged,
  23.184 -    SDLMMNotificationClient_OnDeviceAdded,
  23.185 -    SDLMMNotificationClient_OnDeviceRemoved,
  23.186 -    SDLMMNotificationClient_OnDefaultDeviceChanged,
  23.187 -    SDLMMNotificationClient_OnPropertyValueChanged
  23.188 -};
  23.189 -
  23.190 -static SDLMMNotificationClient notification_client = { &notification_client_vtbl, { 1 } };
  23.191 +static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483,{ 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
  23.192 +static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,{ 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
  23.193 +static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
  23.194 +static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
  23.195  
  23.196  static SDL_bool
  23.197  WStrEqual(const WCHAR *a, const WCHAR *b)
  23.198 @@ -236,10 +69,22 @@
  23.199      return *b == 0;
  23.200  }
  23.201  
  23.202 +static size_t
  23.203 +WStrLen(const WCHAR *wstr)
  23.204 +{
  23.205 +    size_t retval = 0;
  23.206 +    if (wstr) {
  23.207 +        while (*(wstr++)) {
  23.208 +            retval++;
  23.209 +        }
  23.210 +    }
  23.211 +    return retval;
  23.212 +}
  23.213 +
  23.214  static WCHAR *
  23.215  WStrDupe(const WCHAR *wstr)
  23.216  {
  23.217 -    const int len = (lstrlenW(wstr) + 1) * sizeof (WCHAR);
  23.218 +    const int len = (WStrLen(wstr) + 1) * sizeof (WCHAR);
  23.219      WCHAR *retval = (WCHAR *) SDL_malloc(len);
  23.220      if (retval) {
  23.221          SDL_memcpy(retval, wstr, len);
  23.222 @@ -247,8 +92,9 @@
  23.223      return retval;
  23.224  }
  23.225  
  23.226 -static void 
  23.227 -RemoveWASAPIDevice(const SDL_bool iscapture, LPCWSTR devid)
  23.228 +
  23.229 +void
  23.230 +WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
  23.231  {
  23.232      DevIdList *i;
  23.233      DevIdList *next;
  23.234 @@ -269,23 +115,16 @@
  23.235      }
  23.236  }
  23.237  
  23.238 -static void
  23.239 -AddWASAPIDevice(const SDL_bool iscapture, IMMDevice *device, LPCWSTR devid)
  23.240 +void
  23.241 +WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid)
  23.242  {
  23.243 -    IPropertyStore *props = NULL;
  23.244 -    char *utf8dev = NULL;
  23.245      DevIdList *devidlist;
  23.246 -    PROPVARIANT var;
  23.247  
  23.248      /* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
  23.249         In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
  23.250         phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be
  23.251         available and switch automatically. (!!! FIXME...?) */
  23.252  
  23.253 -    /* PKEY_Device_FriendlyName gives you "Speakers (SoundBlaster Pro)" which drives me nuts. I'd rather it be
  23.254 -       "SoundBlaster Pro (Speakers)" but I guess that's developers vs users. Windows uses the FriendlyName in
  23.255 -       its own UIs, like Volume Control, etc. */
  23.256 -
  23.257      /* see if we already have this one. */
  23.258      for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) {
  23.259          if (WStrEqual(devidlist->str, devid)) {
  23.260 @@ -308,61 +147,13 @@
  23.261      devidlist->next = deviceid_list;
  23.262      deviceid_list = devidlist;
  23.263  
  23.264 -    if (SUCCEEDED(IMMDevice_OpenPropertyStore(device, STGM_READ, &props))) {
  23.265 -        PropVariantInit(&var);
  23.266 -        if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_Device_FriendlyName, &var))) {
  23.267 -            utf8dev = WIN_StringToUTF8(var.pwszVal);
  23.268 -            if (utf8dev) {
  23.269 -                SDL_AddAudioDevice(iscapture, utf8dev, (void *) devid);
  23.270 -                SDL_free(utf8dev);
  23.271 -            }
  23.272 -        }
  23.273 -        PropVariantClear(&var);
  23.274 -        IPropertyStore_Release(props);
  23.275 -    }
  23.276 -}
  23.277 -
  23.278 -static void
  23.279 -EnumerateEndpoints(const SDL_bool iscapture)
  23.280 -{
  23.281 -    IMMDeviceCollection *collection = NULL;
  23.282 -    UINT i, total;
  23.283 -
  23.284 -    /* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
  23.285 -       ...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */
  23.286 -
  23.287 -    if (FAILED(IMMDeviceEnumerator_EnumAudioEndpoints(enumerator, iscapture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &collection))) {
  23.288 -        return;
  23.289 -    }
  23.290 -
  23.291 -    if (FAILED(IMMDeviceCollection_GetCount(collection, &total))) {
  23.292 -        IMMDeviceCollection_Release(collection);
  23.293 -        return;
  23.294 -    }
  23.295 -
  23.296 -    for (i = 0; i < total; i++) {
  23.297 -        IMMDevice *device = NULL;
  23.298 -        if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
  23.299 -            LPWSTR devid = NULL;
  23.300 -            if (SUCCEEDED(IMMDevice_GetId(device, &devid))) {
  23.301 -                AddWASAPIDevice(iscapture, device, devid);
  23.302 -                CoTaskMemFree(devid);
  23.303 -            }
  23.304 -            IMMDevice_Release(device);
  23.305 -        }
  23.306 -    }
  23.307 -
  23.308 -    IMMDeviceCollection_Release(collection);
  23.309 +    SDL_AddAudioDevice(iscapture, devname, (void *) devid);
  23.310  }
  23.311  
  23.312  static void
  23.313  WASAPI_DetectDevices(void)
  23.314  {
  23.315 -    EnumerateEndpoints(SDL_FALSE);  /* playback */
  23.316 -    EnumerateEndpoints(SDL_TRUE);   /* capture */
  23.317 -
  23.318 -    /* if this fails, we just won't get hotplug events. Carry on anyhow. */
  23.319 -    IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *) &notification_client);
  23.320 +    WASAPI_EnumerateEndpoints();
  23.321  }
  23.322  
  23.323  static int
  23.324 @@ -372,10 +163,11 @@
  23.325  
  23.326      /* it's okay to fail here; we'll deal with failures in the audio thread. */
  23.327      /* FIXME: need a lock around checking this->hidden->client */
  23.328 -    if (!this->hidden->client || FAILED(IAudioClient_GetCurrentPadding(this->hidden->client, &frames))) {
  23.329 -        return 0;  /* oh well. */
  23.330 +    if (this->hidden->client != NULL) {  /* definitely activated? */
  23.331 +        if (FAILED(IAudioClient_GetCurrentPadding(this->hidden->client, &frames))) {
  23.332 +            return 0;  /* oh well. */
  23.333 +        }
  23.334      }
  23.335 -
  23.336      return ((int) frames) * this->hidden->framesize;
  23.337  }
  23.338  
  23.339 @@ -397,41 +189,9 @@
  23.340      return SDL_TRUE;
  23.341  }
  23.342  
  23.343 -static int PrepWasapiDevice(_THIS, const int iscapture, IMMDevice *device);
  23.344 -static void ReleaseWasapiDevice(_THIS);
  23.345 -
  23.346 -static SDL_bool
  23.347 -RecoverWasapiDevice(_THIS)
  23.348 +static int
  23.349 +UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
  23.350  {
  23.351 -    const SDL_AudioSpec oldspec = this->spec;
  23.352 -    IMMDevice *device = NULL;
  23.353 -    HRESULT ret = S_OK;
  23.354 -
  23.355 -    if (this->hidden->default_device_generation) {
  23.356 -        const EDataFlow dataflow = this->iscapture ? eCapture : eRender;
  23.357 -        ReleaseWasapiDevice(this);  /* dump the lost device's handles. */
  23.358 -        this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ?  &default_capture_generation : &default_playback_generation);
  23.359 -        ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_WASAPI_role, &device);
  23.360 -        if (FAILED(ret)) {
  23.361 -            return SDL_FALSE;  /* can't find a new default device! */
  23.362 -        }
  23.363 -    } else {
  23.364 -        device = this->hidden->device;
  23.365 -        this->hidden->device = NULL;  /* don't release this in ReleaseWasapiDevice(). */
  23.366 -        ReleaseWasapiDevice(this);  /* dump the lost device's handles. */
  23.367 -    }
  23.368 -
  23.369 -    SDL_assert(device != NULL);
  23.370 -
  23.371 -    /* this can fail for lots of reasons, but the most likely is we had a 
  23.372 -       non-default device that was disconnected, so we can't recover. Default
  23.373 -       devices try to reinitialize whatever the new default is, so it's more
  23.374 -       likely to carry on here, but this handles a non-default device that
  23.375 -       simply had its format changed in the Windows Control Panel. */
  23.376 -    if (PrepWasapiDevice(this, this->iscapture, device) == -1) {
  23.377 -        return SDL_FALSE;
  23.378 -    }
  23.379 -
  23.380      /* Since WASAPI requires us to handle all audio conversion, and our
  23.381         device format might have changed, we might have to add/remove/change
  23.382         the audio stream that the higher level uses to convert data, so
  23.383 @@ -444,9 +204,9 @@
  23.384          /* no need to buffer/convert in an AudioStream! */
  23.385          SDL_FreeAudioStream(this->stream);
  23.386          this->stream = NULL;
  23.387 -    } else if ( (oldspec.channels == this->spec.channels) &&
  23.388 -         (oldspec.format == this->spec.format) &&
  23.389 -         (oldspec.freq == this->spec.freq) ) {
  23.390 +    } else if ( (oldspec->channels == this->spec.channels) &&
  23.391 +         (oldspec->format == this->spec.format) &&
  23.392 +         (oldspec->freq == this->spec.freq) ) {
  23.393          /* The existing audio stream is okay to keep using. */
  23.394      } else {
  23.395          /* replace the audiostream for new format */
  23.396 @@ -465,7 +225,7 @@
  23.397          }
  23.398  
  23.399          if (!this->stream) {
  23.400 -            return SDL_FALSE;
  23.401 +            return -1;
  23.402          }
  23.403      }
  23.404  
  23.405 @@ -473,13 +233,37 @@
  23.406      if (this->spec.size > this->work_buffer_len) {
  23.407          Uint8 *ptr = (Uint8 *) SDL_realloc(this->work_buffer, this->spec.size);
  23.408          if (ptr == NULL) {
  23.409 -            SDL_OutOfMemory();
  23.410 -            return SDL_FALSE;
  23.411 +            return SDL_OutOfMemory();
  23.412          }
  23.413          this->work_buffer = ptr;
  23.414          this->work_buffer_len = this->spec.size;
  23.415      }
  23.416  
  23.417 +    return 0;
  23.418 +}
  23.419 +
  23.420 +
  23.421 +static void ReleaseWasapiDevice(_THIS);
  23.422 +
  23.423 +static SDL_bool
  23.424 +RecoverWasapiDevice(_THIS)
  23.425 +{
  23.426 +    ReleaseWasapiDevice(this);  /* dump the lost device's handles. */
  23.427 +
  23.428 +    if (this->hidden->default_device_generation) {
  23.429 +        this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ?  &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
  23.430 +    }
  23.431 +
  23.432 +    /* this can fail for lots of reasons, but the most likely is we had a
  23.433 +       non-default device that was disconnected, so we can't recover. Default
  23.434 +       devices try to reinitialize whatever the new default is, so it's more
  23.435 +       likely to carry on here, but this handles a non-default device that
  23.436 +       simply had its format changed in the Windows Control Panel. */
  23.437 +    if (WASAPI_ActivateDevice(this, SDL_TRUE) == -1) {
  23.438 +        SDL_OpenedAudioDeviceDisconnected(this);
  23.439 +        return SDL_FALSE;
  23.440 +    }
  23.441 +
  23.442      this->hidden->device_lost = SDL_FALSE;
  23.443  
  23.444      return SDL_TRUE;  /* okay, carry on with new device details! */
  23.445 @@ -495,8 +279,12 @@
  23.446          return SDL_FALSE;  /* already failed. */
  23.447      }
  23.448  
  23.449 +    if (!this->hidden->client) {
  23.450 +        return SDL_TRUE;  /* still waiting for activation. */
  23.451 +    }
  23.452 +
  23.453      if (!lost && (generation > 0)) { /* is a default device? */
  23.454 -        const int newgen = SDL_AtomicGet(this->iscapture ? &default_capture_generation : &default_playback_generation);
  23.455 +        const int newgen = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
  23.456          if (generation != newgen) {  /* the desired default device was changed, jump over to it. */
  23.457              lost = SDL_TRUE;
  23.458          }
  23.459 @@ -511,7 +299,7 @@
  23.460      /* get an endpoint buffer from WASAPI. */
  23.461      BYTE *buffer = NULL;
  23.462  
  23.463 -    while (RecoverWasapiIfLost(this)) {
  23.464 +    while (RecoverWasapiIfLost(this) && this->hidden->render) {
  23.465          if (!WasapiFailed(this, IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer))) {
  23.466              return (Uint8 *) buffer;
  23.467          }
  23.468 @@ -524,17 +312,18 @@
  23.469  static void
  23.470  WASAPI_PlayDevice(_THIS)
  23.471  {
  23.472 -    /* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */
  23.473 -    WasapiFailed(this, IAudioRenderClient_ReleaseBuffer(this->hidden->render, this->spec.samples, 0));
  23.474 +    if (this->hidden->render != NULL) {  /* definitely activated? */
  23.475 +        /* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */
  23.476 +        WasapiFailed(this, IAudioRenderClient_ReleaseBuffer(this->hidden->render, this->spec.samples, 0));
  23.477 +    }
  23.478  }
  23.479  
  23.480  static void
  23.481  WASAPI_WaitDevice(_THIS)
  23.482  {
  23.483 -    const UINT32 maxpadding = this->spec.samples;
  23.484 -    while (RecoverWasapiIfLost(this)) {
  23.485 +    while (RecoverWasapiIfLost(this) && this->hidden->client) {
  23.486 +        const UINT32 maxpadding = this->spec.samples;
  23.487          UINT32 padding = 0;
  23.488 -
  23.489          if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
  23.490              if (padding <= maxpadding) {
  23.491                  break;
  23.492 @@ -562,6 +351,14 @@
  23.493          UINT32 frames = 0;
  23.494          DWORD flags = 0;
  23.495  
  23.496 +        /* uhoh, client isn't activated yet, just return silence. */
  23.497 +        if (!this->hidden->capture) {
  23.498 +            /* Delay so we run at about the speed that audio would be arriving. */
  23.499 +            SDL_Delay(((this->spec.samples * 1000) / this->spec.freq));
  23.500 +            SDL_memset(buffer, this->spec.silence, buflen);
  23.501 +            return buflen;
  23.502 +        }
  23.503 +
  23.504          ret = IAudioCaptureClient_GetBuffer(this->hidden->capture, &ptr, &frames, &flags, NULL, NULL);
  23.505          if (ret != AUDCLNT_S_BUFFER_EMPTY) {
  23.506              WasapiFailed(this, ret); /* mark device lost/failed if necessary. */
  23.507 @@ -609,6 +406,10 @@
  23.508      UINT32 frames = 0;
  23.509      DWORD flags = 0;
  23.510  
  23.511 +    if (!this->hidden->capture) {
  23.512 +        return;  /* not activated yet? */
  23.513 +    }
  23.514 +
  23.515      /* just read until we stop getting packets, throwing them away. */
  23.516      while (SDL_TRUE) {
  23.517          const HRESULT ret = IAudioCaptureClient_GetBuffer(this->hidden->capture, &ptr, &frames, &flags, NULL, NULL);
  23.518 @@ -646,30 +447,49 @@
  23.519          this->hidden->waveformat = NULL;
  23.520      }
  23.521  
  23.522 -    if (this->hidden->device) {
  23.523 -        IMMDevice_Release(this->hidden->device);
  23.524 -        this->hidden->device = NULL;
  23.525 -    }
  23.526 -
  23.527      if (this->hidden->capturestream) {
  23.528          SDL_FreeAudioStream(this->hidden->capturestream);
  23.529          this->hidden->capturestream = NULL;
  23.530      }
  23.531 +
  23.532 +    if (this->hidden->activation_handler) {
  23.533 +        WASAPI_PlatformDeleteActivationHandler(this->hidden->activation_handler);
  23.534 +        this->hidden->activation_handler = NULL;
  23.535 +    }
  23.536  }
  23.537  
  23.538  static void
  23.539  WASAPI_CloseDevice(_THIS)
  23.540  {
  23.541 +    WASAPI_UnrefDevice(this);
  23.542 +}
  23.543 +
  23.544 +void
  23.545 +WASAPI_RefDevice(_THIS)
  23.546 +{
  23.547 +    SDL_AtomicIncRef(&this->hidden->refcount);
  23.548 +}
  23.549 +
  23.550 +void
  23.551 +WASAPI_UnrefDevice(_THIS)
  23.552 +{
  23.553 +    if (!SDL_AtomicDecRef(&this->hidden->refcount)) {
  23.554 +        return;
  23.555 +    }
  23.556 +
  23.557 +    /* actual closing happens here. */
  23.558 +
  23.559      /* don't touch this->hidden->task in here; it has to be reverted from
  23.560 -      our callback thread. We do that in WASAPI_ThreadDeinit().
  23.561 -      (likewise for this->hidden->coinitialized). */
  23.562 +       our callback thread. We do that in WASAPI_ThreadDeinit().
  23.563 +       (likewise for this->hidden->coinitialized). */
  23.564      ReleaseWasapiDevice(this);
  23.565 +    SDL_free(this->hidden->devid);
  23.566      SDL_free(this->hidden);
  23.567  }
  23.568  
  23.569 -
  23.570 -static int
  23.571 -PrepWasapiDevice(_THIS, const int iscapture, IMMDevice *device)
  23.572 +/* This is called once a device is activated, possibly asynchronously. */
  23.573 +int
  23.574 +WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
  23.575  {
  23.576      /* !!! FIXME: we could request an exclusive mode stream, which is lower latency;
  23.577         !!!  it will write into the kernel's audio buffer directly instead of
  23.578 @@ -682,10 +502,11 @@
  23.579         !!!  wins actually look like. Maybe add a hint to force exclusive mode at
  23.580         !!!  some point. To be sure, defaulting to shared mode is the right thing to
  23.581         !!!  do in any case. */
  23.582 +    const SDL_AudioSpec oldspec = this->spec;
  23.583      const AUDCLNT_SHAREMODE sharemode = AUDCLNT_SHAREMODE_SHARED;
  23.584      UINT32 bufsize = 0;  /* this is in sample frames, not samples, not bytes. */
  23.585      REFERENCE_TIME duration = 0;
  23.586 -    IAudioClient *client = NULL;
  23.587 +    IAudioClient *client = this->hidden->client;
  23.588      IAudioRenderClient *render = NULL;
  23.589      IAudioCaptureClient *capture = NULL;
  23.590      WAVEFORMATEX *waveformat = NULL;
  23.591 @@ -694,15 +515,7 @@
  23.592      SDL_bool valid_format = SDL_FALSE;
  23.593      HRESULT ret = S_OK;
  23.594  
  23.595 -    this->hidden->device = device;
  23.596 -
  23.597 -    ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &client);
  23.598 -    if (FAILED(ret)) {
  23.599 -        return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
  23.600 -    }
  23.601 -
  23.602      SDL_assert(client != NULL);
  23.603 -    this->hidden->client = client;
  23.604  
  23.605      ret = IAudioClient_GetMixFormat(client, &waveformat);
  23.606      if (FAILED(ret)) {
  23.607 @@ -763,7 +576,7 @@
  23.608      }
  23.609  
  23.610      this->spec.samples = (Uint16) bufsize;
  23.611 -    if (!iscapture) {
  23.612 +    if (!this->iscapture) {
  23.613          this->spec.samples /= 2;  /* fill half of the DMA buffer on each run. */
  23.614      }
  23.615  
  23.616 @@ -772,7 +585,7 @@
  23.617  
  23.618      this->hidden->framesize = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
  23.619  
  23.620 -    if (iscapture) {
  23.621 +    if (this->iscapture) {
  23.622          this->hidden->capturestream = SDL_NewAudioStream(this->spec.format, this->spec.channels, this->spec.freq, this->spec.format, this->spec.channels, this->spec.freq);
  23.623          if (!this->hidden->capturestream) {
  23.624              return -1;  /* already set SDL_Error */
  23.625 @@ -805,15 +618,20 @@
  23.626          }
  23.627      }
  23.628  
  23.629 +    if (updatestream) {
  23.630 +        if (UpdateAudioStream(this, &oldspec) == -1) {
  23.631 +            return -1;
  23.632 +        }
  23.633 +    }
  23.634 +
  23.635      return 0;  /* good to go. */
  23.636  }
  23.637  
  23.638 +
  23.639  static int
  23.640  WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
  23.641  {
  23.642 -    const SDL_bool is_default_device = (handle == NULL);
  23.643 -    IMMDevice *device = NULL;
  23.644 -    HRESULT ret = S_OK;
  23.645 +    LPCWSTR devid = (LPCWSTR) handle;
  23.646  
  23.647      /* Initialize all variables that we clean on shutdown */
  23.648      this->hidden = (struct SDL_PrivateAudioData *)
  23.649 @@ -823,49 +641,42 @@
  23.650      }
  23.651      SDL_zerop(this->hidden);
  23.652  
  23.653 -    if (is_default_device) {
  23.654 -        const EDataFlow dataflow = iscapture ? eCapture : eRender;
  23.655 -        this->hidden->default_device_generation = SDL_AtomicGet(iscapture ? &default_capture_generation : &default_playback_generation);
  23.656 -        ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_WASAPI_role, &device);
  23.657 +    WASAPI_RefDevice(this);   /* so CloseDevice() will unref to zero. */
  23.658 +
  23.659 +    if (!devid) {  /* is default device? */
  23.660 +        this->hidden->default_device_generation = SDL_AtomicGet(iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
  23.661      } else {
  23.662 -        ret = IMMDeviceEnumerator_GetDevice(enumerator, (LPCWSTR) handle, &device);
  23.663 +        this->hidden->devid = WStrDupe(devid);
  23.664 +        if (!this->hidden->devid) {
  23.665 +            return SDL_OutOfMemory();
  23.666 +        }
  23.667      }
  23.668  
  23.669 -    if (FAILED(ret)) {
  23.670 -        return WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret);
  23.671 +    if (WASAPI_ActivateDevice(this, SDL_FALSE) == -1) {
  23.672 +        return -1;  /* already set error. */
  23.673      }
  23.674  
  23.675 -    SDL_assert(device != NULL);
  23.676 -    return PrepWasapiDevice(this, iscapture, device);
  23.677 +    /* Ready, but waiting for async device activation.
  23.678 +       Until activation is successful, we will report silence from capture
  23.679 +       devices and ignore data on playback devices.
  23.680 +       Also, since we don't know the _actual_ device format until after
  23.681 +       activation, we let the app have whatever it asks for. We set up
  23.682 +       an SDL_AudioStream to convert, if necessary, once the activation
  23.683 +       completes. */
  23.684 +
  23.685 +    return 0;
  23.686  }
  23.687  
  23.688  static void
  23.689  WASAPI_ThreadInit(_THIS)
  23.690  {
  23.691 -    /* this thread uses COM. */
  23.692 -    if (SUCCEEDED(WIN_CoInitialize())) {    /* can't report errors, hope it worked! */
  23.693 -        this->hidden->coinitialized = SDL_TRUE;
  23.694 -    }
  23.695 -
  23.696 -    /* Set this thread to very high "Pro Audio" priority. */
  23.697 -    if (pAvSetMmThreadCharacteristicsW) {
  23.698 -        DWORD idx = 0;
  23.699 -        this->hidden->task = pAvSetMmThreadCharacteristicsW(TEXT("Pro Audio"), &idx);
  23.700 -    }
  23.701 +    WASAPI_PlatformThreadInit(this);
  23.702  }
  23.703  
  23.704  static void
  23.705  WASAPI_ThreadDeinit(_THIS)
  23.706  {
  23.707 -    /* Set this thread to very high "Pro Audio" priority. */
  23.708 -    if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
  23.709 -        pAvRevertMmThreadCharacteristics(this->hidden->task);
  23.710 -        this->hidden->task = NULL;
  23.711 -    }
  23.712 -
  23.713 -    if (this->hidden->coinitialized) {
  23.714 -        WIN_CoUninitialize();
  23.715 -    }
  23.716 +    WASAPI_PlatformThreadDeinit(this);
  23.717  }
  23.718  
  23.719  static void
  23.720 @@ -874,21 +685,7 @@
  23.721      DevIdList *devidlist;
  23.722      DevIdList *next;
  23.723  
  23.724 -    if (enumerator) {
  23.725 -        IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *) &notification_client);
  23.726 -        IMMDeviceEnumerator_Release(enumerator);
  23.727 -        enumerator = NULL;
  23.728 -    }
  23.729 -
  23.730 -    #ifndef __WINRT__
  23.731 -    if (libavrt) {
  23.732 -        FreeLibrary(libavrt);
  23.733 -        libavrt = NULL;
  23.734 -    }
  23.735 -    #endif
  23.736 -
  23.737 -    pAvSetMmThreadCharacteristicsW = NULL;
  23.738 -    pAvRevertMmThreadCharacteristics = NULL;
  23.739 +    WASAPI_PlatformDeinit();
  23.740  
  23.741      for (devidlist = deviceid_list; devidlist; devidlist = next) {
  23.742          next = devidlist->next;
  23.743 @@ -896,51 +693,23 @@
  23.744          SDL_free(devidlist);
  23.745      }
  23.746      deviceid_list = NULL;
  23.747 -
  23.748 -    WIN_CoUninitialize();
  23.749  }
  23.750  
  23.751  static int
  23.752  WASAPI_Init(SDL_AudioDriverImpl * impl)
  23.753  {
  23.754 -    HRESULT ret;
  23.755 +    SDL_AtomicSet(&WASAPI_DefaultPlaybackGeneration, 1);
  23.756 +    SDL_AtomicSet(&WASAPI_DefaultCaptureGeneration, 1);
  23.757  
  23.758 -    /* just skip the discussion with COM here. */
  23.759 -    if (!WIN_IsWindowsVistaOrGreater()) {
  23.760 -        SDL_SetError("WASAPI support requires Windows Vista or later");
  23.761 +    if (WASAPI_PlatformInit() == -1) {
  23.762          return 0;
  23.763      }
  23.764  
  23.765 -    SDL_AtomicSet(&default_playback_generation, 1);
  23.766 -    SDL_AtomicSet(&default_capture_generation, 1);
  23.767 -
  23.768 -    if (FAILED(WIN_CoInitialize())) {
  23.769 -        SDL_SetError("WASAPI: CoInitialize() failed");
  23.770 -        return 0;
  23.771 -    }
  23.772 -
  23.773 -    ret = CoCreateInstance(&SDL_CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &SDL_IID_IMMDeviceEnumerator, (LPVOID) &enumerator);
  23.774 -    if (FAILED(ret)) {
  23.775 -        WIN_CoUninitialize();
  23.776 -        WIN_SetErrorFromHRESULT("WASAPI CoCreateInstance(MMDeviceEnumerator)", ret);
  23.777 -        return 0;  /* oh well. */
  23.778 -    }
  23.779 -
  23.780 -    #ifdef __WINRT__
  23.781 -    pAvSetMmThreadCharacteristicsW = AvSetMmThreadCharacteristicsW;
  23.782 -    pAvRevertMmThreadCharacteristics = AvRevertMmThreadCharacteristics;
  23.783 -    #else
  23.784 -    libavrt = LoadLibraryW(L"avrt.dll");  /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
  23.785 -    if (libavrt) {
  23.786 -        pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW) GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
  23.787 -        pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics) GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
  23.788 -    }
  23.789 -    #endif
  23.790 -
  23.791      /* Set the function pointers */
  23.792      impl->DetectDevices = WASAPI_DetectDevices;
  23.793      impl->ThreadInit = WASAPI_ThreadInit;
  23.794      impl->ThreadDeinit = WASAPI_ThreadDeinit;
  23.795 +    impl->BeginLoopIteration = WASAPI_BeginLoopIteration;
  23.796      impl->OpenDevice = WASAPI_OpenDevice;
  23.797      impl->PlayDevice = WASAPI_PlayDevice;
  23.798      impl->WaitDevice = WASAPI_WaitDevice;
    24.1 --- a/src/audio/wasapi/SDL_wasapi.h	Wed Dec 06 13:48:51 2017 -0500
    24.2 +++ b/src/audio/wasapi/SDL_wasapi.h	Wed Dec 06 12:24:32 2017 -0500
    24.3 @@ -23,14 +23,23 @@
    24.4  #ifndef SDL_wasapi_h_
    24.5  #define SDL_wasapi_h_
    24.6  
    24.7 +#ifdef __cplusplus
    24.8 +extern "C" {
    24.9 +#endif
   24.10 +
   24.11  #include "../SDL_sysaudio.h"
   24.12  
   24.13  /* Hidden "this" pointer for the audio functions */
   24.14 +#ifdef __cplusplus
   24.15 +#define _THIS SDL_AudioDevice *_this
   24.16 +#else
   24.17  #define _THIS SDL_AudioDevice *this
   24.18 +#endif
   24.19  
   24.20  struct SDL_PrivateAudioData
   24.21  {
   24.22 -    IMMDevice *device;
   24.23 +    SDL_atomic_t refcount;
   24.24 +    WCHAR *devid;
   24.25      WAVEFORMATEX *waveformat;
   24.26      IAudioClient *client;
   24.27      IAudioRenderClient *render;
   24.28 @@ -41,8 +50,35 @@
   24.29      int framesize;
   24.30      int default_device_generation;
   24.31      SDL_bool device_lost;
   24.32 +    void *activation_handler;
   24.33 +    SDL_atomic_t just_activated;
   24.34  };
   24.35  
   24.36 +/* these increment as default devices change. Opened default devices pick up changes in their threads. */
   24.37 +extern SDL_atomic_t WASAPI_DefaultPlaybackGeneration;
   24.38 +extern SDL_atomic_t WASAPI_DefaultCaptureGeneration;
   24.39 +
   24.40 +/* win32 and winrt implementations call into these. */
   24.41 +int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream);
   24.42 +void WASAPI_RefDevice(_THIS);
   24.43 +void WASAPI_UnrefDevice(_THIS);
   24.44 +void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid);
   24.45 +void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid);
   24.46 +
   24.47 +/* These are functions that are implemented differently for Windows vs WinRT. */
   24.48 +int WASAPI_PlatformInit(void);
   24.49 +void WASAPI_PlatformDeinit(void);
   24.50 +void WASAPI_EnumerateEndpoints(void);
   24.51 +int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery);
   24.52 +void WASAPI_PlatformThreadInit(_THIS);
   24.53 +void WASAPI_PlatformThreadDeinit(_THIS);
   24.54 +void WASAPI_PlatformDeleteActivationHandler(void *handler);
   24.55 +void WASAPI_BeginLoopIteration(_THIS);
   24.56 +
   24.57 +#ifdef __cplusplus
   24.58 +}
   24.59 +#endif
   24.60 +
   24.61  #endif /* SDL_wasapi_h_ */
   24.62  
   24.63  /* vi: set ts=4 sw=4 expandtab: */
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/audio/wasapi/SDL_wasapi_win32.c	Wed Dec 06 12:24:32 2017 -0500
    25.3 @@ -0,0 +1,418 @@
    25.4 +/*
    25.5 +  Simple DirectMedia Layer
    25.6 +  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    25.7 +
    25.8 +  This software is provided 'as-is', without any express or implied
    25.9 +  warranty.  In no event will the authors be held liable for any damages
   25.10 +  arising from the use of this software.
   25.11 +
   25.12 +  Permission is granted to anyone to use this software for any purpose,
   25.13 +  including commercial applications, and to alter it and redistribute it
   25.14 +  freely, subject to the following restrictions:
   25.15 +
   25.16 +  1. The origin of this software must not be misrepresented; you must not
   25.17 +     claim that you wrote the original software. If you use this software
   25.18 +     in a product, an acknowledgment in the product documentation would be
   25.19 +     appreciated but is not required.
   25.20 +  2. Altered source versions must be plainly marked as such, and must not be
   25.21 +     misrepresented as being the original software.
   25.22 +  3. This notice may not be removed or altered from any source distribution.
   25.23 +*/
   25.24 +
   25.25 +#include "../../SDL_internal.h"
   25.26 +
   25.27 +/* This is code that Windows uses to talk to WASAPI-related system APIs.
   25.28 +   This is for non-WinRT desktop apps. The C++/CX implementation of these
   25.29 +   functions, exclusive to WinRT, are in SDL_wasapi_winrt.cpp.
   25.30 +   The code in SDL_wasapi.c is used by both standard Windows and WinRT builds
   25.31 +   to deal with audio and calls into these functions. */
   25.32 +
   25.33 +#if SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__)
   25.34 +
   25.35 +#include "../../core/windows/SDL_windows.h"
   25.36 +#include "SDL_audio.h"
   25.37 +#include "SDL_timer.h"
   25.38 +#include "../SDL_audio_c.h"
   25.39 +#include "../SDL_sysaudio.h"
   25.40 +#include "SDL_assert.h"
   25.41 +#include "SDL_log.h"
   25.42 +
   25.43 +#define COBJMACROS
   25.44 +#include <mmdeviceapi.h>
   25.45 +#include <audioclient.h>
   25.46 +
   25.47 +#include "SDL_wasapi.h"
   25.48 +
   25.49 +static const ERole SDL_WASAPI_role = eConsole;  /* !!! FIXME: should this be eMultimedia? Should be a hint? */
   25.50 +
   25.51 +/* This is global to the WASAPI target, to handle hotplug and default device lookup. */
   25.52 +static IMMDeviceEnumerator *enumerator = NULL;
   25.53 +
   25.54 +/* PropVariantInit() is an inline function/macro in PropIdl.h that calls the C runtime's memset() directly. Use ours instead, to avoid dependency. */
   25.55 +#ifdef PropVariantInit
   25.56 +#undef PropVariantInit
   25.57 +#endif
   25.58 +#define PropVariantInit(p) SDL_zerop(p)
   25.59 +
   25.60 +/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */
   25.61 +static HMODULE libavrt = NULL;
   25.62 +typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPWSTR, LPDWORD);
   25.63 +typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
   25.64 +static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
   25.65 +static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
   25.66 +
   25.67 +/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */
   25.68 +static const CLSID SDL_CLSID_MMDeviceEnumerator = { 0xbcde0395, 0xe52f, 0x467c,{ 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e } };
   25.69 +static const IID SDL_IID_IMMDeviceEnumerator = { 0xa95664d2, 0x9614, 0x4f35,{ 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6 } };
   25.70 +static const IID SDL_IID_IMMNotificationClient = { 0x7991eec9, 0x7e89, 0x4d85,{ 0x83, 0x90, 0x6c, 0x70, 0x3c, 0xec, 0x60, 0xc0 } };
   25.71 +static const IID SDL_IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089,{ 0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5 } };
   25.72 +static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32,{ 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
   25.73 +static const PROPERTYKEY SDL_PKEY_Device_FriendlyName = { { 0xa45c254e, 0xdf1c, 0x4efd,{ 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, } }, 14 };
   25.74 +
   25.75 +
   25.76 +static char *
   25.77 +GetWasapiDeviceName(IMMDevice *device)
   25.78 +{
   25.79 +    /* PKEY_Device_FriendlyName gives you "Speakers (SoundBlaster Pro)" which drives me nuts. I'd rather it be
   25.80 +       "SoundBlaster Pro (Speakers)" but I guess that's developers vs users. Windows uses the FriendlyName in
   25.81 +       its own UIs, like Volume Control, etc. */
   25.82 +    char *utf8dev = NULL;
   25.83 +    IPropertyStore *props = NULL;
   25.84 +    if (SUCCEEDED(IMMDevice_OpenPropertyStore(device, STGM_READ, &props))) {
   25.85 +        PROPVARIANT var;
   25.86 +        PropVariantInit(&var);
   25.87 +        if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_Device_FriendlyName, &var))) {
   25.88 +            utf8dev = WIN_StringToUTF8(var.pwszVal);
   25.89 +        }
   25.90 +        PropVariantClear(&var);
   25.91 +        IPropertyStore_Release(props);
   25.92 +    }
   25.93 +    return utf8dev;
   25.94 +}
   25.95 +
   25.96 +
   25.97 +/* We need a COM subclass of IMMNotificationClient for hotplug support, which is
   25.98 +   easy in C++, but we have to tapdance more to make work in C.
   25.99 +   Thanks to this page for coaching on how to make this work:
  25.100 +     https://www.codeproject.com/Articles/13601/COM-in-plain-C */
  25.101 +
  25.102 +typedef struct SDLMMNotificationClient
  25.103 +{
  25.104 +    const IMMNotificationClientVtbl *lpVtbl;
  25.105 +    SDL_atomic_t refcount;
  25.106 +} SDLMMNotificationClient;
  25.107 +
  25.108 +static HRESULT STDMETHODCALLTYPE
  25.109 +SDLMMNotificationClient_QueryInterface(IMMNotificationClient *this, REFIID iid, void **ppv)
  25.110 +{
  25.111 +    if ((WIN_IsEqualIID(iid, &IID_IUnknown)) || (WIN_IsEqualIID(iid, &SDL_IID_IMMNotificationClient)))
  25.112 +    {
  25.113 +        *ppv = this;
  25.114 +        this->lpVtbl->AddRef(this);
  25.115 +        return S_OK;
  25.116 +    }
  25.117 +
  25.118 +    *ppv = NULL;
  25.119 +    return E_NOINTERFACE;
  25.120 +}
  25.121 +
  25.122 +static ULONG STDMETHODCALLTYPE
  25.123 +SDLMMNotificationClient_AddRef(IMMNotificationClient *ithis)
  25.124 +{
  25.125 +    SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis;
  25.126 +    return (ULONG) (SDL_AtomicIncRef(&this->refcount) + 1);
  25.127 +}
  25.128 +
  25.129 +static ULONG STDMETHODCALLTYPE
  25.130 +SDLMMNotificationClient_Release(IMMNotificationClient *ithis)
  25.131 +{
  25.132 +    /* this is a static object; we don't ever free it. */
  25.133 +    SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis;
  25.134 +    const ULONG retval = SDL_AtomicDecRef(&this->refcount);
  25.135 +    if (retval == 0) {
  25.136 +        SDL_AtomicSet(&this->refcount, 0);  /* uhh... */
  25.137 +        return 0;
  25.138 +    }
  25.139 +    return retval - 1;
  25.140 +}
  25.141 +
  25.142 +/* These are the entry points called when WASAPI device endpoints change. */
  25.143 +static HRESULT STDMETHODCALLTYPE
  25.144 +SDLMMNotificationClient_OnDefaultDeviceChanged(IMMNotificationClient *ithis, EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
  25.145 +{
  25.146 +    if (role != SDL_WASAPI_role) {
  25.147 +        return S_OK;  /* ignore it. */
  25.148 +    }
  25.149 +
  25.150 +    /* Increment the "generation," so opened devices will pick this up in their threads. */
  25.151 +    switch (flow) {
  25.152 +        case eRender:
  25.153 +            SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1);
  25.154 +            break;
  25.155 +
  25.156 +        case eCapture:
  25.157 +            SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1);
  25.158 +            break;
  25.159 +
  25.160 +        case eAll:
  25.161 +            SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1);
  25.162 +            SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1);
  25.163 +            break;
  25.164 +
  25.165 +        default:
  25.166 +            SDL_assert(!"uhoh, unexpected OnDefaultDeviceChange flow!");
  25.167 +            break;
  25.168 +    }
  25.169 +
  25.170 +    return S_OK;
  25.171 +}
  25.172 +
  25.173 +static HRESULT STDMETHODCALLTYPE
  25.174 +SDLMMNotificationClient_OnDeviceAdded(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId)
  25.175 +{
  25.176 +    /* we ignore this; devices added here then progress to ACTIVE, if appropriate, in 
  25.177 +       OnDeviceStateChange, making that a better place to deal with device adds. More 
  25.178 +       importantly: the first time you plug in a USB audio device, this callback will 
  25.179 +       fire, but when you unplug it, it isn't removed (it's state changes to NOTPRESENT).
  25.180 +       Plugging it back in won't fire this callback again. */
  25.181 +    return S_OK;
  25.182 +}
  25.183 +
  25.184 +static HRESULT STDMETHODCALLTYPE
  25.185 +SDLMMNotificationClient_OnDeviceRemoved(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId)
  25.186 +{
  25.187 +    /* See notes in OnDeviceAdded handler about why we ignore this. */
  25.188 +    return S_OK;
  25.189 +}
  25.190 +
  25.191 +static HRESULT STDMETHODCALLTYPE
  25.192 +SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId, DWORD dwNewState)
  25.193 +{
  25.194 +    SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis;
  25.195 +    IMMDevice *device = NULL;
  25.196 +
  25.197 +    if (SUCCEEDED(IMMDeviceEnumerator_GetDevice(enumerator, pwstrDeviceId, &device))) {
  25.198 +        IMMEndpoint *endpoint = NULL;
  25.199 +        if (SUCCEEDED(IMMDevice_QueryInterface(device, &SDL_IID_IMMEndpoint, (void **) &endpoint))) {
  25.200 +            EDataFlow flow;
  25.201 +            if (SUCCEEDED(IMMEndpoint_GetDataFlow(endpoint, &flow))) {
  25.202 +                const SDL_bool iscapture = (flow == eCapture);
  25.203 +                if (dwNewState == DEVICE_STATE_ACTIVE) {
  25.204 +                    char *utf8dev = GetWasapiDeviceName(device);
  25.205 +                    if (utf8dev) {
  25.206 +                        WASAPI_AddDevice(iscapture, utf8dev, pwstrDeviceId);
  25.207 +                        SDL_free(utf8dev);
  25.208 +                    }
  25.209 +                } else {
  25.210 +                    WASAPI_RemoveDevice(iscapture, pwstrDeviceId);
  25.211 +                }
  25.212 +            }
  25.213 +            IMMEndpoint_Release(endpoint);
  25.214 +        }
  25.215 +        IMMDevice_Release(device);
  25.216 +    }
  25.217 +
  25.218 +    return S_OK;
  25.219 +}
  25.220 +
  25.221 +static HRESULT STDMETHODCALLTYPE
  25.222 +SDLMMNotificationClient_OnPropertyValueChanged(IMMNotificationClient *this, LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
  25.223 +{
  25.224 +    return S_OK;  /* we don't care about these. */
  25.225 +}
  25.226 +
  25.227 +static const IMMNotificationClientVtbl notification_client_vtbl = {
  25.228 +    SDLMMNotificationClient_QueryInterface,
  25.229 +    SDLMMNotificationClient_AddRef,
  25.230 +    SDLMMNotificationClient_Release,
  25.231 +    SDLMMNotificationClient_OnDeviceStateChanged,
  25.232 +    SDLMMNotificationClient_OnDeviceAdded,
  25.233 +    SDLMMNotificationClient_OnDeviceRemoved,
  25.234 +    SDLMMNotificationClient_OnDefaultDeviceChanged,
  25.235 +    SDLMMNotificationClient_OnPropertyValueChanged
  25.236 +};
  25.237 +
  25.238 +static SDLMMNotificationClient notification_client = { &notification_client_vtbl, 1 };
  25.239 +
  25.240 +
  25.241 +int
  25.242 +WASAPI_PlatformInit(void)
  25.243 +{
  25.244 +    HRESULT ret;
  25.245 +
  25.246 +    /* just skip the discussion with COM here. */
  25.247 +    if (!WIN_IsWindowsVistaOrGreater()) {
  25.248 +        return SDL_SetError("WASAPI support requires Windows Vista or later");
  25.249 +    }
  25.250 +
  25.251 +    if (FAILED(WIN_CoInitialize())) {
  25.252 +        return SDL_SetError("WASAPI: CoInitialize() failed");
  25.253 +    }
  25.254 +
  25.255 +    ret = CoCreateInstance(&SDL_CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &SDL_IID_IMMDeviceEnumerator, (LPVOID) &enumerator);
  25.256 +    if (FAILED(ret)) {
  25.257 +        WIN_CoUninitialize();
  25.258 +        return WIN_SetErrorFromHRESULT("WASAPI CoCreateInstance(MMDeviceEnumerator)", ret);
  25.259 +    }
  25.260 +
  25.261 +    libavrt = LoadLibraryW(L"avrt.dll");  /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
  25.262 +    if (libavrt) {
  25.263 +        pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW) GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
  25.264 +        pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics) GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
  25.265 +    }
  25.266 +
  25.267 +    return 0;
  25.268 +}
  25.269 +
  25.270 +void
  25.271 +WASAPI_PlatformDeinit(void)
  25.272 +{
  25.273 +    if (enumerator) {
  25.274 +        IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *) &notification_client);
  25.275 +        IMMDeviceEnumerator_Release(enumerator);
  25.276 +        enumerator = NULL;
  25.277 +    }
  25.278 +
  25.279 +    if (libavrt) {
  25.280 +        FreeLibrary(libavrt);
  25.281 +        libavrt = NULL;
  25.282 +    }
  25.283 +
  25.284 +    pAvSetMmThreadCharacteristicsW = NULL;
  25.285 +    pAvRevertMmThreadCharacteristics = NULL;
  25.286 +
  25.287 +    WIN_CoUninitialize();
  25.288 +}
  25.289 +
  25.290 +void
  25.291 +WASAPI_PlatformThreadInit(_THIS)
  25.292 +{
  25.293 +    /* this thread uses COM. */
  25.294 +    if (SUCCEEDED(WIN_CoInitialize())) {    /* can't report errors, hope it worked! */
  25.295 +        this->hidden->coinitialized = SDL_TRUE;
  25.296 +    }
  25.297 +
  25.298 +    /* Set this thread to very high "Pro Audio" priority. */
  25.299 +    if (pAvSetMmThreadCharacteristicsW) {
  25.300 +        DWORD idx = 0;
  25.301 +        this->hidden->task = pAvSetMmThreadCharacteristicsW(TEXT("Pro Audio"), &idx);
  25.302 +    }
  25.303 +}
  25.304 +
  25.305 +void
  25.306 +WASAPI_PlatformThreadDeinit(_THIS)
  25.307 +{
  25.308 +    /* Set this thread back to normal priority. */
  25.309 +    if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
  25.310 +        pAvRevertMmThreadCharacteristics(this->hidden->task);
  25.311 +        this->hidden->task = NULL;
  25.312 +    }
  25.313 +
  25.314 +    if (this->hidden->coinitialized) {
  25.315 +        WIN_CoUninitialize();
  25.316 +        this->hidden->coinitialized = SDL_FALSE;
  25.317 +    }
  25.318 +}
  25.319 +
  25.320 +int
  25.321 +WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
  25.322 +{
  25.323 +    LPCWSTR devid = this->hidden->devid;
  25.324 +    IMMDevice *device = NULL;
  25.325 +    HRESULT ret;
  25.326 +
  25.327 +    if (devid == NULL) {
  25.328 +        const EDataFlow dataflow = this->iscapture ? eCapture : eRender;
  25.329 +        ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_WASAPI_role, &device);
  25.330 +    } else {
  25.331 +        ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, &device);
  25.332 +    }
  25.333 +
  25.334 +    if (FAILED(ret)) {
  25.335 +        SDL_assert(device == NULL);
  25.336 +        this->hidden->client = NULL;
  25.337 +        return WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret);
  25.338 +    }
  25.339 +
  25.340 +    /* this is not async in standard win32, yay! */
  25.341 +    ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &this->hidden->client);
  25.342 +    IMMDevice_Release(device);
  25.343 +
  25.344 +    if (FAILED(ret)) {
  25.345 +        SDL_assert(this->hidden->client == NULL);
  25.346 +        return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
  25.347 +    }
  25.348 +
  25.349 +    SDL_assert(this->hidden->client != NULL);
  25.350 +    if (WASAPI_PrepDevice(this, isrecovery) == -1) {   /* not async, fire it right away. */
  25.351 +        return -1;
  25.352 +    }
  25.353 +
  25.354 +    return 0;  /* good to go. */
  25.355 +}
  25.356 +
  25.357 +
  25.358 +static void
  25.359 +WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
  25.360 +{
  25.361 +    IMMDeviceCollection *collection = NULL;
  25.362 +    UINT i, total;
  25.363 +
  25.364 +    /* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
  25.365 +       ...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */
  25.366 +
  25.367 +    if (FAILED(IMMDeviceEnumerator_EnumAudioEndpoints(enumerator, iscapture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &collection))) {
  25.368 +        return;
  25.369 +    }
  25.370 +
  25.371 +    if (FAILED(IMMDeviceCollection_GetCount(collection, &total))) {
  25.372 +        IMMDeviceCollection_Release(collection);
  25.373 +        return;
  25.374 +    }
  25.375 +
  25.376 +    for (i = 0; i < total; i++) {
  25.377 +        IMMDevice *device = NULL;
  25.378 +        if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
  25.379 +            LPWSTR devid = NULL;
  25.380 +            if (SUCCEEDED(IMMDevice_GetId(device, &devid))) {
  25.381 +                char *devname = GetWasapiDeviceName(device);
  25.382 +                if (devname) {
  25.383 +                    WASAPI_AddDevice(iscapture, devname, devid);
  25.384 +                    SDL_free(devname);
  25.385 +                }
  25.386 +                CoTaskMemFree(devid);
  25.387 +            }
  25.388 +            IMMDevice_Release(device);
  25.389 +        }
  25.390 +    }
  25.391 +
  25.392 +    IMMDeviceCollection_Release(collection);
  25.393 +}
  25.394 +
  25.395 +void
  25.396 +WASAPI_EnumerateEndpoints(void)
  25.397 +{
  25.398 +    WASAPI_EnumerateEndpointsForFlow(SDL_FALSE);  /* playback */
  25.399 +    WASAPI_EnumerateEndpointsForFlow(SDL_TRUE);  /* capture */
  25.400 +
  25.401 +    /* if this fails, we just won't get hotplug events. Carry on anyhow. */
  25.402 +    IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *) &notification_client);
  25.403 +}
  25.404 +
  25.405 +void
  25.406 +WASAPI_PlatformDeleteActivationHandler(void *handler)
  25.407 +{
  25.408 +    /* not asynchronous. */
  25.409 +    SDL_assert(!"This function should have only be called on WinRT.");
  25.410 +}
  25.411 +
  25.412 +void
  25.413 +WASAPI_BeginLoopIteration(_THIS)
  25.414 +{
  25.415 +    /* no-op. */
  25.416 +}
  25.417 +
  25.418 +#endif  /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
  25.419 +
  25.420 +/* vi: set ts=4 sw=4 expandtab: */
  25.421 +
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/audio/wasapi/SDL_wasapi_winrt.cpp	Wed Dec 06 12:24:32 2017 -0500
    26.3 @@ -0,0 +1,276 @@
    26.4 +/*
    26.5 +  Simple DirectMedia Layer
    26.6 +  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    26.7 +
    26.8 +  This software is provided 'as-is', without any express or implied
    26.9 +  warranty.  In no event will the authors be held liable for any damages
   26.10 +  arising from the use of this software.
   26.11 +
   26.12 +  Permission is granted to anyone to use this software for any purpose,
   26.13 +  including commercial applications, and to alter it and redistribute it
   26.14 +  freely, subject to the following restrictions:
   26.15 +
   26.16 +  1. The origin of this software must not be misrepresented; you must not
   26.17 +     claim that you wrote the original software. If you use this software
   26.18 +     in a product, an acknowledgment in the product documentation would be
   26.19 +     appreciated but is not required.
   26.20 +  2. Altered source versions must be plainly marked as such, and must not be
   26.21 +     misrepresented as being the original software.
   26.22 +  3. This notice may not be removed or altered from any source distribution.
   26.23 +*/
   26.24 +
   26.25 +#include "../../SDL_internal.h"
   26.26 +
   26.27 +// This is C++/CX code that the WinRT port uses to talk to WASAPI-related
   26.28 +//  system APIs. The C implementation of these functions, for non-WinRT apps,
   26.29 +//  is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard
   26.30 +//  Windows and WinRT builds to deal with audio and calls into these functions.
   26.31 +
   26.32 +#if SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
   26.33 +
   26.34 +#include <Windows.h>
   26.35 +#include <windows.ui.core.h>
   26.36 +#include <windows.devices.enumeration.h>
   26.37 +#include <windows.media.devices.h>
   26.38 +#include <wrl/implements.h>
   26.39 +
   26.40 +extern "C" {
   26.41 +#include "../../core/windows/SDL_windows.h"
   26.42 +#include "SDL_audio.h"
   26.43 +#include "SDL_timer.h"
   26.44 +#include "../SDL_audio_c.h"
   26.45 +#include "../SDL_sysaudio.h"
   26.46 +#include "SDL_assert.h"
   26.47 +#include "SDL_log.h"
   26.48 +}
   26.49 +
   26.50 +#define COBJMACROS
   26.51 +#include <mmdeviceapi.h>
   26.52 +#include <audioclient.h>
   26.53 +
   26.54 +#include "SDL_wasapi.h"
   26.55 +
   26.56 +using namespace Windows::Devices::Enumeration;
   26.57 +using namespace Windows::Media::Devices;
   26.58 +using namespace Windows::Foundation;
   26.59 +using namespace Microsoft::WRL;
   26.60 +
   26.61 +class SDL_WasapiDeviceEventHandler
   26.62 +{
   26.63 +public:
   26.64 +    SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture);
   26.65 +    ~SDL_WasapiDeviceEventHandler();
   26.66 +    void OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ args);
   26.67 +    void OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
   26.68 +    void OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
   26.69 +    void OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args);
   26.70 +    void OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args);
   26.71 +
   26.72 +private:
   26.73 +    const SDL_bool iscapture;
   26.74 +    DeviceWatcher^ watcher;
   26.75 +    Windows::Foundation::EventRegistrationToken added_handler;
   26.76 +    Windows::Foundation::EventRegistrationToken removed_handler;
   26.77 +    Windows::Foundation::EventRegistrationToken updated_handler;
   26.78 +    Windows::Foundation::EventRegistrationToken default_changed_handler;
   26.79 +};
   26.80 +
   26.81 +SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture)
   26.82 +    : iscapture(_iscapture)
   26.83 +    , watcher(DeviceInformation::CreateWatcher(_iscapture ? DeviceClass::AudioCapture : DeviceClass::AudioRender))
   26.84 +{
   26.85 +    if (!watcher)
   26.86 +        return;  // uhoh.
   26.87 +
   26.88 +    // !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan.
   26.89 +    added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher^, DeviceInformation^>([this](DeviceWatcher^ sender, DeviceInformation^ args) { OnDeviceAdded(sender, args); } );
   26.90 +    removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceRemoved(sender, args); } );
   26.91 +    updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceUpdated(sender, args); } );
   26.92 +    if (iscapture) {
   26.93 +        default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioCaptureDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) { OnDefaultCaptureDeviceChanged(sender, args); } );
   26.94 +    } else {
   26.95 +        default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioRenderDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) { OnDefaultRenderDeviceChanged(sender, args); } );
   26.96 +    }
   26.97 +    watcher->Start();
   26.98 +}
   26.99 +
  26.100 +SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler()
  26.101 +{
  26.102 +    if (watcher) {
  26.103 +        watcher->Added -= added_handler;
  26.104 +        watcher->Removed -= removed_handler;
  26.105 +        watcher->Updated -= updated_handler;
  26.106 +        watcher->Stop();
  26.107 +        watcher = nullptr;
  26.108 +    }
  26.109 +
  26.110 +    if (iscapture) {
  26.111 +        MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler;
  26.112 +    } else {
  26.113 +        MediaDevice::DefaultAudioRenderDeviceChanged -= default_changed_handler;
  26.114 +    }
  26.115 +}
  26.116 +
  26.117 +void
  26.118 +SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ info)
  26.119 +{
  26.120 +    SDL_assert(sender == this->watcher);
  26.121 +    char *utf8dev = WIN_StringToUTF8(info->Name->Data());
  26.122 +    if (utf8dev) {
  26.123 +        WASAPI_AddDevice(this->iscapture, utf8dev, info->Id->Data());
  26.124 +        SDL_free(utf8dev);
  26.125 +    }
  26.126 +}
  26.127 +
  26.128 +void
  26.129 +SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ info)
  26.130 +{
  26.131 +    SDL_assert(sender == this->watcher);
  26.132 +    WASAPI_RemoveDevice(this->iscapture, info->Id->Data());
  26.133 +}
  26.134 +
  26.135 +void
  26.136 +SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args)
  26.137 +{
  26.138 +    SDL_assert(sender == this->watcher);
  26.139 +}
  26.140 +
  26.141 +void
  26.142 +SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args)
  26.143 +{
  26.144 +    SDL_assert(this->iscapture);
  26.145 +    SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1);
  26.146 +}
  26.147 +
  26.148 +void
  26.149 +SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args)
  26.150 +{
  26.151 +    SDL_assert(!this->iscapture);
  26.152 +    SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1);
  26.153 +}
  26.154 +
  26.155 +
  26.156 +static SDL_WasapiDeviceEventHandler *playback_device_event_handler;
  26.157 +static SDL_WasapiDeviceEventHandler *capture_device_event_handler;
  26.158 +
  26.159 +int WASAPI_PlatformInit(void)
  26.160 +{
  26.161 +    return 0;
  26.162 +}
  26.163 +
  26.164 +void WASAPI_PlatformDeinit(void)
  26.165 +{
  26.166 +    delete playback_device_event_handler;
  26.167 +    playback_device_event_handler = nullptr;
  26.168 +    delete capture_device_event_handler;
  26.169 +    capture_device_event_handler = nullptr;
  26.170 +}
  26.171 +
  26.172 +void WASAPI_EnumerateEndpoints(void)
  26.173 +{
  26.174 +    // DeviceWatchers will fire an Added event for each existing device at
  26.175 +    //  startup, so we don't need to enumerate them separately before
  26.176 +    //  listening for updates.
  26.177 +    playback_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_FALSE);
  26.178 +    capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE);
  26.179 +}
  26.180 +
  26.181 +struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
  26.182 +{
  26.183 +    SDL_WasapiActivationHandler() : device(nullptr) {}
  26.184 +    STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation);
  26.185 +    SDL_AudioDevice *device;
  26.186 +};
  26.187 +
  26.188 +HRESULT
  26.189 +SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
  26.190 +{
  26.191 +    HRESULT result = S_OK;
  26.192 +    IUnknown *iunknown = nullptr;
  26.193 +    const HRESULT ret = async->GetActivateResult(&result, &iunknown);
  26.194 +
  26.195 +    if (SUCCEEDED(ret) && SUCCEEDED(result)) {
  26.196 +        iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client));
  26.197 +        if (device->hidden->client) {
  26.198 +            // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
  26.199 +            SDL_AtomicSet(&device->hidden->just_activated, 1);
  26.200 +        }
  26.201 +    }
  26.202 +
  26.203 +    WASAPI_UnrefDevice(device);
  26.204 +
  26.205 +    return S_OK;
  26.206 +}
  26.207 +
  26.208 +void
  26.209 +WASAPI_PlatformDeleteActivationHandler(void *handler)
  26.210 +{
  26.211 +    ((SDL_WasapiActivationHandler *) handler)->Release();
  26.212 +}
  26.213 +
  26.214 +int
  26.215 +WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
  26.216 +{
  26.217 +    LPCWSTR devid = _this->hidden->devid;
  26.218 +    Platform::String^ defdevid;
  26.219 +
  26.220 +    if (devid == nullptr) {
  26.221 +        defdevid = _this->iscapture ? MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) : MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
  26.222 +        if (defdevid) {
  26.223 +            devid = defdevid->Data();
  26.224 +        }
  26.225 +    }
  26.226 +
  26.227 +    SDL_AtomicSet(&_this->hidden->just_activated, 0);
  26.228 +
  26.229 +    ComPtr<SDL_WasapiActivationHandler> handler = Make<SDL_WasapiActivationHandler>();
  26.230 +    if (handler == nullptr) {
  26.231 +        return SDL_SetError("Failed to allocate WASAPI activation handler");
  26.232 +    }
  26.233 +
  26.234 +    handler.Get()->AddRef();  // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc.
  26.235 +    handler.Get()->device = _this;
  26.236 +    _this->hidden->activation_handler = handler.Get();
  26.237 +
  26.238 +    WASAPI_RefDevice(_this);  /* completion handler will unref it. */
  26.239 +    IActivateAudioInterfaceAsyncOperation *async = nullptr;
  26.240 +    const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
  26.241 +
  26.242 +    if (async != nullptr) {
  26.243 +        async->Release();
  26.244 +    }
  26.245 +
  26.246 +    if (FAILED(ret)) {
  26.247 +        handler.Get()->Release();
  26.248 +        WASAPI_UnrefDevice(_this);
  26.249 +        return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
  26.250 +    }
  26.251 +
  26.252 +    return 0;
  26.253 +}
  26.254 +
  26.255 +void
  26.256 +WASAPI_BeginLoopIteration(_THIS)
  26.257 +{
  26.258 +    if (SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
  26.259 +        if (WASAPI_PrepDevice(_this, SDL_TRUE) == -1) {
  26.260 +            SDL_OpenedAudioDeviceDisconnected(_this);
  26.261 +        } 
  26.262 +    }
  26.263 +}
  26.264 +
  26.265 +void
  26.266 +WASAPI_PlatformThreadInit(_THIS)
  26.267 +{
  26.268 +    // !!! FIXME: set this thread to "Pro Audio" priority.
  26.269 +}
  26.270 +
  26.271 +void
  26.272 +WASAPI_PlatformThreadDeinit(_THIS)
  26.273 +{
  26.274 +    // !!! FIXME: set this thread to "Pro Audio" priority.
  26.275 +}
  26.276 +
  26.277 +#endif  // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
  26.278 +
  26.279 +/* vi: set ts=4 sw=4 expandtab: */
    27.1 --- a/src/audio/xaudio2/SDL_xaudio2.c	Wed Dec 06 13:48:51 2017 -0500
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,505 +0,0 @@
    27.4 -/*
    27.5 -  Simple DirectMedia Layer
    27.6 -  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    27.7 -
    27.8 -  This software is provided 'as-is', without any express or implied
    27.9 -  warranty.  In no event will the authors be held liable for any damages
   27.10 -  arising from the use of this software.
   27.11 -
   27.12 -  Permission is granted to anyone to use this software for any purpose,
   27.13 -  including commercial applications, and to alter it and redistribute it
   27.14 -  freely, subject to the following restrictions:
   27.15 -
   27.16 -  1. The origin of this software must not be misrepresented; you must not
   27.17 -     claim that you wrote the original software. If you use this software
   27.18 -     in a product, an acknowledgment in the product documentation would be
   27.19 -     appreciated but is not required.
   27.20 -  2. Altered source versions must be plainly marked as such, and must not be
   27.21 -     misrepresented as being the original software.
   27.22 -  3. This notice may not be removed or altered from any source distribution.
   27.23 -*/
   27.24 -
   27.25 -/* WinRT NOTICE:
   27.26 -
   27.27 -   A few changes to SDL's XAudio2 backend were warranted by API
   27.28 -   changes to Windows.  Many, but not all of these are documented by Microsoft
   27.29 -   at:
   27.30 -   http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
   27.31 -
   27.32 -   1. Windows' thread synchronization function, CreateSemaphore, was removed
   27.33 -      from WinRT.  SDL's semaphore API was substituted instead.
   27.34 -   2. The method calls, IXAudio2::GetDeviceCount and IXAudio2::GetDeviceDetails
   27.35 -      were removed from the XAudio2 API.  Microsoft is telling developers to
   27.36 -      use APIs in Windows::Foundation instead.
   27.37 -      For SDL, the missing methods were reimplemented using the APIs Microsoft
   27.38 -      said to use.
   27.39 -   3. CoInitialize and CoUninitialize are not available in WinRT.
   27.40 -      These calls were removed, as COM will have been initialized earlier,
   27.41 -      at least by the call to the WinRT app's main function
   27.42 -      (aka 'int main(Platform::Array<Platform::String^>^)).  (DLudwig:
   27.43 -      This was my understanding of how WinRT: the 'main' function uses
   27.44 -      a tag of [MTAThread], which should initialize COM.  My understanding
   27.45 -      of COM is somewhat limited, and I may be incorrect here.)
   27.46 -   4. IXAudio2::CreateMasteringVoice changed its integer-based 'DeviceIndex'
   27.47 -      argument to a string-based one, 'szDeviceId'.  In WinRT, the
   27.48 -      string-based argument will be used.
   27.49 -*/
   27.50 -#include "../../SDL_internal.h"
   27.51 -
   27.52 -#if SDL_AUDIO_DRIVER_XAUDIO2
   27.53 -
   27.54 -#include "../../core/windows/SDL_windows.h"
   27.55 -#include "SDL_audio.h"
   27.56 -#include "../SDL_audio_c.h"
   27.57 -#include "../SDL_sysaudio.h"
   27.58 -#include "SDL_assert.h"
   27.59 -
   27.60 -#ifdef __GNUC__
   27.61 -/* The configure script already did any necessary checking */
   27.62 -#  define SDL_XAUDIO2_HAS_SDK 1
   27.63 -#elif defined(__WINRT__)
   27.64 -/* WinRT always has access to the XAudio 2 SDK (albeit with a header file
   27.65 -   that doesn't compile as C code).
   27.66 -*/
   27.67 -#  define SDL_XAUDIO2_HAS_SDK
   27.68 -#include "SDL_xaudio2.h"    /* ... compiles as C code, in contrast to XAudio2 headers
   27.69 -                               in the Windows SDK, v.10.0.10240.0 (Win 10's initial SDK)
   27.70 -                             */
   27.71 -#else
   27.72 -/* XAudio2 exists in the last DirectX SDK as well as the latest Windows SDK.
   27.73 -   To enable XAudio2 support, you will need to add the location of your DirectX SDK headers to
   27.74 -   the SDL projects additional include directories and then set SDL_XAUDIO2_HAS_SDK=1 as a
   27.75 -   preprocessor define
   27.76 - */
   27.77 -#if 0 /* See comment above */
   27.78 -#include <dxsdkver.h>
   27.79 -#if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
   27.80 -#  pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
   27.81 -#else
   27.82 -#  define SDL_XAUDIO2_HAS_SDK 1
   27.83 -#endif
   27.84 -#endif /* 0 */
   27.85 -#endif /* __GNUC__ */
   27.86 -
   27.87 -#ifdef SDL_XAUDIO2_HAS_SDK
   27.88 -
   27.89 -/* Check to see if we're compiling for XAudio 2.8, or higher. */
   27.90 -#ifdef WINVER
   27.91 -#if WINVER >= 0x0602  /* Windows 8 SDK or higher? */
   27.92 -#define SDL_XAUDIO2_WIN8 1
   27.93 -#endif
   27.94 -#endif
   27.95 -
   27.96 -#if !defined(SDL_XAUDIO2_H_)
   27.97 -#define INITGUID 1
   27.98 -#include <xaudio2.h>
   27.99 -#endif
  27.100 -
  27.101 -/* Hidden "this" pointer for the audio functions */
  27.102 -#define _THIS   SDL_AudioDevice *this
  27.103 -
  27.104 -#ifdef __WINRT__
  27.105 -#include "SDL_xaudio2_winrthelpers.h"
  27.106 -#endif
  27.107 -
  27.108 -/* Fixes bug 1210 where some versions of gcc need named parameters */
  27.109 -#ifdef __GNUC__
  27.110 -#ifdef THIS
  27.111 -#undef THIS
  27.112 -#endif
  27.113 -#define THIS    INTERFACE *p
  27.114 -#ifdef THIS_
  27.115 -#undef THIS_
  27.116 -#endif
  27.117 -#define THIS_   INTERFACE *p,
  27.118 -#endif
  27.119 -
  27.120 -struct SDL_PrivateAudioData
  27.121 -{
  27.122 -    IXAudio2 *ixa2;
  27.123 -    IXAudio2SourceVoice *source;
  27.124 -    IXAudio2MasteringVoice *mastering;
  27.125 -    SDL_sem * semaphore;
  27.126 -    Uint8 *mixbuf;
  27.127 -    int mixlen;
  27.128 -    Uint8 *nextbuf;
  27.129 -};
  27.130 -
  27.131 -
  27.132 -static void
  27.133 -XAUDIO2_DetectDevices(void)
  27.134 -{
  27.135 -    IXAudio2 *ixa2 = NULL;
  27.136 -    UINT32 devcount = 0;
  27.137 -    UINT32 i = 0;
  27.138 -
  27.139 -    if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
  27.140 -        SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
  27.141 -        return;
  27.142 -    } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
  27.143 -        SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
  27.144 -        IXAudio2_Release(ixa2);
  27.145 -        return;
  27.146 -    }
  27.147 -
  27.148 -    for (i = 0; i < devcount; i++) {
  27.149 -        XAUDIO2_DEVICE_DETAILS details;
  27.150 -        if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
  27.151 -            char *str = WIN_StringToUTF8(details.DisplayName);
  27.152 -            if (str != NULL) {
  27.153 -                SDL_AddAudioDevice(SDL_FALSE, str, (void *) ((size_t) i+1));
  27.154 -                SDL_free(str);  /* SDL_AddAudioDevice made a copy of the string. */
  27.155 -            }
  27.156 -        }
  27.157 -    }
  27.158 -
  27.159 -    IXAudio2_Release(ixa2);
  27.160 -}
  27.161 -
  27.162 -static void STDMETHODCALLTYPE
  27.163 -VoiceCBOnBufferEnd(THIS_ void *data)
  27.164 -{
  27.165 -    /* Just signal the SDL audio thread and get out of XAudio2's way. */
  27.166 -    SDL_AudioDevice *this = (SDL_AudioDevice *) data;
  27.167 -    SDL_SemPost(this->hidden->semaphore);
  27.168 -}
  27.169 -
  27.170 -static void STDMETHODCALLTYPE
  27.171 -VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
  27.172 -{
  27.173 -    SDL_AudioDevice *this = (SDL_AudioDevice *) data;
  27.174 -    SDL_OpenedAudioDeviceDisconnected(this);
  27.175 -}
  27.176 -
  27.177 -/* no-op callbacks... */
  27.178 -static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
  27.179 -static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
  27.180 -static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
  27.181 -static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
  27.182 -static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
  27.183 -
  27.184 -
  27.185 -static Uint8 *
  27.186 -XAUDIO2_GetDeviceBuf(_THIS)
  27.187 -{
  27.188 -    return this->hidden->nextbuf;
  27.189 -}
  27.190 -
  27.191 -static void
  27.192 -XAUDIO2_PlayDevice(_THIS)
  27.193 -{
  27.194 -    XAUDIO2_BUFFER buffer;
  27.195 -    Uint8 *mixbuf = this->hidden->mixbuf;
  27.196 -    Uint8 *nextbuf = this->hidden->nextbuf;
  27.197 -    const int mixlen = this->hidden->mixlen;
  27.198 -    IXAudio2SourceVoice *source = this->hidden->source;
  27.199 -    HRESULT result = S_OK;
  27.200 -
  27.201 -    if (!SDL_AtomicGet(&this->enabled)) { /* shutting down? */
  27.202 -        return;
  27.203 -    }
  27.204 -
  27.205 -    /* Submit the next filled buffer */
  27.206 -    SDL_zero(buffer);
  27.207 -    buffer.AudioBytes = mixlen;
  27.208 -    buffer.pAudioData = nextbuf;
  27.209 -    buffer.pContext = this;
  27.210 -
  27.211 -    if (nextbuf == mixbuf) {
  27.212 -        nextbuf += mixlen;
  27.213 -    } else {
  27.214 -        nextbuf = mixbuf;
  27.215 -    }
  27.216 -    this->hidden->nextbuf = nextbuf;
  27.217 -
  27.218 -    result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
  27.219 -    if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
  27.220 -        /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
  27.221 -    }
  27.222 -
  27.223 -    if (result != S_OK) {  /* uhoh, panic! */
  27.224 -        IXAudio2SourceVoice_FlushSourceBuffers(source);
  27.225 -        SDL_OpenedAudioDeviceDisconnected(this);
  27.226 -    }
  27.227 -}
  27.228 -
  27.229 -static void
  27.230 -XAUDIO2_WaitDevice(_THIS)
  27.231 -{
  27.232 -    if (SDL_AtomicGet(&this->enabled)) {
  27.233 -        SDL_SemWait(this->hidden->semaphore);
  27.234 -    }
  27.235 -}
  27.236 -
  27.237 -static void
  27.238 -XAUDIO2_PrepareToClose(_THIS)
  27.239 -{
  27.240 -    IXAudio2SourceVoice *source = this->hidden->source;
  27.241 -    if (source) {
  27.242 -        IXAudio2SourceVoice_Discontinuity(source);
  27.243 -    }
  27.244 -}
  27.245 -
  27.246 -static void
  27.247 -XAUDIO2_CloseDevice(_THIS)
  27.248 -{
  27.249 -    IXAudio2 *ixa2 = this->hidden->ixa2;
  27.250 -    IXAudio2SourceVoice *source = this->hidden->source;
  27.251 -    IXAudio2MasteringVoice *mastering = this->hidden->mastering;
  27.252 -
  27.253 -    if (source != NULL) {
  27.254 -        IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
  27.255 -        IXAudio2SourceVoice_FlushSourceBuffers(source);
  27.256 -        IXAudio2SourceVoice_DestroyVoice(source);
  27.257 -    }
  27.258 -    if (ixa2 != NULL) {
  27.259 -        IXAudio2_StopEngine(ixa2);
  27.260 -    }
  27.261 -    if (mastering != NULL) {
  27.262 -        IXAudio2MasteringVoice_DestroyVoice(mastering);
  27.263 -    }
  27.264 -    if (ixa2 != NULL) {
  27.265 -        IXAudio2_Release(ixa2);
  27.266 -    }
  27.267 -    if (this->hidden->semaphore != NULL) {
  27.268 -        SDL_DestroySemaphore(this->hidden->semaphore);
  27.269 -    }
  27.270 -
  27.271 -    SDL_free(this->hidden->mixbuf);
  27.272 -    SDL_free(this->hidden);
  27.273 -}
  27.274 -
  27.275 -static int
  27.276 -XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
  27.277 -{
  27.278 -    HRESULT result = S_OK;
  27.279 -    WAVEFORMATEX waveformat;
  27.280 -    int valid_format = 0;
  27.281 -    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
  27.282 -    IXAudio2 *ixa2 = NULL;
  27.283 -    IXAudio2SourceVoice *source = NULL;
  27.284 -#if defined(SDL_XAUDIO2_WIN8)
  27.285 -    LPCWSTR devId = NULL;
  27.286 -#else
  27.287 -    UINT32 devId = 0;  /* 0 == system default device. */
  27.288 -#endif
  27.289 -
  27.290 -    static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
  27.291 -        VoiceCBOnVoiceProcessPassStart,
  27.292 -        VoiceCBOnVoiceProcessPassEnd,
  27.293 -        VoiceCBOnStreamEnd,
  27.294 -        VoiceCBOnBufferStart,
  27.295 -        VoiceCBOnBufferEnd,
  27.296 -        VoiceCBOnLoopEnd,
  27.297 -        VoiceCBOnVoiceError
  27.298 -    };
  27.299 -
  27.300 -    static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
  27.301 -
  27.302 -#if defined(SDL_XAUDIO2_WIN8)
  27.303 -    /* !!! FIXME: hook up hotplugging. */
  27.304 -#else
  27.305 -    if (handle != NULL) {  /* specific device requested? */
  27.306 -        /* -1 because we increment the original value to avoid NULL. */
  27.307 -        const size_t val = ((size_t) handle) - 1;
  27.308 -        devId = (UINT32) val;
  27.309 -    }
  27.310 -#endif
  27.311 -
  27.312 -    if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
  27.313 -        return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
  27.314 -    }
  27.315 -
  27.316 -    /*
  27.317 -    XAUDIO2_DEBUG_CONFIGURATION debugConfig;
  27.318 -    debugConfig.TraceMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS | XAUDIO2_LOG_DETAIL | XAUDIO2_LOG_FUNC_CALLS | XAUDIO2_LOG_TIMING | XAUDIO2_LOG_LOCKS | XAUDIO2_LOG_MEMORY | XAUDIO2_LOG_STREAMING;
  27.319 -    debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS;
  27.320 -    debugConfig.LogThreadID = TRUE;
  27.321 -    debugConfig.LogFileline = TRUE;
  27.322 -    debugConfig.LogFunctionName = TRUE;
  27.323 -    debugConfig.LogTiming = TRUE;
  27.324 -    ixa2->SetDebugConfiguration(&debugConfig);
  27.325 -    */
  27.326 -
  27.327 -    /* Initialize all variables that we clean on shutdown */
  27.328 -    this->hidden = (struct SDL_PrivateAudioData *)
  27.329 -        SDL_malloc((sizeof *this->hidden));
  27.330 -    if (this->hidden == NULL) {
  27.331 -        IXAudio2_Release(ixa2);
  27.332 -        return SDL_OutOfMemory();
  27.333 -    }
  27.334 -    SDL_zerop(this->hidden);
  27.335 -
  27.336 -    this->hidden->ixa2 = ixa2;
  27.337 -    this->hidden->semaphore = SDL_CreateSemaphore(1);
  27.338 -    if (this->hidden->semaphore == NULL) {
  27.339 -        return SDL_SetError("XAudio2: CreateSemaphore() failed!");
  27.340 -    }
  27.341 -
  27.342 -    while ((!valid_format) && (test_format)) {
  27.343 -        switch (test_format) {
  27.344 -        case AUDIO_U8:
  27.345 -        case AUDIO_S16:
  27.346 -        case AUDIO_S32:
  27.347 -        case AUDIO_F32:
  27.348 -            this->spec.format = test_format;
  27.349 -            valid_format = 1;
  27.350 -            break;
  27.351 -        }
  27.352 -        test_format = SDL_NextAudioFormat();
  27.353 -    }
  27.354 -
  27.355 -    if (!valid_format) {
  27.356 -        return SDL_SetError("XAudio2: Unsupported audio format");
  27.357 -    }
  27.358 -
  27.359 -    /* Update the fragment size as size in bytes */
  27.360 -    SDL_CalculateAudioSpec(&this->spec);
  27.361 -
  27.362 -    /* We feed a Source, it feeds the Mastering, which feeds the device. */
  27.363 -    this->hidden->mixlen = this->spec.size;
  27.364 -    this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
  27.365 -    if (this->hidden->mixbuf == NULL) {
  27.366 -        return SDL_OutOfMemory();
  27.367 -    }
  27.368 -    this->hidden->nextbuf = this->hidden->mixbuf;
  27.369 -    SDL_memset(this->hidden->mixbuf, this->spec.silence, 2 * this->hidden->mixlen);
  27.370 -
  27.371 -    /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
  27.372 -       Xbox360, this means 5.1 output, but on Windows, it means "figure out
  27.373 -       what the system has." It might be preferable to let XAudio2 blast
  27.374 -       stereo output to appropriate surround sound configurations
  27.375 -       instead of clamping to 2 channels, even though we'll configure the
  27.376 -       Source Voice for whatever number of channels you supply. */
  27.377 -#if SDL_XAUDIO2_WIN8
  27.378 -    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
  27.379 -                                           XAUDIO2_DEFAULT_CHANNELS,
  27.380 -                                           this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects);
  27.381 -#else
  27.382 -    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
  27.383 -                                           XAUDIO2_DEFAULT_CHANNELS,
  27.384 -                                           this->spec.freq, 0, devId, NULL);
  27.385 -#endif
  27.386 -    if (result != S_OK) {
  27.387 -        return SDL_SetError("XAudio2: Couldn't create mastering voice");
  27.388 -    }
  27.389 -
  27.390 -    SDL_zero(waveformat);
  27.391 -    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
  27.392 -        waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
  27.393 -    } else {
  27.394 -        waveformat.wFormatTag = WAVE_FORMAT_PCM;
  27.395 -    }
  27.396 -    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
  27.397 -    waveformat.nChannels = this->spec.channels;
  27.398 -    waveformat.nSamplesPerSec = this->spec.freq;
  27.399 -    waveformat.nBlockAlign =
  27.400 -        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
  27.401 -    waveformat.nAvgBytesPerSec =
  27.402 -        waveformat.nSamplesPerSec * waveformat.nBlockAlign;
  27.403 -    waveformat.cbSize = sizeof(waveformat);
  27.404 -
  27.405 -#ifdef __WINRT__
  27.406 -    // DLudwig: for now, make XAudio2 do sample rate conversion, just to
  27.407 -    // get the loopwave test to work.
  27.408 -    //
  27.409 -    // TODO, WinRT: consider removing WinRT-specific source-voice creation code from SDL_xaudio2.c
  27.410 -    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
  27.411 -                                        0,
  27.412 -                                        1.0f, &callbacks, NULL, NULL);
  27.413 -#else
  27.414 -    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
  27.415 -                                        XAUDIO2_VOICE_NOSRC |
  27.416 -                                        XAUDIO2_VOICE_NOPITCH,
  27.417 -                                        1.0f, &callbacks, NULL, NULL);
  27.418 -
  27.419 -#endif
  27.420 -    if (result != S_OK) {
  27.421 -        return SDL_SetError("XAudio2: Couldn't create source voice");
  27.422 -    }
  27.423 -    this->hidden->source = source;
  27.424 -
  27.425 -    /* Start everything playing! */
  27.426 -    result = IXAudio2_StartEngine(ixa2);
  27.427 -    if (result != S_OK) {
  27.428 -        return SDL_SetError("XAudio2: Couldn't start engine");
  27.429 -    }
  27.430 -
  27.431 -    result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
  27.432 -    if (result != S_OK) {
  27.433 -        return SDL_SetError("XAudio2: Couldn't start source voice");
  27.434 -    }
  27.435 -
  27.436 -    return 0; /* good to go. */
  27.437 -}
  27.438 -
  27.439 -static void
  27.440 -XAUDIO2_Deinitialize(void)
  27.441 -{
  27.442 -#if defined(__WIN32__)
  27.443 -    WIN_CoUninitialize();
  27.444 -#endif
  27.445 -}
  27.446 -
  27.447 -#endif  /* SDL_XAUDIO2_HAS_SDK */
  27.448 -
  27.449 -
  27.450 -static int
  27.451 -XAUDIO2_Init(SDL_AudioDriverImpl * impl)
  27.452 -{
  27.453 -#ifndef SDL_XAUDIO2_HAS_SDK
  27.454 -    SDL_SetError("XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
  27.455 -    return 0;  /* no XAudio2 support, ever. Update your SDK! */
  27.456 -#else
  27.457 -    /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
  27.458 -    IXAudio2 *ixa2 = NULL;
  27.459 -    HRESULT hr = S_FALSE;
  27.460 -#if defined(__WIN32__)
  27.461 -    // TODO, WinRT: Investigate using CoInitializeEx here
  27.462 -    if (FAILED(WIN_CoInitialize())) {
  27.463 -        SDL_SetError("XAudio2: CoInitialize() failed");
  27.464 -        return 0;
  27.465 -    }
  27.466 -#endif
  27.467 -
  27.468 -    hr = XAudio2Create( &ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR );
  27.469 -    if ( hr != S_OK) {
  27.470 -#if defined(__WIN32__)
  27.471 -        WIN_CoUninitialize();
  27.472 -#endif
  27.473 -        SDL_SetError("XAudio2: XAudio2Create() failed at initialization: 0x%.8x", hr );
  27.474 -        return 0;  /* not available. */
  27.475 -    }
  27.476 -    IXAudio2_Release(ixa2);
  27.477 -
  27.478 -    /* Set the function pointers */
  27.479 -    impl->DetectDevices = XAUDIO2_DetectDevices;
  27.480 -    impl->OpenDevice = XAUDIO2_OpenDevice;
  27.481 -    impl->PlayDevice = XAUDIO2_PlayDevice;
  27.482 -    impl->WaitDevice = XAUDIO2_WaitDevice;
  27.483 -    impl->PrepareToClose = XAUDIO2_PrepareToClose;
  27.484 -    impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
  27.485 -    impl->CloseDevice = XAUDIO2_CloseDevice;
  27.486 -    impl->Deinitialize = XAUDIO2_Deinitialize;
  27.487 -
  27.488 -    /* !!! FIXME: We can apparently use a C++ interface on Windows 8
  27.489 -     * !!! FIXME: (Windows::Devices::Enumeration::DeviceInformation) for device
  27.490 -     * !!! FIXME: detection, but it's not implemented here yet.
  27.491 -     * !!! FIXME:  see http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
  27.492 -     * !!! FIXME:  for now, force the default device.
  27.493 -     */
  27.494 -#if defined(SDL_XAUDIO2_WIN8) || defined(__WINRT__)
  27.495 -    impl->OnlyHasDefaultOutputDevice = 1;
  27.496 -#endif
  27.497 -
  27.498 -    return 1;   /* this audio target is available. */
  27.499 -#endif
  27.500 -}
  27.501 -
  27.502 -AudioBootStrap XAUDIO2_bootstrap = {
  27.503 -    "xaudio2", "XAudio2", XAUDIO2_Init, 0
  27.504 -};
  27.505 -
  27.506 -#endif  /* SDL_AUDIO_DRIVER_XAUDIO2 */
  27.507 -
  27.508 -/* vi: set ts=4 sw=4 expandtab: */
    28.1 --- a/src/audio/xaudio2/SDL_xaudio2.h	Wed Dec 06 13:48:51 2017 -0500
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,386 +0,0 @@
    28.4 -/*
    28.5 -  Simple DirectMedia Layer
    28.6 -  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    28.7 -
    28.8 -  This software is provided 'as-is', without any express or implied
    28.9 -  warranty.  In no event will the authors be held liable for any damages
   28.10 -  arising from the use of this software.
   28.11 -
   28.12 -  Permission is granted to anyone to use this software for any purpose,
   28.13 -  including commercial applications, and to alter it and redistribute it
   28.14 -  freely, subject to the following restrictions:
   28.15 -
   28.16 -  1. The origin of this software must not be misrepresented; you must not
   28.17 -     claim that you wrote the original software. If you use this software
   28.18 -     in a product, an acknowledgment in the product documentation would be
   28.19 -     appreciated but is not required.
   28.20 -  2. Altered source versions must be plainly marked as such, and must not be
   28.21 -     misrepresented as being the original software.
   28.22 -  3. This notice may not be removed or altered from any source distribution.
   28.23 -*/
   28.24 -
   28.25 -#ifndef SDL_XAUDIO2_H_
   28.26 -#define SDL_XAUDIO2_H_
   28.27 -
   28.28 -#include <windows.h>
   28.29 -#include <mmreg.h>
   28.30 -#include <objbase.h>
   28.31 -
   28.32 -/* XAudio2 packs its structure members together as tightly as possible.
   28.33 -   This pragma is needed to ensure compatibility with XAudio2 on 64-bit
   28.34 -   platforms.
   28.35 -*/
   28.36 -#pragma pack(push, 1)
   28.37 -
   28.38 -typedef interface IXAudio2 IXAudio2;
   28.39 -typedef interface IXAudio2SourceVoice IXAudio2SourceVoice;
   28.40 -typedef interface IXAudio2MasteringVoice IXAudio2MasteringVoice;
   28.41 -typedef interface IXAudio2EngineCallback IXAudio2EngineCallback;
   28.42 -typedef interface IXAudio2VoiceCallback IXAudio2VoiceCallback;
   28.43 -typedef interface IXAudio2Voice IXAudio2Voice;
   28.44 -typedef interface IXAudio2SubmixVoice IXAudio2SubmixVoice;
   28.45 -
   28.46 -typedef enum _AUDIO_STREAM_CATEGORY {
   28.47 -    AudioCategory_Other = 0,
   28.48 -    AudioCategory_ForegroundOnlyMedia,
   28.49 -    AudioCategory_BackgroundCapableMedia,
   28.50 -    AudioCategory_Communications,
   28.51 -    AudioCategory_Alerts,
   28.52 -    AudioCategory_SoundEffects,
   28.53 -    AudioCategory_GameEffects,
   28.54 -    AudioCategory_GameMedia,
   28.55 -    AudioCategory_GameChat,
   28.56 -    AudioCategory_Movie,
   28.57 -    AudioCategory_Media
   28.58 -} AUDIO_STREAM_CATEGORY;
   28.59 -
   28.60 -typedef struct XAUDIO2_BUFFER {
   28.61 -    UINT32     Flags;
   28.62 -    UINT32     AudioBytes;
   28.63 -    const BYTE *pAudioData;
   28.64 -    UINT32     PlayBegin;
   28.65 -    UINT32     PlayLength;
   28.66 -    UINT32     LoopBegin;
   28.67 -    UINT32     LoopLength;
   28.68 -    UINT32     LoopCount;
   28.69 -    void       *pContext;
   28.70 -} XAUDIO2_BUFFER;
   28.71 -
   28.72 -typedef struct XAUDIO2_BUFFER_WMA {
   28.73 -    const UINT32 *pDecodedPacketCumulativeBytes;
   28.74 -    UINT32       PacketCount;
   28.75 -} XAUDIO2_BUFFER_WMA;
   28.76 -
   28.77 -typedef struct XAUDIO2_SEND_DESCRIPTOR {
   28.78 -    UINT32        Flags;
   28.79 -    IXAudio2Voice *pOutputVoice;
   28.80 -} XAUDIO2_SEND_DESCRIPTOR;
   28.81 -
   28.82 -typedef struct XAUDIO2_VOICE_SENDS {
   28.83 -    UINT32                  SendCount;
   28.84 -    XAUDIO2_SEND_DESCRIPTOR *pSends;
   28.85 -} XAUDIO2_VOICE_SENDS;
   28.86 -
   28.87 -typedef struct XAUDIO2_EFFECT_DESCRIPTOR {
   28.88 -    IUnknown *pEffect;
   28.89 -    BOOL     InitialState;
   28.90 -    UINT32   OutputChannels;
   28.91 -} XAUDIO2_EFFECT_DESCRIPTOR;
   28.92 -
   28.93 -typedef struct XAUDIO2_EFFECT_CHAIN {
   28.94 -    UINT32                    EffectCount;
   28.95 -    XAUDIO2_EFFECT_DESCRIPTOR *pEffectDescriptors;
   28.96 -} XAUDIO2_EFFECT_CHAIN;
   28.97 -
   28.98 -typedef struct XAUDIO2_PERFORMANCE_DATA {
   28.99 -    UINT64 AudioCyclesSinceLastQuery;
  28.100 -    UINT64 TotalCyclesSinceLastQuery;
  28.101 -    UINT32 MinimumCyclesPerQuantum;
  28.102 -    UINT32 MaximumCyclesPerQuantum;
  28.103 -    UINT32 MemoryUsageInBytes;
  28.104 -    UINT32 CurrentLatencyInSamples;
  28.105 -    UINT32 GlitchesSinceEngineStarted;
  28.106 -    UINT32 ActiveSourceVoiceCount;
  28.107 -    UINT32 TotalSourceVoiceCount;
  28.108 -    UINT32 ActiveSubmixVoiceCount;
  28.109 -    UINT32 ActiveResamplerCount;
  28.110 -    UINT32 ActiveMatrixMixCount;
  28.111 -    UINT32 ActiveXmaSourceVoices;
  28.112 -    UINT32 ActiveXmaStreams;
  28.113 -} XAUDIO2_PERFORMANCE_DATA;
  28.114 -
  28.115 -typedef struct XAUDIO2_DEBUG_CONFIGURATION {
  28.116 -    UINT32 TraceMask;
  28.117 -    UINT32 BreakMask;
  28.118 -    BOOL   LogThreadID;
  28.119 -    BOOL   LogFileline;
  28.120 -    BOOL   LogFunctionName;
  28.121 -    BOOL   LogTiming;
  28.122 -} XAUDIO2_DEBUG_CONFIGURATION;
  28.123 -
  28.124 -typedef struct XAUDIO2_VOICE_DETAILS {
  28.125 -    UINT32 CreationFlags;
  28.126 -    UINT32 ActiveFlags;
  28.127 -    UINT32 InputChannels;
  28.128 -    UINT32 InputSampleRate;
  28.129 -} XAUDIO2_VOICE_DETAILS;
  28.130 -
  28.131 -typedef enum XAUDIO2_FILTER_TYPE {
  28.132 -    LowPassFilter = 0,
  28.133 -    BandPassFilter = 1,
  28.134 -    HighPassFilter = 2,
  28.135 -    NotchFilter = 3,
  28.136 -    LowPassOnePoleFilter = 4,
  28.137 -    HighPassOnePoleFilter = 5
  28.138 -} XAUDIO2_FILTER_TYPE;
  28.139 -
  28.140 -typedef struct XAUDIO2_FILTER_PARAMETERS {
  28.141 -    XAUDIO2_FILTER_TYPE Type;
  28.142 -    float               Frequency;
  28.143 -    float               OneOverQ;
  28.144 -} XAUDIO2_FILTER_PARAMETERS;
  28.145 -
  28.146 -typedef struct XAUDIO2_VOICE_STATE {
  28.147 -    void   *pCurrentBufferContext;
  28.148 -    UINT32 BuffersQueued;
  28.149 -    UINT64 SamplesPlayed;
  28.150 -} XAUDIO2_VOICE_STATE;
  28.151 -
  28.152 -
  28.153 -typedef UINT32 XAUDIO2_PROCESSOR;
  28.154 -#define Processor1 0x00000001
  28.155 -#define XAUDIO2_DEFAULT_PROCESSOR Processor1
  28.156 -
  28.157 -#define XAUDIO2_E_DEVICE_INVALIDATED 0x88960004
  28.158 -#define XAUDIO2_COMMIT_NOW 0
  28.159 -#define XAUDIO2_VOICE_NOSAMPLESPLAYED 0x0100
  28.160 -#define XAUDIO2_DEFAULT_CHANNELS 0
  28.161 -
  28.162 -extern HRESULT __stdcall XAudio2Create(
  28.163 -    _Out_ IXAudio2          **ppXAudio2,
  28.164 -    _In_  UINT32            Flags,
  28.165 -    _In_  XAUDIO2_PROCESSOR XAudio2Processor
  28.166 -    );
  28.167 -
  28.168 -#undef INTERFACE
  28.169 -#define INTERFACE IXAudio2
  28.170 -typedef interface IXAudio2 {
  28.171 -    const struct IXAudio2Vtbl FAR* lpVtbl;
  28.172 -} IXAudio2;
  28.173 -typedef const struct IXAudio2Vtbl IXAudio2Vtbl;
  28.174 -const struct IXAudio2Vtbl
  28.175 -{
  28.176 -    /* IUnknown */
  28.177 -    STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
  28.178 -    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
  28.179 -    STDMETHOD_(ULONG, Release)(THIS) PURE;
  28.180 -
  28.181 -    /* IXAudio2 */
  28.182 -    STDMETHOD_(HRESULT, RegisterForCallbacks)(THIS, IXAudio2EngineCallback *pCallback) PURE;
  28.183 -    STDMETHOD_(VOID, UnregisterForCallbacks)(THIS, IXAudio2EngineCallback *pCallback) PURE;
  28.184 -    STDMETHOD_(HRESULT, CreateSourceVoice)(THIS, IXAudio2SourceVoice **ppSourceVoice,
  28.185 -                                           const WAVEFORMATEX *pSourceFormat,
  28.186 -                                           UINT32 Flags,
  28.187 -                                           float MaxFrequencyRatio,
  28.188 -                                           IXAudio2VoiceCallback *pCallback,
  28.189 -                                           const XAUDIO2_VOICE_SENDS *pSendList,
  28.190 -                                           const XAUDIO2_EFFECT_CHAIN *pEffectChain) PURE;
  28.191 -    STDMETHOD_(HRESULT, CreateSubmixVoice)(THIS, IXAudio2SubmixVoice **ppSubmixVoice,
  28.192 -                                           UINT32 InputChannels,
  28.193 -                                           UINT32 InputSampleRate,
  28.194 -                                           UINT32 Flags,
  28.195 -                                           UINT32 ProcessingStage,
  28.196 -                                           const XAUDIO2_VOICE_SENDS *pSendList,
  28.197 -                                           const XAUDIO2_EFFECT_CHAIN *pEffectChain) PURE;
  28.198 -    STDMETHOD_(HRESULT, CreateMasteringVoice)(THIS, IXAudio2MasteringVoice **ppMasteringVoice,
  28.199 -                                              UINT32 InputChannels,
  28.200 -                                              UINT32 InputSampleRate,
  28.201 -                                              UINT32 Flags,
  28.202 -                                              LPCWSTR szDeviceId,
  28.203 -                                              const XAUDIO2_EFFECT_CHAIN *pEffectChain,
  28.204 -                                              AUDIO_STREAM_CATEGORY StreamCategory) PURE;
  28.205 -    STDMETHOD_(HRESULT, StartEngine)(THIS) PURE;
  28.206 -    STDMETHOD_(VOID, StopEngine)(THIS) PURE;
  28.207 -    STDMETHOD_(HRESULT, CommitChanges)(THIS, UINT32 OperationSet) PURE;
  28.208 -    STDMETHOD_(HRESULT, GetPerformanceData)(THIS, XAUDIO2_PERFORMANCE_DATA *pPerfData) PURE;
  28.209 -    STDMETHOD_(HRESULT, SetDebugConfiguration)(THIS, XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
  28.210 -                                               VOID *pReserved) PURE;
  28.211 -};
  28.212 -
  28.213 -#define IXAudio2_Release(A) ((A)->lpVtbl->Release(A))
  28.214 -#define IXAudio2_CreateSourceVoice(A,B,C,D,E,F,G,H) ((A)->lpVtbl->CreateSourceVoice(A,B,C,D,E,F,G,H))
  28.215 -#define IXAudio2_CreateMasteringVoice(A,B,C,D,E,F,G,H) ((A)->lpVtbl->CreateMasteringVoice(A,B,C,D,E,F,G,H))
  28.216 -#define IXAudio2_StartEngine(A) ((A)->lpVtbl->StartEngine(A))
  28.217 -#define IXAudio2_StopEngine(A) ((A)->lpVtbl->StopEngine(A))
  28.218 -
  28.219 -
  28.220 -#undef INTERFACE
  28.221 -#define INTERFACE IXAudio2SourceVoice
  28.222 -typedef interface IXAudio2SourceVoice {
  28.223 -    const struct IXAudio2SourceVoiceVtbl FAR* lpVtbl;
  28.224 -} IXAudio2SourceVoice;
  28.225 -typedef const struct IXAudio2SourceVoiceVtbl IXAudio2SourceVoiceVtbl;
  28.226 -const struct IXAudio2SourceVoiceVtbl
  28.227 -{
  28.228 -    /* MSDN says that IXAudio2Voice inherits from IXAudio2, but MSVC's debugger
  28.229 -     * says otherwise, and that IXAudio2Voice doesn't inherit from any other
  28.230 -     * interface!
  28.231 -     */
  28.232 -
  28.233 -    /* IXAudio2Voice */
  28.234 -    STDMETHOD_(VOID, GetVoiceDetails)(THIS, XAUDIO2_VOICE_DETAILS *pVoiceDetails) PURE;
  28.235 -    STDMETHOD_(HRESULT, SetOutputVoices)(THIS, const XAUDIO2_VOICE_SENDS *pSendList) PURE;
  28.236 -    STDMETHOD_(HRESULT, SetEffectChain)(THIS, const XAUDIO2_EFFECT_CHAIN *pEffectChain) PURE;
  28.237 -    STDMETHOD_(HRESULT, EnableEffect)(THIS, UINT32 EffectIndex, UINT32 OperationSet) PURE;
  28.238 -    STDMETHOD_(HRESULT, DisableEffect)(THIS, UINT32 EffectIndex, UINT32 OperationSet) PURE;
  28.239 -    STDMETHOD_(VOID, GetEffectState)(THIS, UINT32 EffectIndex, BOOL *pEnabled) PURE;
  28.240 -    STDMETHOD_(HRESULT, SetEffectParameters)(THIS, UINT32 EffectIndex,
  28.241 -                                             const void *pParameters,
  28.242 -                                             UINT32 ParametersByteSize,
  28.243 -                                             UINT32 OperationSet) PURE;
  28.244 -    STDMETHOD_(VOID, GetEffectParameters)(THIS, UINT32 EffectIndex,
  28.245 -                                          void *pParameters,
  28.246 -                                          UINT32 ParametersByteSize) PURE;
  28.247 -    STDMETHOD_(HRESULT, SetFilterParameters)(THIS, const XAUDIO2_FILTER_PARAMETERS *pParameters,
  28.248 -                                             UINT32 OperationSet) PURE;
  28.249 -    STDMETHOD_(VOID, GetFilterParameters)(THIS, XAUDIO2_FILTER_PARAMETERS *pParameters) PURE;
  28.250 -    STDMETHOD_(HRESULT, SetOutputFilterParameters)(THIS, IXAudio2Voice *pDestinationVoice,
  28.251 -                                                   XAUDIO2_FILTER_PARAMETERS *pParameters,
  28.252 -                                                   UINT32 OperationSet) PURE;
  28.253 -    STDMETHOD_(VOID, GetOutputFilterParameters)(THIS, IXAudio2Voice *pDestinationVoice,
  28.254 -                                                XAUDIO2_FILTER_PARAMETERS *pParameters) PURE;
  28.255 -    STDMETHOD_(HRESULT, SetVolume)(THIS, float Volume,
  28.256 -                                   UINT32 OperationSet) PURE;
  28.257 -    STDMETHOD_(VOID, GetVolume)(THIS, float *pVolume) PURE;
  28.258 -    STDMETHOD_(HRESULT, SetChannelVolumes)(THIS, UINT32 Channels,
  28.259 -                                           const float *pVolumes,
  28.260 -                                           UINT32 OperationSet) PURE;
  28.261 -    STDMETHOD_(VOID, GetChannelVolumes)(THIS, UINT32 Channels,
  28.262 -                                        float *pVolumes) PURE;
  28.263 -    STDMETHOD_(HRESULT, SetOutputMatrix)(THIS, IXAudio2Voice *pDestinationVoice,
  28.264 -                                         UINT32 SourceChannels,
  28.265 -                                         UINT32 DestinationChannels,
  28.266 -                                         const float *pLevelMatrix,
  28.267 -                                         UINT32 OperationSet) PURE;
  28.268 -    STDMETHOD_(VOID, GetOutputMatrix)(THIS, IXAudio2Voice *pDestinationVoice,
  28.269 -                                      UINT32 SourceChannels,
  28.270 -                                      UINT32 DestinationChannels,
  28.271 -                                      float *pLevelMatrix) PURE;
  28.272 -    STDMETHOD_(VOID, DestroyVoice)(THIS) PURE;
  28.273 -
  28.274 -    /* IXAudio2SourceVoice */
  28.275 -    STDMETHOD_(HRESULT, Start)(THIS, UINT32 Flags,
  28.276 -                               UINT32 OperationSet) PURE;
  28.277 -    STDMETHOD_(HRESULT, Stop)(THIS, UINT32 Flags,
  28.278 -                              UINT32 OperationSet) PURE;
  28.279 -    STDMETHOD_(HRESULT, SubmitSourceBuffer)(THIS, const XAUDIO2_BUFFER *pBuffer,
  28.280 -                                            const XAUDIO2_BUFFER_WMA *pBufferWMA) PURE;
  28.281 -    STDMETHOD_(HRESULT, FlushSourceBuffers)(THIS) PURE;
  28.282 -    STDMETHOD_(HRESULT, Discontinuity)(THIS) PURE;
  28.283 -    STDMETHOD_(HRESULT, ExitLoop)(THIS, UINT32 OperationSet) PURE;
  28.284 -    STDMETHOD_(VOID, GetState)(THIS, XAUDIO2_VOICE_STATE *pVoiceState,
  28.285 -                               UINT32 Flags) PURE;
  28.286 -    STDMETHOD_(HRESULT, SetFrequencyRatio)(THIS, float Ratio,
  28.287 -                                           UINT32 OperationSet) PURE;
  28.288 -    STDMETHOD_(VOID, GetFrequencyRatio)(THIS, float *pRatio) PURE;
  28.289 -    STDMETHOD_(HRESULT, SetSourceSampleRate)(THIS, UINT32 NewSourceSampleRate) PURE;
  28.290 -};
  28.291 -
  28.292 -#define IXAudio2SourceVoice_DestroyVoice(A) ((A)->lpVtbl->DestroyVoice(A))
  28.293 -#define IXAudio2SourceVoice_Start(A,B,C) ((A)->lpVtbl->Start(A,B,C))
  28.294 -#define IXAudio2SourceVoice_Stop(A,B,C) ((A)->lpVtbl->Stop(A,B,C))
  28.295 -#define IXAudio2SourceVoice_SubmitSourceBuffer(A,B,C) ((A)->lpVtbl->SubmitSourceBuffer(A,B,C))
  28.296 -#define IXAudio2SourceVoice_FlushSourceBuffers(A) ((A)->lpVtbl->FlushSourceBuffers(A))
  28.297 -#define IXAudio2SourceVoice_Discontinuity(A) ((A)->lpVtbl->Discontinuity(A))
  28.298 -#define IXAudio2SourceVoice_GetState(A,B,C) ((A)->lpVtbl->GetState(A,B,C))
  28.299 -
  28.300 -
  28.301 -#undef INTERFACE
  28.302 -#define INTERFACE IXAudio2MasteringVoice
  28.303 -typedef interface IXAudio2MasteringVoice {
  28.304 -    const struct IXAudio2MasteringVoiceVtbl FAR* lpVtbl;
  28.305 -} IXAudio2MasteringVoice;
  28.306 -typedef const struct IXAudio2MasteringVoiceVtbl IXAudio2MasteringVoiceVtbl;
  28.307 -const struct IXAudio2MasteringVoiceVtbl
  28.308 -{
  28.309 -    /* MSDN says that IXAudio2Voice inherits from IXAudio2, but MSVC's debugger
  28.310 -     * says otherwise, and that IXAudio2Voice doesn't inherit from any other
  28.311 -     * interface!
  28.312 -     */
  28.313 -
  28.314 -    /* IXAudio2Voice */
  28.315 -    STDMETHOD_(VOID, GetVoiceDetails)(THIS, XAUDIO2_VOICE_DETAILS *pVoiceDetails) PURE;
  28.316 -    STDMETHOD_(HRESULT, SetOutputVoices)(THIS, const XAUDIO2_VOICE_SENDS *pSendList) PURE;
  28.317 -    STDMETHOD_(HRESULT, SetEffectChain)(THIS, const XAUDIO2_EFFECT_CHAIN *pEffectChain) PURE;
  28.318 -    STDMETHOD_(HRESULT, EnableEffect)(THIS, UINT32 EffectIndex, UINT32 OperationSet) PURE;
  28.319 -    STDMETHOD_(HRESULT, DisableEffect)(THIS, UINT32 EffectIndex, UINT32 OperationSet) PURE;
  28.320 -    STDMETHOD_(VOID, GetEffectState)(THIS, UINT32 EffectIndex, BOOL *pEnabled) PURE;
  28.321 -    STDMETHOD_(HRESULT, SetEffectParameters)(THIS, UINT32 EffectIndex,
  28.322 -                                             const void *pParameters,
  28.323 -                                             UINT32 ParametersByteSize,
  28.324 -                                             UINT32 OperationSet) PURE;
  28.325 -    STDMETHOD_(VOID, GetEffectParameters)(THIS, UINT32 EffectIndex,
  28.326 -                                          void *pParameters,
  28.327 -                                          UINT32 ParametersByteSize) PURE;
  28.328 -    STDMETHOD_(HRESULT, SetFilterParameters)(THIS, const XAUDIO2_FILTER_PARAMETERS *pParameters,
  28.329 -                                             UINT32 OperationSet) PURE;
  28.330 -    STDMETHOD_(VOID, GetFilterParameters)(THIS, XAUDIO2_FILTER_PARAMETERS *pParameters) PURE;
  28.331 -    STDMETHOD_(HRESULT, SetOutputFilterParameters)(THIS, IXAudio2Voice *pDestinationVoice,
  28.332 -                                                   XAUDIO2_FILTER_PARAMETERS *pParameters,
  28.333 -                                                   UINT32 OperationSet) PURE;
  28.334 -    STDMETHOD_(VOID, GetOutputFilterParameters)(THIS, IXAudio2Voice *pDestinationVoice,
  28.335 -                                                XAUDIO2_FILTER_PARAMETERS *pParameters) PURE;
  28.336 -    STDMETHOD_(HRESULT, SetVolume)(THIS, float Volume,
  28.337 -                                   UINT32 OperationSet) PURE;
  28.338 -    STDMETHOD_(VOID, GetVolume)(THIS, float *pVolume) PURE;
  28.339 -    STDMETHOD_(HRESULT, SetChannelVolumes)(THIS, UINT32 Channels,
  28.340 -                                           const float *pVolumes,
  28.341 -                                           UINT32 OperationSet) PURE;
  28.342 -    STDMETHOD_(VOID, GetChannelVolumes)(THIS, UINT32 Channels,
  28.343 -                                        float *pVolumes) PURE;
  28.344 -    STDMETHOD_(HRESULT, SetOutputMatrix)(THIS, IXAudio2Voice *pDestinationVoice,
  28.345 -                                         UINT32 SourceChannels,
  28.346 -                                         UINT32 DestinationChannels,
  28.347 -                                         const float *pLevelMatrix,
  28.348 -                                         UINT32 OperationSet) PURE;
  28.349 -    STDMETHOD_(VOID, GetOutputMatrix)(THIS, IXAudio2Voice *pDestinationVoice,
  28.350 -                                      UINT32 SourceChannels,
  28.351 -                                      UINT32 DestinationChannels,
  28.352 -                                      float *pLevelMatrix) PURE;
  28.353 -    STDMETHOD_(VOID, DestroyVoice)(THIS) PURE;
  28.354 -
  28.355 -    /* IXAudio2SourceVoice */
  28.356 -    STDMETHOD_(VOID, GetChannelMask)(THIS, DWORD *pChannelMask) PURE;
  28.357 -};
  28.358 -
  28.359 -#define IXAudio2MasteringVoice_DestroyVoice(A) ((A)->lpVtbl->DestroyVoice(A))
  28.360 -
  28.361 -
  28.362 -#undef INTERFACE
  28.363 -#define INTERFACE IXAudio2VoiceCallback
  28.364 -typedef interface IXAudio2VoiceCallback {
  28.365 -    const struct IXAudio2VoiceCallbackVtbl FAR* lpVtbl;
  28.366 -} IXAudio2VoiceCallback;
  28.367 -typedef const struct IXAudio2VoiceCallbackVtbl IXAudio2VoiceCallbackVtbl;
  28.368 -const struct IXAudio2VoiceCallbackVtbl
  28.369 -{
  28.370 -    /* MSDN says that IXAudio2VoiceCallback inherits from IXAudio2, but SDL's
  28.371 -     * own code says otherwise, and that IXAudio2VoiceCallback doesn't inherit
  28.372 -     * from any other interface!
  28.373 -     */
  28.374 -
  28.375 -    /* IXAudio2VoiceCallback */
  28.376 -    STDMETHOD_(VOID, OnVoiceProcessingPassStart)(THIS, UINT32 BytesRequired) PURE;
  28.377 -    STDMETHOD_(VOID, OnVoiceProcessingPassEnd)(THIS) PURE;
  28.378 -    STDMETHOD_(VOID, OnStreamEnd)(THIS) PURE;
  28.379 -    STDMETHOD_(VOID, OnBufferStart)(THIS, void *pBufferContext) PURE;
  28.380 -    STDMETHOD_(VOID, OnBufferEnd)(THIS, void *pBufferContext) PURE;
  28.381 -    STDMETHOD_(VOID, OnLoopEnd)(THIS, void *pBufferContext) PURE;
  28.382 -    STDMETHOD_(VOID, OnVoiceError)(THIS, void *pBufferContext, HRESULT Error) PURE;
  28.383 -};
  28.384 -
  28.385 -#pragma pack(pop)   /* Undo pragma push */
  28.386 -
  28.387 -#endif  /* SDL_XAUDIO2_H_ */
  28.388 -
  28.389 -/* vi: set ts=4 sw=4 expandtab: */
    29.1 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp	Wed Dec 06 13:48:51 2017 -0500
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,90 +0,0 @@
    29.4 -/*
    29.5 -  Simple DirectMedia Layer
    29.6 -  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    29.7 -
    29.8 -  This software is provided 'as-is', without any express or implied
    29.9 -  warranty.  In no event will the authors be held liable for any damages
   29.10 -  arising from the use of this software.
   29.11 -
   29.12 -  Permission is granted to anyone to use this software for any purpose,
   29.13 -  including commercial applications, and to alter it and redistribute it
   29.14 -  freely, subject to the following restrictions:
   29.15 -
   29.16 -  1. The origin of this software must not be misrepresented; you must not
   29.17 -     claim that you wrote the original software. If you use this software
   29.18 -     in a product, an acknowledgment in the product documentation would be
   29.19 -     appreciated but is not required.
   29.20 -  2. Altered source versions must be plainly marked as such, and must not be
   29.21 -     misrepresented as being the original software.
   29.22 -  3. This notice may not be removed or altered from any source distribution.
   29.23 -*/
   29.24 -#include "../../SDL_internal.h"
   29.25 -
   29.26 -#include <xaudio2.h>
   29.27 -#include "SDL_xaudio2_winrthelpers.h"
   29.28 -
   29.29 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
   29.30 -using Windows::Devices::Enumeration::DeviceClass;
   29.31 -using Windows::Devices::Enumeration::DeviceInformation;
   29.32 -using Windows::Devices::Enumeration::DeviceInformationCollection;
   29.33 -#endif
   29.34 -
   29.35 -extern "C" HRESULT __cdecl IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
   29.36 -{
   29.37 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   29.38 -    // There doesn't seem to be any audio device enumeration on Windows Phone.
   29.39 -    // In lieu of this, just treat things as if there is one and only one
   29.40 -    // audio device.
   29.41 -    *devcount = 1;
   29.42 -    return S_OK;
   29.43 -#else
   29.44 -    // TODO, WinRT: make xaudio2 device enumeration only happen once, and in the background
   29.45 -    auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
   29.46 -    while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
   29.47 -    {
   29.48 -    }
   29.49 - 
   29.50 -    DeviceInformationCollection^ devices = operation->GetResults();
   29.51 -    *devcount = devices->Size;
   29.52 -    return S_OK;
   29.53 -#endif
   29.54 -}
   29.55 -
   29.56 -extern "C" HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
   29.57 -{
   29.58 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   29.59 -    // Windows Phone doesn't seem to have the same device enumeration APIs that
   29.60 -    // Windows 8/RT has, or it doesn't have them at all.  In lieu of this,
   29.61 -    // just treat things as if there is one, and only one, default device.
   29.62 -    if (index != 0)
   29.63 -    {
   29.64 -        return XAUDIO2_E_INVALID_CALL;
   29.65 -    }
   29.66 -
   29.67 -    if (details)
   29.68 -    {
   29.69 -        wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), L"default", _TRUNCATE);
   29.70 -        wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), L"default", _TRUNCATE);
   29.71 -    }
   29.72 -    return S_OK;
   29.73 -#else
   29.74 -    auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
   29.75 -    while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
   29.76 -    {
   29.77 -    }
   29.78 - 
   29.79 -    DeviceInformationCollection^ devices = operation->GetResults();
   29.80 -    if (index >= devices->Size)
   29.81 -    {
   29.82 -        return XAUDIO2_E_INVALID_CALL;
   29.83 -    }
   29.84 -
   29.85 -    DeviceInformation^ d = devices->GetAt(index);
   29.86 -    if (details)
   29.87 -    {
   29.88 -        wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), d->Id->Data(), _TRUNCATE);
   29.89 -        wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), d->Name->Data(), _TRUNCATE);
   29.90 -    }
   29.91 -    return S_OK;
   29.92 -#endif
   29.93 -}
    30.1 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h	Wed Dec 06 13:48:51 2017 -0500
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,70 +0,0 @@
    30.4 -/*
    30.5 -  Simple DirectMedia Layer
    30.6 -  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    30.7 -
    30.8 -  This software is provided 'as-is', without any express or implied
    30.9 -  warranty.  In no event will the authors be held liable for any damages
   30.10 -  arising from the use of this software.
   30.11 -
   30.12 -  Permission is granted to anyone to use this software for any purpose,
   30.13 -  including commercial applications, and to alter it and redistribute it
   30.14 -  freely, subject to the following restrictions:
   30.15 -
   30.16 -  1. The origin of this software must not be misrepresented; you must not
   30.17 -     claim that you wrote the original software. If you use this software
   30.18 -     in a product, an acknowledgment in the product documentation would be
   30.19 -     appreciated but is not required.
   30.20 -  2. Altered source versions must be plainly marked as such, and must not be
   30.21 -     misrepresented as being the original software.
   30.22 -  3. This notice may not be removed or altered from any source distribution.
   30.23 -*/
   30.24 -
   30.25 -//
   30.26 -// Re-implementation of methods removed from XAudio2 (in WinRT):
   30.27 -//
   30.28 -
   30.29 -typedef struct XAUDIO2_DEVICE_DETAILS
   30.30 -{
   30.31 -    WCHAR DeviceID[256];
   30.32 -    WCHAR DisplayName[256];
   30.33 -    /* Other fields exist in the pre-Windows 8 version of this struct, however
   30.34 -       they weren't used by SDL, so they weren't added.
   30.35 -    */
   30.36 -} XAUDIO2_DEVICE_DETAILS;
   30.37 -
   30.38 -
   30.39 -#ifdef __cplusplus
   30.40 -extern "C" {
   30.41 -#endif
   30.42 -
   30.43 -HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
   30.44 -HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
   30.45 -
   30.46 -#ifdef __cplusplus
   30.47 -}
   30.48 -#endif
   30.49 -
   30.50 -
   30.51 -//
   30.52 -// C-style macros to call XAudio2's methods in C++:
   30.53 -//
   30.54 -#ifdef __cplusplus
   30.55 -/*
   30.56 -#define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G))
   30.57 -#define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H))
   30.58 -#define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C))
   30.59 -#define IXAudio2_Release(A) (A)->Release()
   30.60 -#define IXAudio2_StartEngine(A) (A)->StartEngine()
   30.61 -#define IXAudio2_StopEngine(A) (A)->StopEngine()
   30.62 -
   30.63 -#define IXAudio2MasteringVoice_DestroyVoice(A) (A)->DestroyVoice()
   30.64 -
   30.65 -#define IXAudio2SourceVoice_DestroyVoice(A) (A)->DestroyVoice()
   30.66 -#define IXAudio2SourceVoice_Discontinuity(A) (A)->Discontinuity()
   30.67 -#define IXAudio2SourceVoice_FlushSourceBuffers(A) (A)->FlushSourceBuffers()
   30.68 -#define IXAudio2SourceVoice_GetState(A, B) (A)->GetState((B))
   30.69 -#define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C))
   30.70 -#define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C))
   30.71 -#define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))
   30.72 -*/
   30.73 -#endif // ifdef __cplusplus