WinRT: made SDL_xaudio2.c compile as C code when building for WinRT

XAudio2 2.8's header file, xaudio2.h, doesn't compile in plain C code for WinRT
apps, not automatically at least.  Initially, this file was adapted to compile
as C++, however these changes are now deprecated in favor of some preprocessor
based hacks that should get xaudio2.h to compile (while making sure XAudio2
still works).
This commit is contained in:
David Ludwig 2013-09-06 19:07:15 -04:00
parent ac6e5a69ce
commit fff780818d
5 changed files with 49 additions and 50 deletions

View File

@ -261,12 +261,7 @@
<ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" /> <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
<ClCompile Include="..\..\src\audio\SDL_mixer.c" /> <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
<ClCompile Include="..\..\src\audio\SDL_wave.c" /> <ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c"> <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp"> <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT> <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT> <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>

View File

@ -37,14 +37,7 @@
<ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" /> <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
<ClCompile Include="..\..\src\audio\SDL_mixer.c" /> <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
<ClCompile Include="..\..\src\audio\SDL_wave.c" /> <ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c"> <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp"> <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT> <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT> <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>

View File

@ -21,37 +21,7 @@
/* WinRT NOTICE: /* WinRT NOTICE:
A number of changes were warranted to SDL's XAudio2 backend in order to A few changes to SDL's XAudio2 backend were warranted by API
get it compiling for WinRT.
When compiling for WinRT, XAudio2.h requires that it be compiled in a C++
file, and not a straight C file. Trying to compile it as C leads to lots
of errors, at least with MSVC 2012 and Windows SDK 8.0, as of Nov 22, 2012.
To address this specific issue, a few changes were made to SDL_xaudio2.c:
1. SDL_xaudio2.c is compiled as a C++ file in WinRT builds. Exported
symbols, namely XAUDIO2_bootstrap, uses 'extern "C"' to make sure the
rest of SDL can access it. Non-WinRT builds continue to compile
SDL_xaudio2.c as a C file.
2. A macro redefines variables named 'this' to '_this', to prevent compiler
errors (C2355 in Visual C++) related to 'this' being a reserverd keyword.
This hack may need to be altered in the future, particularly if C++'s
'this' keyword needs to be used (within SDL_xaudio2.c). At the time
WinRT support was initially added to SDL's XAudio2 backend, this
capability was not needed.
3. The C-style macros to invoke XAudio2's COM-based methods were
rewritten to be C++-friendly. These are provided in the file,
SDL_xaudio2_winrthelpers.h.
4. IXAudio2::CreateSourceVoice, when used in C++, requires its callbacks to
be specified via a C++ class. SDL's XAudio2 backend was written with
C-style callbacks. A class to bridge these two interfaces,
SDL_XAudio2VoiceCallback, was written to make XAudio2 happy. Its methods
just call SDL's existing, C-style callbacks.
5. Multiple checks for the __cplusplus macro were made, in appropriate
places.
A few additional changes to SDL's XAudio2 backend were warranted by API
changes to Windows. Many, but not all of these are documented by Microsoft changes to Windows. Many, but not all of these are documented by Microsoft
at: at:
http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
@ -108,14 +78,29 @@ extern "C" {
#ifdef SDL_XAUDIO2_HAS_SDK #ifdef SDL_XAUDIO2_HAS_SDK
/* Check to see if we're compiling for XAudio 2.8, or higher. */
#ifdef WINVER
#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */
#define SDL_XAUDIO2_2_8 1
#endif
#endif
/* The XAudio header file, when #include'd on WinRT, will only compile in C++
files, but not C. A few preprocessor-based hacks are defined below in order
to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c.
*/
#ifdef __WINRT__
#define uuid(x)
#define DX_BUILD
#endif
#define INITGUID 1 #define INITGUID 1
#include <xaudio2.h> #include <xaudio2.h>
/* Hidden "this" pointer for the audio functions */ /* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this #define _THIS SDL_AudioDevice *this
#ifdef __cplusplus #ifdef __WINRT__
#define this _this
#include "SDL_xaudio2_winrthelpers.h" #include "SDL_xaudio2_winrthelpers.h"
#endif #endif
@ -273,10 +258,18 @@ XAUDIO2_WaitDone(_THIS)
XAUDIO2_VOICE_STATE state; XAUDIO2_VOICE_STATE state;
SDL_assert(!this->enabled); /* flag that stops playing. */ SDL_assert(!this->enabled); /* flag that stops playing. */
IXAudio2SourceVoice_Discontinuity(source); IXAudio2SourceVoice_Discontinuity(source);
#if SDL_XAUDIO2_2_8
IXAudio2SourceVoice_GetState(source, &state, 0);
#else
IXAudio2SourceVoice_GetState(source, &state); IXAudio2SourceVoice_GetState(source, &state);
#endif
while (state.BuffersQueued > 0) { while (state.BuffersQueued > 0) {
SDL_SemWait(this->hidden->semaphore); SDL_SemWait(this->hidden->semaphore);
#if SDL_XAUDIO2_2_8
IXAudio2SourceVoice_GetState(source, &state, 0);
#else
IXAudio2SourceVoice_GetState(source, &state); IXAudio2SourceVoice_GetState(source, &state);
#endif
} }
} }
@ -447,9 +440,15 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
stereo output to appropriate surround sound configurations stereo output to appropriate surround sound configurations
instead of clamping to 2 channels, even though we'll configure the instead of clamping to 2 channels, even though we'll configure the
Source Voice for whatever number of channels you supply. */ Source Voice for whatever number of channels you supply. */
#if SDL_XAUDIO2_2_8
result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
XAUDIO2_DEFAULT_CHANNELS,
this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects);
#else
result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_CHANNELS,
this->spec.freq, 0, devId, NULL); this->spec.freq, 0, devId, NULL);
#endif
if (result != S_OK) { if (result != S_OK) {
XAUDIO2_CloseDevice(this); XAUDIO2_CloseDevice(this);
return SDL_SetError("XAudio2: Couldn't create mastering voice"); return SDL_SetError("XAudio2: Couldn't create mastering voice");

View File

@ -8,7 +8,7 @@ using Windows::Devices::Enumeration::DeviceInformation;
using Windows::Devices::Enumeration::DeviceInformationCollection; using Windows::Devices::Enumeration::DeviceInformationCollection;
#endif #endif
HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) extern "C" HRESULT __cdecl IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
{ {
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
// There doesn't seem to be any audio device enumeration on Windows Phone. // There doesn't seem to be any audio device enumeration on Windows Phone.
@ -29,7 +29,7 @@ HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
#endif #endif
} }
HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details) extern "C" HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
{ {
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
// Windows Phone doesn't seem to have the same device enumeration APIs that // Windows Phone doesn't seem to have the same device enumeration APIs that

View File

@ -14,14 +14,24 @@ typedef struct XAUDIO2_DEVICE_DETAILS
*/ */
} XAUDIO2_DEVICE_DETAILS; } XAUDIO2_DEVICE_DETAILS;
#ifdef __cplusplus
extern "C" {
#endif
HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount); HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details); HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
#ifdef __cplusplus
}
#endif
// //
// C-style macros to call XAudio2's methods in C++: // C-style macros to call XAudio2's methods in C++:
// //
#ifdef __cplusplus
/*
#define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G)) #define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G))
#define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H)) #define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H))
#define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C)) #define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C))
@ -38,3 +48,5 @@ HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVIC
#define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C)) #define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C))
#define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C)) #define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C))
#define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C)) #define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))
*/
#endif // ifdef __cplusplus