WinRT: made SDL_xaudio2.c compile as C code when building for WinRT
authorDavid Ludwig
Fri, 06 Sep 2013 19:07:15 -0400
changeset 85190a334fc866b0
parent 8518 bc44448125eb
child 8520 66c31b377506
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).
VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj
VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
src/audio/xaudio2/SDL_xaudio2.c
src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
src/audio/xaudio2/SDL_xaudio2_winrthelpers.h
     1.1 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj	Wed Sep 04 20:20:36 2013 -0400
     1.2 +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj	Fri Sep 06 19:07:15 2013 -0400
     1.3 @@ -261,12 +261,7 @@
     1.4      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
     1.5      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
     1.6      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
     1.7 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
     1.8 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">CompileAsCpp</CompileAs>
     1.9 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">CompileAsCpp</CompileAs>
    1.10 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
    1.11 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
    1.12 -    </ClCompile>
    1.13 +    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
    1.14      <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    1.15        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    1.16        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
     2.1 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj	Wed Sep 04 20:20:36 2013 -0400
     2.2 +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj	Fri Sep 06 19:07:15 2013 -0400
     2.3 @@ -37,14 +37,7 @@
     2.4      <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
     2.5      <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
     2.6      <ClCompile Include="..\..\src\audio\SDL_wave.c" />
     2.7 -    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
     2.8 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">CompileAsCpp</CompileAs>
     2.9 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">CompileAsCpp</CompileAs>
    2.10 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
    2.11 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
    2.12 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
    2.13 -      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
    2.14 -    </ClCompile>
    2.15 +    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
    2.16      <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
    2.17        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
    2.18        <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
     3.1 --- a/src/audio/xaudio2/SDL_xaudio2.c	Wed Sep 04 20:20:36 2013 -0400
     3.2 +++ b/src/audio/xaudio2/SDL_xaudio2.c	Fri Sep 06 19:07:15 2013 -0400
     3.3 @@ -21,37 +21,7 @@
     3.4  
     3.5  /* WinRT NOTICE:
     3.6  
     3.7 -   A number of changes were warranted to SDL's XAudio2 backend in order to
     3.8 -   get it compiling for WinRT.
     3.9 -
    3.10 -   When compiling for WinRT, XAudio2.h requires that it be compiled in a C++
    3.11 -   file, and not a straight C file.  Trying to compile it as C leads to lots
    3.12 -   of errors, at least with MSVC 2012 and Windows SDK 8.0, as of Nov 22, 2012.
    3.13 -   To address this specific issue, a few changes were made to SDL_xaudio2.c:
    3.14 -   
    3.15 -   1. SDL_xaudio2.c is compiled as a C++ file in WinRT builds.  Exported
    3.16 -      symbols, namely XAUDIO2_bootstrap, uses 'extern "C"' to make sure the
    3.17 -      rest of SDL can access it.  Non-WinRT builds continue to compile
    3.18 -      SDL_xaudio2.c as a C file.
    3.19 -   2. A macro redefines variables named 'this' to '_this', to prevent compiler
    3.20 -      errors (C2355 in Visual C++) related to 'this' being a reserverd keyword.
    3.21 -      This hack may need to be altered in the future, particularly if C++'s
    3.22 -      'this' keyword needs to be used (within SDL_xaudio2.c).  At the time
    3.23 -      WinRT support was initially added to SDL's XAudio2 backend, this
    3.24 -      capability was not needed.
    3.25 -   3. The C-style macros to invoke XAudio2's COM-based methods were
    3.26 -      rewritten to be C++-friendly.  These are provided in the file,
    3.27 -      SDL_xaudio2_winrthelpers.h.
    3.28 -   4. IXAudio2::CreateSourceVoice, when used in C++, requires its callbacks to
    3.29 -      be specified via a C++ class.  SDL's XAudio2 backend was written with
    3.30 -      C-style callbacks.  A class to bridge these two interfaces,
    3.31 -      SDL_XAudio2VoiceCallback, was written to make XAudio2 happy.  Its methods
    3.32 -      just call SDL's existing, C-style callbacks.
    3.33 -   5. Multiple checks for the __cplusplus macro were made, in appropriate
    3.34 -      places.  
    3.35 -
    3.36 -
    3.37 -   A few additional changes to SDL's XAudio2 backend were warranted by API
    3.38 +   A few changes to SDL's XAudio2 backend were warranted by API
    3.39     changes to Windows.  Many, but not all of these are documented by Microsoft
    3.40     at:
    3.41     http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
    3.42 @@ -108,14 +78,29 @@
    3.43  
    3.44  #ifdef SDL_XAUDIO2_HAS_SDK
    3.45  
    3.46 +/* Check to see if we're compiling for XAudio 2.8, or higher. */
    3.47 +#ifdef WINVER
    3.48 +#if WINVER >= 0x0602  /* Windows 8 SDK or higher? */
    3.49 +#define SDL_XAUDIO2_2_8 1
    3.50 +#endif
    3.51 +#endif
    3.52 +
    3.53 +/* The XAudio header file, when #include'd on WinRT, will only compile in C++
    3.54 +   files, but not C.  A few preprocessor-based hacks are defined below in order
    3.55 +   to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c.
    3.56 + */
    3.57 +#ifdef __WINRT__
    3.58 +#define uuid(x)
    3.59 +#define DX_BUILD
    3.60 +#endif
    3.61 +
    3.62  #define INITGUID 1
    3.63  #include <xaudio2.h>
    3.64  
    3.65  /* Hidden "this" pointer for the audio functions */
    3.66  #define _THIS   SDL_AudioDevice *this
    3.67  
    3.68 -#ifdef __cplusplus
    3.69 -#define this _this
    3.70 +#ifdef __WINRT__
    3.71  #include "SDL_xaudio2_winrthelpers.h"
    3.72  #endif
    3.73  
    3.74 @@ -273,10 +258,18 @@
    3.75      XAUDIO2_VOICE_STATE state;
    3.76      SDL_assert(!this->enabled);  /* flag that stops playing. */
    3.77      IXAudio2SourceVoice_Discontinuity(source);
    3.78 +#if SDL_XAUDIO2_2_8
    3.79 +    IXAudio2SourceVoice_GetState(source, &state, 0);
    3.80 +#else
    3.81      IXAudio2SourceVoice_GetState(source, &state);
    3.82 +#endif
    3.83      while (state.BuffersQueued > 0) {
    3.84          SDL_SemWait(this->hidden->semaphore);
    3.85 +#if SDL_XAUDIO2_2_8
    3.86 +        IXAudio2SourceVoice_GetState(source, &state, 0);
    3.87 +#else
    3.88          IXAudio2SourceVoice_GetState(source, &state);
    3.89 +#endif
    3.90      }
    3.91  }
    3.92  
    3.93 @@ -447,9 +440,15 @@
    3.94         stereo output to appropriate surround sound configurations
    3.95         instead of clamping to 2 channels, even though we'll configure the
    3.96         Source Voice for whatever number of channels you supply. */
    3.97 +#if SDL_XAUDIO2_2_8
    3.98 +    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
    3.99 +                                           XAUDIO2_DEFAULT_CHANNELS,
   3.100 +                                           this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects);
   3.101 +#else
   3.102      result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
   3.103                                             XAUDIO2_DEFAULT_CHANNELS,
   3.104                                             this->spec.freq, 0, devId, NULL);
   3.105 +#endif
   3.106      if (result != S_OK) {
   3.107          XAUDIO2_CloseDevice(this);
   3.108          return SDL_SetError("XAudio2: Couldn't create mastering voice");
     4.1 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp	Wed Sep 04 20:20:36 2013 -0400
     4.2 +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp	Fri Sep 06 19:07:15 2013 -0400
     4.3 @@ -8,7 +8,7 @@
     4.4  using Windows::Devices::Enumeration::DeviceInformationCollection;
     4.5  #endif
     4.6  
     4.7 -HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
     4.8 +extern "C" HRESULT __cdecl IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
     4.9  {
    4.10  #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    4.11      // There doesn't seem to be any audio device enumeration on Windows Phone.
    4.12 @@ -29,7 +29,7 @@
    4.13  #endif
    4.14  }
    4.15  
    4.16 -HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
    4.17 +extern "C" HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
    4.18  {
    4.19  #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    4.20      // Windows Phone doesn't seem to have the same device enumeration APIs that
     5.1 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h	Wed Sep 04 20:20:36 2013 -0400
     5.2 +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h	Fri Sep 06 19:07:15 2013 -0400
     5.3 @@ -14,14 +14,24 @@
     5.4      */
     5.5  } XAUDIO2_DEVICE_DETAILS;
     5.6  
     5.7 +
     5.8 +#ifdef __cplusplus
     5.9 +extern "C" {
    5.10 +#endif
    5.11 +
    5.12  HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
    5.13  HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
    5.14  
    5.15 +#ifdef __cplusplus
    5.16 +}
    5.17 +#endif
    5.18 +
    5.19  
    5.20  //
    5.21  // C-style macros to call XAudio2's methods in C++:
    5.22  //
    5.23 -
    5.24 +#ifdef __cplusplus
    5.25 +/*
    5.26  #define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G))
    5.27  #define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H))
    5.28  #define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C))
    5.29 @@ -38,3 +48,5 @@
    5.30  #define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C))
    5.31  #define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C))
    5.32  #define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))
    5.33 +*/
    5.34 +#endif // ifdef __cplusplus