WinRT: got XAudio2 sort-of working (it plays stuff poorly, then crashes)
authorDavid Ludwig <dludwig@pobox.com>
Sat, 24 Nov 2012 11:19:06 -0500
changeset 8361 eefad2ec4f76
parent 8360 7f1bc00e59fc
child 8362 ec8b86ada110
WinRT: got XAudio2 sort-of working (it plays stuff poorly, then crashes)
src/audio/xaudio2/SDL_xaudio2.c
src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
--- a/src/audio/xaudio2/SDL_xaudio2.c	Sat Nov 24 11:17:23 2012 -0500
+++ b/src/audio/xaudio2/SDL_xaudio2.c	Sat Nov 24 11:19:06 2012 -0500
@@ -128,14 +128,6 @@
 };
 
 
-static __inline__ char *
-utf16_to_utf8(const WCHAR *S)
-{
-    /* !!! FIXME: this should be UTF-16, not UCS-2! */
-    return SDL_iconv_string("UTF-8", "UCS-2", (char *)(S),
-                            (SDL_wcslen(S)+1)*sizeof(WCHAR));
-}
-
 static void
 XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
 {
@@ -159,7 +151,7 @@
     for (i = 0; i < devcount; i++) {
         XAUDIO2_DEVICE_DETAILS details;
         if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
-            char *str = utf16_to_utf8(details.DisplayName);
+            char *str = WIN_StringToUTF8(details.DisplayName);
             if (str != NULL) {
                 addfn(str);
                 SDL_free(str);  /* addfn() made a copy of the string. */
@@ -313,7 +305,7 @@
             SDL_free(this->hidden->mixbuf);
         }
         if (this->hidden->semaphore != NULL) {
-            CloseHandle(this->hidden->semaphore);
+            SDL_DestroySemaphore(this->hidden->semaphore);
         }
 
         SDL_free(this->hidden);
@@ -331,7 +323,8 @@
     IXAudio2 *ixa2 = NULL;
     IXAudio2SourceVoice *source = NULL;
 #if defined(__WINRT__)
-    WCHAR devId[256];
+    WCHAR devIdBuffer[256];
+    LPCWSTR devId = 0;
 #else
     UINT32 devId = 0;  /* 0 == system default device. */
 #endif
@@ -353,7 +346,7 @@
 #endif // ! defined(__cplusplus)
 
 #if defined(__WINRT__)
-    SDL_zero(devId);
+    SDL_zero(devIdBuffer);
 #endif
 
     if (iscapture) {
@@ -363,6 +356,14 @@
         SDL_SetError("XAudio2: XAudio2Create() failed.");
         return 0;
     }
+    XAUDIO2_DEBUG_CONFIGURATION debugConfig;
+    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;
+    debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS;
+    debugConfig.LogThreadID = TRUE;
+    debugConfig.LogFileline = TRUE;
+    debugConfig.LogFunctionName = TRUE;
+    debugConfig.LogTiming = TRUE;
+    ixa2->SetDebugConfiguration(&debugConfig);
 
     if (devname != NULL) {
         UINT32 devcount = 0;
@@ -376,13 +377,14 @@
         for (i = 0; i < devcount; i++) {
             XAUDIO2_DEVICE_DETAILS details;
             if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
-                char *str = utf16_to_utf8(details.DisplayName);
+                char *str = WIN_StringToUTF8(details.DisplayName);
                 if (str != NULL) {
                     const int match = (SDL_strcmp(str, devname) == 0);
                     SDL_free(str);
                     if (match) {
 #if defined(__WINRT__)
-                        wcsncpy_s(devId, ARRAYSIZE(devId), details.DeviceID, _TRUNCATE);
+                        wcsncpy_s(devIdBuffer, ARRAYSIZE(devIdBuffer), details.DeviceID, _TRUNCATE);
+                        devId = (LPCWSTR) &devIdBuffer;
 #else
                         devId = i;
 #endif
@@ -478,11 +480,19 @@
         waveformat.nChannels * (waveformat.wBitsPerSample / 8);
     waveformat.nAvgBytesPerSec =
         waveformat.nSamplesPerSec * waveformat.nBlockAlign;
+    waveformat.cbSize = sizeof(waveformat);
 
+#ifdef __WINRT__
+    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
+                                        0,
+                                        1.0f, &callbacks, NULL, NULL);
+#else
     result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
                                         XAUDIO2_VOICE_NOSRC |
                                         XAUDIO2_VOICE_NOPITCH,
                                         1.0f, &callbacks, NULL, NULL);
+
+#endif
     if (result != S_OK) {
         XAUDIO2_CloseDevice(this);
         SDL_SetError("XAudio2: Couldn't create source voice");
@@ -529,6 +539,7 @@
     /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
     IXAudio2 *ixa2 = NULL;
 #if defined(__WIN32__)
+    // TODO, WinRT: Investigate using CoInitializeEx here
     if (FAILED(WIN_CoInitialize())) {
         SDL_SetError("XAudio2: CoInitialize() failed");
         return 0;
--- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp	Sat Nov 24 11:17:23 2012 -0500
+++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp	Sat Nov 24 11:19:06 2012 -0500
@@ -8,6 +8,7 @@
 
 HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
 {
+    // TODO, WinRT: make xaudio2 device enumeration only happen once, and in the background
     auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
     while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
     {