src/audio/xaudio2/SDL_xaudio2.c
author Sam Lantinga
Sat, 06 Oct 2012 11:23:47 -0700
changeset 6565 1f3c0df426dc
parent 6352 a9bcd26e7105
child 6885 700f1b25f77f
child 8353 82447809a27e
permissions -rw-r--r--
When using Xinerama, XVidMode always works on screen 0. Otherwise use the real X11 screen.
icculus@5592
     1
/*
icculus@5592
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
icculus@5592
     4
icculus@5592
     5
  This software is provided 'as-is', without any express or implied
icculus@5592
     6
  warranty.  In no event will the authors be held liable for any damages
icculus@5592
     7
  arising from the use of this software.
icculus@5592
     8
icculus@5592
     9
  Permission is granted to anyone to use this software for any purpose,
icculus@5592
    10
  including commercial applications, and to alter it and redistribute it
icculus@5592
    11
  freely, subject to the following restrictions:
icculus@5592
    12
icculus@5592
    13
  1. The origin of this software must not be misrepresented; you must not
icculus@5592
    14
     claim that you wrote the original software. If you use this software
icculus@5592
    15
     in a product, an acknowledgment in the product documentation would be
icculus@5592
    16
     appreciated but is not required.
icculus@5592
    17
  2. Altered source versions must be plainly marked as such, and must not be
icculus@5592
    18
     misrepresented as being the original software.
icculus@5592
    19
  3. This notice may not be removed or altered from any source distribution.
icculus@5592
    20
*/
icculus@5592
    21
#include "SDL_config.h"
slouken@6044
    22
slouken@6044
    23
#if SDL_AUDIO_DRIVER_XAUDIO2
slouken@6044
    24
icculus@5592
    25
#include "../../core/windows/SDL_windows.h"
icculus@5592
    26
#include "SDL_audio.h"
icculus@5592
    27
#include "../SDL_audio_c.h"
icculus@5636
    28
#include "../SDL_sysaudio.h"
icculus@5592
    29
#include "SDL_assert.h"
icculus@5592
    30
icculus@5635
    31
#include <dxsdkver.h> /* XAudio2 exists as of the March 2008 DirectX SDK */
icculus@5636
    32
#if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
slouken@6161
    33
#  pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
icculus@5636
    34
#else
icculus@5636
    35
#  define SDL_XAUDIO2_HAS_SDK 1
icculus@5635
    36
#endif
icculus@5592
    37
icculus@5636
    38
#ifdef SDL_XAUDIO2_HAS_SDK
icculus@5615
    39
icculus@5635
    40
#define INITGUID 1
icculus@5635
    41
#include <XAudio2.h>
icculus@5635
    42
icculus@5635
    43
/* Hidden "this" pointer for the audio functions */
icculus@5635
    44
#define _THIS	SDL_AudioDevice *this
icculus@5635
    45
icculus@5635
    46
struct SDL_PrivateAudioData
icculus@5635
    47
{
icculus@5635
    48
    IXAudio2 *ixa2;
icculus@5635
    49
    IXAudio2SourceVoice *source;
icculus@5635
    50
    IXAudio2MasteringVoice *mastering;
icculus@5635
    51
    HANDLE semaphore;
icculus@5635
    52
    Uint8 *mixbuf;
icculus@5635
    53
    int mixlen;
icculus@5635
    54
    Uint8 *nextbuf;
icculus@5635
    55
};
icculus@5635
    56
icculus@5635
    57
icculus@5592
    58
static __inline__ char *
icculus@5592
    59
utf16_to_utf8(const WCHAR *S)
icculus@5592
    60
{
icculus@5592
    61
    /* !!! FIXME: this should be UTF-16, not UCS-2! */
icculus@5592
    62
    return SDL_iconv_string("UTF-8", "UCS-2", (char *)(S),
icculus@5592
    63
                            (SDL_wcslen(S)+1)*sizeof(WCHAR));
icculus@5592
    64
}
icculus@5592
    65
icculus@5593
    66
static void
icculus@5593
    67
XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
icculus@5592
    68
{
icculus@5592
    69
    IXAudio2 *ixa2 = NULL;
icculus@5592
    70
    UINT32 devcount = 0;
icculus@5592
    71
    UINT32 i = 0;
icculus@5592
    72
    void *ptr = NULL;
icculus@5592
    73
icculus@5592
    74
    if (iscapture) {
icculus@5592
    75
        SDL_SetError("XAudio2: capture devices unsupported.");
icculus@5593
    76
        return;
icculus@5592
    77
    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
icculus@5592
    78
        SDL_SetError("XAudio2: XAudio2Create() failed.");
icculus@5593
    79
        return;
icculus@5592
    80
    } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
icculus@5592
    81
        SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
icculus@5592
    82
        IXAudio2_Release(ixa2);
icculus@5593
    83
        return;
icculus@5592
    84
    }
icculus@5592
    85
icculus@5592
    86
    for (i = 0; i < devcount; i++) {
icculus@5592
    87
        XAUDIO2_DEVICE_DETAILS details;
icculus@5592
    88
        if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
icculus@5592
    89
            char *str = utf16_to_utf8(details.DisplayName);
icculus@5592
    90
            if (str != NULL) {
icculus@5593
    91
                addfn(str);
icculus@5593
    92
                SDL_free(str);  /* addfn() made a copy of the string. */
icculus@5592
    93
            }
icculus@5592
    94
        }
icculus@5592
    95
    }
icculus@5592
    96
icculus@5592
    97
    IXAudio2_Release(ixa2);
icculus@5592
    98
}
icculus@5592
    99
icculus@5592
   100
static void STDMETHODCALLTYPE
icculus@5592
   101
VoiceCBOnBufferEnd(THIS_ void *data)
icculus@5592
   102
{
icculus@5592
   103
    /* Just signal the SDL audio thread and get out of XAudio2's way. */
icculus@5592
   104
    SDL_AudioDevice *this = (SDL_AudioDevice *) data;
icculus@5592
   105
    ReleaseSemaphore(this->hidden->semaphore, 1, NULL);
icculus@5592
   106
}
icculus@5592
   107
icculus@5592
   108
static void STDMETHODCALLTYPE
icculus@5592
   109
VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
icculus@5592
   110
{
icculus@5592
   111
    /* !!! FIXME: attempt to recover, or mark device disconnected. */
icculus@5592
   112
    SDL_assert(0 && "write me!");
icculus@5592
   113
}
icculus@5592
   114
icculus@5592
   115
/* no-op callbacks... */
icculus@5592
   116
static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
icculus@5592
   117
static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
icculus@5592
   118
static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
icculus@5592
   119
static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
icculus@5592
   120
static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
icculus@5592
   121
icculus@5592
   122
icculus@5592
   123
static Uint8 *
icculus@5592
   124
XAUDIO2_GetDeviceBuf(_THIS)
icculus@5592
   125
{
icculus@5592
   126
    return this->hidden->nextbuf;
icculus@5592
   127
}
icculus@5592
   128
icculus@5592
   129
static void
icculus@5592
   130
XAUDIO2_PlayDevice(_THIS)
icculus@5592
   131
{
icculus@5592
   132
    XAUDIO2_BUFFER buffer;
icculus@5592
   133
    Uint8 *mixbuf = this->hidden->mixbuf;
icculus@5592
   134
    Uint8 *nextbuf = this->hidden->nextbuf;
icculus@5592
   135
    const int mixlen = this->hidden->mixlen;
icculus@5592
   136
    IXAudio2SourceVoice *source = this->hidden->source;
icculus@5592
   137
    HRESULT result = S_OK;
icculus@5592
   138
icculus@5592
   139
    if (!this->enabled) { /* shutting down? */
icculus@5592
   140
        return;
icculus@5592
   141
    }
icculus@5592
   142
icculus@5592
   143
    /* Submit the next filled buffer */
icculus@5592
   144
    SDL_zero(buffer);
icculus@5592
   145
    buffer.AudioBytes = mixlen;
icculus@5592
   146
    buffer.pAudioData = nextbuf;
icculus@5592
   147
    buffer.pContext = this;
icculus@5592
   148
icculus@5592
   149
    if (nextbuf == mixbuf) {
icculus@5592
   150
        nextbuf += mixlen;
icculus@5592
   151
    } else {
icculus@5592
   152
        nextbuf = mixbuf;
icculus@5592
   153
    }
icculus@5592
   154
    this->hidden->nextbuf = nextbuf;
icculus@5592
   155
icculus@5592
   156
    result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
icculus@5592
   157
    if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
icculus@5592
   158
        /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
icculus@5592
   159
    }
icculus@5592
   160
icculus@5592
   161
    if (result != S_OK) {  /* uhoh, panic! */
icculus@5592
   162
        IXAudio2SourceVoice_FlushSourceBuffers(source);
icculus@5592
   163
        this->enabled = 0;
icculus@5592
   164
    }
icculus@5592
   165
}
icculus@5592
   166
icculus@5592
   167
static void
icculus@5592
   168
XAUDIO2_WaitDevice(_THIS)
icculus@5592
   169
{
icculus@5592
   170
    if (this->enabled) {
icculus@5592
   171
        WaitForSingleObject(this->hidden->semaphore, INFINITE);
icculus@5592
   172
    }
icculus@5592
   173
}
icculus@5592
   174
icculus@5592
   175
static void
icculus@5592
   176
XAUDIO2_WaitDone(_THIS)
icculus@5592
   177
{
icculus@5592
   178
    IXAudio2SourceVoice *source = this->hidden->source;
icculus@5592
   179
    XAUDIO2_VOICE_STATE state;
icculus@5592
   180
    SDL_assert(!this->enabled);  /* flag that stops playing. */
icculus@5592
   181
    IXAudio2SourceVoice_Discontinuity(source);
icculus@5592
   182
    IXAudio2SourceVoice_GetState(source, &state);
icculus@5592
   183
    while (state.BuffersQueued > 0) {
icculus@5592
   184
        WaitForSingleObject(this->hidden->semaphore, INFINITE);
icculus@5592
   185
        IXAudio2SourceVoice_GetState(source, &state);
icculus@5592
   186
    }
icculus@5592
   187
}
icculus@5592
   188
icculus@5592
   189
icculus@5592
   190
static void
icculus@5592
   191
XAUDIO2_CloseDevice(_THIS)
icculus@5592
   192
{
icculus@5592
   193
    if (this->hidden != NULL) {
icculus@5592
   194
        IXAudio2 *ixa2 = this->hidden->ixa2;
icculus@5592
   195
        IXAudio2SourceVoice *source = this->hidden->source;
icculus@5592
   196
        IXAudio2MasteringVoice *mastering = this->hidden->mastering;
icculus@5592
   197
icculus@5592
   198
        if (source != NULL) {
icculus@5592
   199
            IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
icculus@5592
   200
            IXAudio2SourceVoice_FlushSourceBuffers(source);
icculus@5592
   201
            IXAudio2SourceVoice_DestroyVoice(source);
icculus@5592
   202
        }
icculus@5592
   203
        if (ixa2 != NULL) {
icculus@5592
   204
            IXAudio2_StopEngine(ixa2);
icculus@5592
   205
        }
icculus@5592
   206
        if (mastering != NULL) {
icculus@5592
   207
            IXAudio2MasteringVoice_DestroyVoice(mastering);
icculus@5592
   208
        }
icculus@5592
   209
        if (ixa2 != NULL) {
icculus@5592
   210
            IXAudio2_Release(ixa2);
icculus@5592
   211
        }
icculus@5592
   212
        if (this->hidden->mixbuf != NULL) {
icculus@5592
   213
            SDL_free(this->hidden->mixbuf);
icculus@5592
   214
        }
icculus@5592
   215
        if (this->hidden->semaphore != NULL) {
icculus@5592
   216
            CloseHandle(this->hidden->semaphore);
icculus@5592
   217
        }
icculus@5592
   218
icculus@5592
   219
        SDL_free(this->hidden);
icculus@5592
   220
        this->hidden = NULL;
icculus@5592
   221
    }
icculus@5592
   222
}
icculus@5592
   223
icculus@5592
   224
static int
icculus@5592
   225
XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
icculus@5592
   226
{
icculus@5592
   227
    HRESULT result = S_OK;
icculus@5592
   228
    WAVEFORMATEX waveformat;
icculus@5592
   229
    int valid_format = 0;
icculus@5592
   230
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
icculus@5592
   231
    IXAudio2 *ixa2 = NULL;
icculus@5592
   232
    IXAudio2SourceVoice *source = NULL;
icculus@5592
   233
    UINT32 devId = 0;  /* 0 == system default device. */
icculus@5592
   234
icculus@5592
   235
	static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
icculus@5592
   236
	    VoiceCBOnVoiceProcessPassStart,
icculus@5592
   237
        VoiceCBOnVoiceProcessPassEnd,
icculus@5592
   238
        VoiceCBOnStreamEnd,
icculus@5592
   239
        VoiceCBOnBufferStart,
icculus@5592
   240
        VoiceCBOnBufferEnd,
icculus@5592
   241
        VoiceCBOnLoopEnd,
icculus@5592
   242
        VoiceCBOnVoiceError
icculus@5592
   243
	};
icculus@5592
   244
icculus@5592
   245
	static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
icculus@5592
   246
icculus@5592
   247
    if (iscapture) {
icculus@5592
   248
        SDL_SetError("XAudio2: capture devices unsupported.");
icculus@5592
   249
        return 0;
icculus@5592
   250
    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
icculus@5592
   251
        SDL_SetError("XAudio2: XAudio2Create() failed.");
icculus@5592
   252
        return 0;
icculus@5592
   253
    }
icculus@5592
   254
icculus@5592
   255
    if (devname != NULL) {
icculus@5592
   256
        UINT32 devcount = 0;
icculus@5592
   257
        UINT32 i = 0;
icculus@5592
   258
icculus@5592
   259
        if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
icculus@5592
   260
            IXAudio2_Release(ixa2);
icculus@5592
   261
            SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
icculus@5592
   262
            return 0;
icculus@5592
   263
        }
icculus@5592
   264
        for (i = 0; i < devcount; i++) {
icculus@5592
   265
            XAUDIO2_DEVICE_DETAILS details;
icculus@5592
   266
            if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
icculus@5592
   267
                char *str = utf16_to_utf8(details.DisplayName);
icculus@5592
   268
                if (str != NULL) {
icculus@5592
   269
                    const int match = (SDL_strcmp(str, devname) == 0);
icculus@5592
   270
                    SDL_free(str);
icculus@5592
   271
                    if (match) {
icculus@5592
   272
                        devId = i;
icculus@5592
   273
                        break;
icculus@5592
   274
                    }
icculus@5592
   275
                }
icculus@5592
   276
            }
icculus@5592
   277
        }
icculus@5592
   278
icculus@5592
   279
        if (i == devcount) {
icculus@5592
   280
            IXAudio2_Release(ixa2);
icculus@5592
   281
            SDL_SetError("XAudio2: Requested device not found.");
icculus@5592
   282
            return 0;
icculus@5592
   283
        }
icculus@5592
   284
    }
icculus@5592
   285
icculus@5592
   286
    /* Initialize all variables that we clean on shutdown */
icculus@5592
   287
    this->hidden = (struct SDL_PrivateAudioData *)
icculus@5592
   288
        SDL_malloc((sizeof *this->hidden));
icculus@5592
   289
    if (this->hidden == NULL) {
icculus@5592
   290
        IXAudio2_Release(ixa2);
icculus@5592
   291
        SDL_OutOfMemory();
icculus@5592
   292
        return 0;
icculus@5592
   293
    }
icculus@5592
   294
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
icculus@5592
   295
icculus@5592
   296
    this->hidden->ixa2 = ixa2;
icculus@5592
   297
    this->hidden->semaphore = CreateSemaphore(NULL, 1, 2, NULL);
icculus@5592
   298
    if (this->hidden->semaphore == NULL) {
icculus@5592
   299
        XAUDIO2_CloseDevice(this);
icculus@5592
   300
        SDL_SetError("XAudio2: CreateSemaphore() failed!");
icculus@5592
   301
        return 0;
icculus@5592
   302
    }
icculus@5592
   303
icculus@5592
   304
    while ((!valid_format) && (test_format)) {
icculus@5592
   305
        switch (test_format) {
icculus@5592
   306
        case AUDIO_U8:
icculus@5592
   307
        case AUDIO_S16:
icculus@5592
   308
        case AUDIO_S32:
icculus@5592
   309
        case AUDIO_F32:
icculus@5592
   310
            this->spec.format = test_format;
icculus@5592
   311
            valid_format = 1;
icculus@5592
   312
            break;
icculus@5592
   313
        }
icculus@5592
   314
        test_format = SDL_NextAudioFormat();
icculus@5592
   315
    }
icculus@5592
   316
icculus@5592
   317
    if (!valid_format) {
icculus@5592
   318
        XAUDIO2_CloseDevice(this);
icculus@5592
   319
        SDL_SetError("XAudio2: Unsupported audio format");
icculus@5592
   320
        return 0;
icculus@5592
   321
    }
icculus@5592
   322
icculus@5592
   323
    /* Update the fragment size as size in bytes */
icculus@5592
   324
    SDL_CalculateAudioSpec(&this->spec);
icculus@5592
   325
icculus@5592
   326
    /* We feed a Source, it feeds the Mastering, which feeds the device. */
icculus@5592
   327
    this->hidden->mixlen = this->spec.size;
icculus@5592
   328
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
icculus@5592
   329
    if (this->hidden->mixbuf == NULL) {
icculus@5592
   330
        XAUDIO2_CloseDevice(this);
icculus@5592
   331
        SDL_OutOfMemory();
icculus@5592
   332
        return 0;
icculus@5592
   333
    }
icculus@5592
   334
    this->hidden->nextbuf = this->hidden->mixbuf;
slouken@6352
   335
    SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
icculus@5592
   336
icculus@5592
   337
    /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
icculus@5592
   338
       Xbox360, this means 5.1 output, but on Windows, it means "figure out
icculus@5592
   339
       what the system has." It might be preferable to let XAudio2 blast
icculus@5592
   340
       stereo output to appropriate surround sound configurations
icculus@5592
   341
       instead of clamping to 2 channels, even though we'll configure the
icculus@5592
   342
       Source Voice for whatever number of channels you supply. */
icculus@5592
   343
    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
icculus@5592
   344
                                           XAUDIO2_DEFAULT_CHANNELS,
icculus@5592
   345
                                           this->spec.freq, 0, devId, NULL);
icculus@5592
   346
    if (result != S_OK) {
icculus@5592
   347
        XAUDIO2_CloseDevice(this);
icculus@5592
   348
        SDL_SetError("XAudio2: Couldn't create mastering voice");
icculus@5592
   349
        return 0;
icculus@5592
   350
    }
icculus@5592
   351
icculus@5592
   352
    SDL_zero(waveformat);
icculus@5592
   353
    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
icculus@5592
   354
        waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
icculus@5592
   355
    } else {
icculus@5592
   356
        waveformat.wFormatTag = WAVE_FORMAT_PCM;
icculus@5592
   357
    }
icculus@5592
   358
    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
icculus@5592
   359
    waveformat.nChannels = this->spec.channels;
icculus@5592
   360
    waveformat.nSamplesPerSec = this->spec.freq;
icculus@5592
   361
    waveformat.nBlockAlign =
icculus@5592
   362
        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
icculus@5592
   363
    waveformat.nAvgBytesPerSec =
icculus@5592
   364
        waveformat.nSamplesPerSec * waveformat.nBlockAlign;
icculus@5592
   365
icculus@5592
   366
    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
icculus@5592
   367
                                        XAUDIO2_VOICE_NOSRC |
icculus@5592
   368
                                        XAUDIO2_VOICE_NOPITCH,
icculus@5592
   369
                                        1.0f, &callbacks, NULL, NULL);
icculus@5592
   370
    if (result != S_OK) {
icculus@5592
   371
        XAUDIO2_CloseDevice(this);
icculus@5592
   372
        SDL_SetError("XAudio2: Couldn't create source voice");
icculus@5592
   373
        return 0;
icculus@5592
   374
    }
icculus@5592
   375
    this->hidden->source = source;
icculus@5592
   376
icculus@5592
   377
    /* Start everything playing! */
icculus@5592
   378
    result = IXAudio2_StartEngine(ixa2);
icculus@5592
   379
    if (result != S_OK) {
icculus@5592
   380
        XAUDIO2_CloseDevice(this);
icculus@5592
   381
        SDL_SetError("XAudio2: Couldn't start engine");
icculus@5592
   382
        return 0;
icculus@5592
   383
    }
icculus@5592
   384
icculus@5592
   385
    result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
icculus@5592
   386
    if (result != S_OK) {
icculus@5592
   387
        XAUDIO2_CloseDevice(this);
icculus@5592
   388
        SDL_SetError("XAudio2: Couldn't start source voice");
icculus@5592
   389
        return 0;
icculus@5592
   390
    }
icculus@5592
   391
icculus@5592
   392
    return 1; /* good to go. */
icculus@5592
   393
}
icculus@5592
   394
icculus@5592
   395
static void
icculus@5592
   396
XAUDIO2_Deinitialize(void)
icculus@5592
   397
{
icculus@5592
   398
    WIN_CoUninitialize();
icculus@5592
   399
}
icculus@5592
   400
icculus@5636
   401
#endif  /* SDL_XAUDIO2_HAS_SDK */
icculus@5615
   402
icculus@5615
   403
icculus@5592
   404
static int
icculus@5592
   405
XAUDIO2_Init(SDL_AudioDriverImpl * impl)
icculus@5592
   406
{
icculus@5636
   407
#ifndef SDL_XAUDIO2_HAS_SDK
icculus@5636
   408
    SDL_SetError("XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
icculus@5615
   409
    return 0;  /* no XAudio2 support, ever. Update your SDK! */
icculus@5615
   410
#else
icculus@5592
   411
    /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
icculus@5592
   412
    IXAudio2 *ixa2 = NULL;
icculus@5592
   413
    if (FAILED(WIN_CoInitialize())) {
icculus@5592
   414
        SDL_SetError("XAudio2: CoInitialize() failed");
icculus@5592
   415
        return 0;
icculus@5592
   416
    }
icculus@5592
   417
icculus@5592
   418
    if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
icculus@5592
   419
        WIN_CoUninitialize();
icculus@5592
   420
        SDL_SetError("XAudio2: XAudio2Create() failed");
icculus@5592
   421
        return 0;  /* not available. */
icculus@5592
   422
    }
icculus@5592
   423
    IXAudio2_Release(ixa2);
icculus@5592
   424
icculus@5592
   425
    /* Set the function pointers */
icculus@5592
   426
    impl->DetectDevices = XAUDIO2_DetectDevices;
icculus@5592
   427
    impl->OpenDevice = XAUDIO2_OpenDevice;
icculus@5592
   428
    impl->PlayDevice = XAUDIO2_PlayDevice;
icculus@5592
   429
    impl->WaitDevice = XAUDIO2_WaitDevice;
icculus@5592
   430
    impl->WaitDone = XAUDIO2_WaitDone;
icculus@5592
   431
    impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
icculus@5592
   432
    impl->CloseDevice = XAUDIO2_CloseDevice;
icculus@5592
   433
    impl->Deinitialize = XAUDIO2_Deinitialize;
icculus@5592
   434
icculus@5592
   435
    return 1;   /* this audio target is available. */
icculus@5615
   436
#endif
icculus@5592
   437
}
icculus@5592
   438
icculus@5592
   439
AudioBootStrap XAUDIO2_bootstrap = {
icculus@5592
   440
    "xaudio2", "XAudio2", XAUDIO2_Init, 0
icculus@5592
   441
};
icculus@5592
   442
icculus@5636
   443
#endif  /* SDL_AUDIO_DRIVER_XAUDIO2 */
icculus@5636
   444
icculus@5592
   445
/* vi: set ts=4 sw=4 expandtab: */