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).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj
index 59bb72d..474039e 100644
--- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj
+++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj
@@ -261,12 +261,7 @@
<ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
<ClCompile Include="..\..\src\audio\SDL_mixer.c" />
<ClCompile Include="..\..\src\audio\SDL_wave.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.c" />
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
index 2fe0318..66bdee5 100644
--- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
+++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
@@ -37,14 +37,7 @@
<ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
<ClCompile Include="..\..\src\audio\SDL_mixer.c" />
<ClCompile Include="..\..\src\audio\SDL_wave.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.c" />
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c
index c540be3..0b2eea3 100644
--- a/src/audio/xaudio2/SDL_xaudio2.c
+++ b/src/audio/xaudio2/SDL_xaudio2.c
@@ -21,37 +21,7 @@
/* WinRT NOTICE:
- A number of changes were warranted to SDL's XAudio2 backend in order to
- 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
+ A few changes to SDL's XAudio2 backend were warranted by API
changes to Windows. Many, but not all of these are documented by Microsoft
at:
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
+/* 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
#include <xaudio2.h>
/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
-#ifdef __cplusplus
-#define this _this
+#ifdef __WINRT__
#include "SDL_xaudio2_winrthelpers.h"
#endif
@@ -273,10 +258,18 @@ XAUDIO2_WaitDone(_THIS)
XAUDIO2_VOICE_STATE state;
SDL_assert(!this->enabled); /* flag that stops playing. */
IXAudio2SourceVoice_Discontinuity(source);
+#if SDL_XAUDIO2_2_8
+ IXAudio2SourceVoice_GetState(source, &state, 0);
+#else
IXAudio2SourceVoice_GetState(source, &state);
+#endif
while (state.BuffersQueued > 0) {
SDL_SemWait(this->hidden->semaphore);
+#if SDL_XAUDIO2_2_8
+ IXAudio2SourceVoice_GetState(source, &state, 0);
+#else
IXAudio2SourceVoice_GetState(source, &state);
+#endif
}
}
@@ -447,9 +440,15 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
stereo output to appropriate surround sound configurations
instead of clamping to 2 channels, even though we'll configure the
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,
XAUDIO2_DEFAULT_CHANNELS,
this->spec.freq, 0, devId, NULL);
+#endif
if (result != S_OK) {
XAUDIO2_CloseDevice(this);
return SDL_SetError("XAudio2: Couldn't create mastering voice");
diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
index aa88fd6..9c0fe0e 100644
--- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
+++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
@@ -8,7 +8,7 @@ using Windows::Devices::Enumeration::DeviceInformation;
using Windows::Devices::Enumeration::DeviceInformationCollection;
#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
// 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
}
-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
// Windows Phone doesn't seem to have the same device enumeration APIs that
diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h
index 7c3ba81..ee5afcd 100644
--- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h
+++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h
@@ -14,14 +14,24 @@ typedef struct XAUDIO2_DEVICE_DETAILS
*/
} XAUDIO2_DEVICE_DETAILS;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
+#ifdef __cplusplus
+}
+#endif
+
//
// 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_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))
@@ -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_Stop(A, B, C) (A)->Stop((B), (C))
#define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))
+*/
+#endif // ifdef __cplusplus