Implemented XAudio2 target for Windows (and Xbox360, theoretically!).
This commit is contained in:
parent
8fa65eea5c
commit
46bb3d8770
9 changed files with 534 additions and 0 deletions
|
@ -847,6 +847,14 @@
|
|||
RelativePath="..\..\src\audio\directsound\SDL_directsound.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\audio\xaudio2\SDL_xaudio2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\audio\xaudio2\SDL_xaudio2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\joystick\windows\SDL_dxjoystick.c"
|
||||
>
|
||||
|
|
|
@ -836,6 +836,14 @@
|
|||
RelativePath="..\..\src\audio\directsound\SDL_directsound.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\audio\xaudio2\SDL_xaudio2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\audio\xaudio2\SDL_xaudio2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\joystick\windows\SDL_dxjoystick.c"
|
||||
>
|
||||
|
|
|
@ -280,6 +280,7 @@
|
|||
<ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
|
||||
<ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
|
||||
<ClInclude Include="..\..\src\audio\directsound\SDL_directsound.h" />
|
||||
<ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2.h" />
|
||||
<ClInclude Include="..\..\src\SDL_error_c.h" />
|
||||
<ClInclude Include="..\..\src\SDL_hints_c.h" />
|
||||
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
|
||||
|
@ -381,6 +382,7 @@
|
|||
<ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c" />
|
||||
<ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c" />
|
||||
<ClCompile Include="..\..\src\audio\directsound\SDL_directsound.c" />
|
||||
<ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_dxjoystick.c" />
|
||||
<ClCompile Include="..\..\src\SDL_error.c" />
|
||||
<ClCompile Include="..\..\src\events\SDL_events.c" />
|
||||
|
|
|
@ -1726,6 +1726,7 @@ AC_HELP_STRING([--enable-directx], [use DirectX for Windows audio/video [[defaul
|
|||
AC_CHECK_HEADER(ddraw.h, have_ddraw=yes)
|
||||
AC_CHECK_HEADER(dsound.h, have_dsound=yes)
|
||||
AC_CHECK_HEADER(dinput.h, have_dinput=yes)
|
||||
AC_CHECK_HEADER(xaudio2.h, have_xaudio2=yes)
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -2063,6 +2064,10 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
|
|||
AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
|
||||
fi
|
||||
if test x$have_xaudio2 = xyes; then
|
||||
AC_DEFINE(SDL_AUDIO_DRIVER_XAUDIO2, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/audio/xaudio2/*.c"
|
||||
fi
|
||||
have_audio=yes
|
||||
fi
|
||||
# Set up dummy files for the joystick for now
|
||||
|
@ -2150,6 +2155,10 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
|
|||
AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
|
||||
fi
|
||||
if test x$have_xaudio2 = xyes; then
|
||||
AC_DEFINE(SDL_AUDIO_DRIVER_XAUDIO2, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/audio/xaudio2/*.c"
|
||||
fi
|
||||
have_audio=yes
|
||||
fi
|
||||
# Set up files for the joystick library
|
||||
|
|
|
@ -184,6 +184,7 @@
|
|||
#undef SDL_AUDIO_DRIVER_COREAUDIO
|
||||
#undef SDL_AUDIO_DRIVER_DISK
|
||||
#undef SDL_AUDIO_DRIVER_DUMMY
|
||||
#undef SDL_AUDIO_DRIVER_XAUDIO2
|
||||
#undef SDL_AUDIO_DRIVER_DSOUND
|
||||
#undef SDL_AUDIO_DRIVER_ESD
|
||||
#undef SDL_AUDIO_DRIVER_ESD_DYNAMIC
|
||||
|
|
|
@ -145,6 +145,7 @@ typedef unsigned int uintptr_t;
|
|||
/* Enable various audio drivers */
|
||||
#ifndef _WIN32_WCE
|
||||
#define SDL_AUDIO_DRIVER_DSOUND 1
|
||||
#define SDL_AUDIO_DRIVER_XAUDIO2 1
|
||||
#endif
|
||||
#define SDL_AUDIO_DRIVER_WINMM 1
|
||||
#define SDL_AUDIO_DRIVER_DISK 1
|
||||
|
|
|
@ -52,6 +52,7 @@ extern AudioBootStrap SUNAUDIO_bootstrap;
|
|||
extern AudioBootStrap ARTS_bootstrap;
|
||||
extern AudioBootStrap ESD_bootstrap;
|
||||
extern AudioBootStrap NAS_bootstrap;
|
||||
extern AudioBootStrap XAUDIO2_bootstrap;
|
||||
extern AudioBootStrap DSOUND_bootstrap;
|
||||
extern AudioBootStrap WINMM_bootstrap;
|
||||
extern AudioBootStrap PAUDIO_bootstrap;
|
||||
|
@ -97,6 +98,9 @@ static const AudioBootStrap *const bootstrap[] = {
|
|||
#if SDL_AUDIO_DRIVER_NAS
|
||||
&NAS_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_XAUDIO2
|
||||
&XAUDIO2_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_DSOUND
|
||||
&DSOUND_bootstrap,
|
||||
#endif
|
||||
|
|
455
src/audio/xaudio2/SDL_xaudio2.c
Normal file
455
src/audio/xaudio2/SDL_xaudio2.c
Normal file
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#define INITGUID 1
|
||||
#include "SDL_xaudio2.h"
|
||||
|
||||
/* !!! FIXME: this is a cut and paste of SDL_FreeUnixAudioDevices(),
|
||||
* !!! FIXME: which is more proof this needs to be managed in SDL_audio.c
|
||||
* !!! FIXME: and not in drivers.
|
||||
*/
|
||||
static void
|
||||
FreeXAudio2AudioDevices(char ***devices, int *devCount)
|
||||
{
|
||||
int i = *devCount;
|
||||
if ((i > 0) && (*devices != NULL)) {
|
||||
while (i--) {
|
||||
SDL_free((*devices)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (*devices != NULL) {
|
||||
SDL_free(*devices);
|
||||
}
|
||||
|
||||
*devices = NULL;
|
||||
*devCount = 0;
|
||||
}
|
||||
|
||||
|
||||
static char **outputDevices = NULL;
|
||||
static int outputDeviceCount = 0;
|
||||
|
||||
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 int
|
||||
XAUDIO2_DetectDevices(int iscapture)
|
||||
{
|
||||
IXAudio2 *ixa2 = NULL;
|
||||
UINT32 devcount = 0;
|
||||
UINT32 i = 0;
|
||||
void *ptr = NULL;
|
||||
|
||||
if (!iscapture) {
|
||||
FreeXAudio2AudioDevices(&outputDevices, &outputDeviceCount);
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
SDL_SetError("XAudio2: capture devices unsupported.");
|
||||
return 0;
|
||||
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
SDL_SetError("XAudio2: XAudio2Create() failed.");
|
||||
return 0;
|
||||
} else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
|
||||
SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
|
||||
IXAudio2_Release(ixa2);
|
||||
return 0;
|
||||
} else if ((ptr = SDL_malloc(sizeof (char *) * devcount)) == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
IXAudio2_Release(ixa2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
outputDevices = (char **) ptr;
|
||||
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);
|
||||
if (str != NULL) {
|
||||
outputDevices[outputDeviceCount++] = str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IXAudio2_Release(ixa2);
|
||||
|
||||
return outputDeviceCount;
|
||||
}
|
||||
|
||||
static const char *
|
||||
XAUDIO2_GetDeviceName(int index, int iscapture)
|
||||
{
|
||||
if ((!iscapture) && (index < outputDeviceCount)) {
|
||||
return outputDevices[index];
|
||||
}
|
||||
|
||||
SDL_SetError("XAudio2: No such device");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE
|
||||
VoiceCBOnBufferEnd(THIS_ void *data)
|
||||
{
|
||||
/* Just signal the SDL audio thread and get out of XAudio2's way. */
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) data;
|
||||
ReleaseSemaphore(this->hidden->semaphore, 1, NULL);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE
|
||||
VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
|
||||
{
|
||||
/* !!! FIXME: attempt to recover, or mark device disconnected. */
|
||||
SDL_assert(0 && "write me!");
|
||||
}
|
||||
|
||||
/* no-op callbacks... */
|
||||
static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
|
||||
static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
|
||||
static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
|
||||
static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
|
||||
static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
|
||||
|
||||
|
||||
static Uint8 *
|
||||
XAUDIO2_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->nextbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
XAUDIO2_PlayDevice(_THIS)
|
||||
{
|
||||
XAUDIO2_BUFFER buffer;
|
||||
Uint8 *mixbuf = this->hidden->mixbuf;
|
||||
Uint8 *nextbuf = this->hidden->nextbuf;
|
||||
const int mixlen = this->hidden->mixlen;
|
||||
IXAudio2SourceVoice *source = this->hidden->source;
|
||||
HRESULT result = S_OK;
|
||||
|
||||
if (!this->enabled) { /* shutting down? */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Submit the next filled buffer */
|
||||
SDL_zero(buffer);
|
||||
buffer.AudioBytes = mixlen;
|
||||
buffer.pAudioData = nextbuf;
|
||||
buffer.pContext = this;
|
||||
|
||||
if (nextbuf == mixbuf) {
|
||||
nextbuf += mixlen;
|
||||
} else {
|
||||
nextbuf = mixbuf;
|
||||
}
|
||||
this->hidden->nextbuf = nextbuf;
|
||||
|
||||
result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
|
||||
if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
|
||||
/* !!! FIXME: possibly disconnected or temporary lost. Recover? */
|
||||
}
|
||||
|
||||
if (result != S_OK) { /* uhoh, panic! */
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(source);
|
||||
this->enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
XAUDIO2_WaitDevice(_THIS)
|
||||
{
|
||||
if (this->enabled) {
|
||||
WaitForSingleObject(this->hidden->semaphore, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
XAUDIO2_WaitDone(_THIS)
|
||||
{
|
||||
IXAudio2SourceVoice *source = this->hidden->source;
|
||||
XAUDIO2_VOICE_STATE state;
|
||||
SDL_assert(!this->enabled); /* flag that stops playing. */
|
||||
IXAudio2SourceVoice_Discontinuity(source);
|
||||
IXAudio2SourceVoice_GetState(source, &state);
|
||||
while (state.BuffersQueued > 0) {
|
||||
WaitForSingleObject(this->hidden->semaphore, INFINITE);
|
||||
IXAudio2SourceVoice_GetState(source, &state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
XAUDIO2_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden != NULL) {
|
||||
IXAudio2 *ixa2 = this->hidden->ixa2;
|
||||
IXAudio2SourceVoice *source = this->hidden->source;
|
||||
IXAudio2MasteringVoice *mastering = this->hidden->mastering;
|
||||
|
||||
if (source != NULL) {
|
||||
IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(source);
|
||||
IXAudio2SourceVoice_DestroyVoice(source);
|
||||
}
|
||||
if (ixa2 != NULL) {
|
||||
IXAudio2_StopEngine(ixa2);
|
||||
}
|
||||
if (mastering != NULL) {
|
||||
IXAudio2MasteringVoice_DestroyVoice(mastering);
|
||||
}
|
||||
if (ixa2 != NULL) {
|
||||
IXAudio2_Release(ixa2);
|
||||
}
|
||||
if (this->hidden->mixbuf != NULL) {
|
||||
SDL_free(this->hidden->mixbuf);
|
||||
}
|
||||
if (this->hidden->semaphore != NULL) {
|
||||
CloseHandle(this->hidden->semaphore);
|
||||
}
|
||||
|
||||
SDL_free(this->hidden);
|
||||
this->hidden = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
{
|
||||
HRESULT result = S_OK;
|
||||
WAVEFORMATEX waveformat;
|
||||
int valid_format = 0;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
IXAudio2 *ixa2 = NULL;
|
||||
IXAudio2SourceVoice *source = NULL;
|
||||
UINT32 devId = 0; /* 0 == system default device. */
|
||||
|
||||
static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
|
||||
VoiceCBOnVoiceProcessPassStart,
|
||||
VoiceCBOnVoiceProcessPassEnd,
|
||||
VoiceCBOnStreamEnd,
|
||||
VoiceCBOnBufferStart,
|
||||
VoiceCBOnBufferEnd,
|
||||
VoiceCBOnLoopEnd,
|
||||
VoiceCBOnVoiceError
|
||||
};
|
||||
|
||||
static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
|
||||
|
||||
if (iscapture) {
|
||||
SDL_SetError("XAudio2: capture devices unsupported.");
|
||||
return 0;
|
||||
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
SDL_SetError("XAudio2: XAudio2Create() failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (devname != NULL) {
|
||||
UINT32 devcount = 0;
|
||||
UINT32 i = 0;
|
||||
|
||||
if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
|
||||
IXAudio2_Release(ixa2);
|
||||
SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
if (str != NULL) {
|
||||
const int match = (SDL_strcmp(str, devname) == 0);
|
||||
SDL_free(str);
|
||||
if (match) {
|
||||
devId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == devcount) {
|
||||
IXAudio2_Release(ixa2);
|
||||
SDL_SetError("XAudio2: Requested device not found.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc((sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
IXAudio2_Release(ixa2);
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
|
||||
|
||||
this->hidden->ixa2 = ixa2;
|
||||
this->hidden->semaphore = CreateSemaphore(NULL, 1, 2, NULL);
|
||||
if (this->hidden->semaphore == NULL) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_SetError("XAudio2: CreateSemaphore() failed!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((!valid_format) && (test_format)) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
case AUDIO_S16:
|
||||
case AUDIO_S32:
|
||||
case AUDIO_F32:
|
||||
this->spec.format = test_format;
|
||||
valid_format = 1;
|
||||
break;
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
if (!valid_format) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_SetError("XAudio2: Unsupported audio format");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update the fragment size as size in bytes */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
/* We feed a Source, it feeds the Mastering, which feeds the device. */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
this->hidden->nextbuf = this->hidden->mixbuf;
|
||||
SDL_memset(this->hidden->mixbuf, '\0', 2 * this->hidden->mixlen);
|
||||
|
||||
/* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
|
||||
Xbox360, this means 5.1 output, but on Windows, it means "figure out
|
||||
what the system has." It might be preferable to let XAudio2 blast
|
||||
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. */
|
||||
result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
|
||||
XAUDIO2_DEFAULT_CHANNELS,
|
||||
this->spec.freq, 0, devId, NULL);
|
||||
if (result != S_OK) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_SetError("XAudio2: Couldn't create mastering voice");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_zero(waveformat);
|
||||
if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
|
||||
waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
} else {
|
||||
waveformat.wFormatTag = WAVE_FORMAT_PCM;
|
||||
}
|
||||
waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
waveformat.nChannels = this->spec.channels;
|
||||
waveformat.nSamplesPerSec = this->spec.freq;
|
||||
waveformat.nBlockAlign =
|
||||
waveformat.nChannels * (waveformat.wBitsPerSample / 8);
|
||||
waveformat.nAvgBytesPerSec =
|
||||
waveformat.nSamplesPerSec * waveformat.nBlockAlign;
|
||||
|
||||
result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
|
||||
XAUDIO2_VOICE_NOSRC |
|
||||
XAUDIO2_VOICE_NOPITCH,
|
||||
1.0f, &callbacks, NULL, NULL);
|
||||
if (result != S_OK) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_SetError("XAudio2: Couldn't create source voice");
|
||||
return 0;
|
||||
}
|
||||
this->hidden->source = source;
|
||||
|
||||
/* Start everything playing! */
|
||||
result = IXAudio2_StartEngine(ixa2);
|
||||
if (result != S_OK) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_SetError("XAudio2: Couldn't start engine");
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
|
||||
if (result != S_OK) {
|
||||
XAUDIO2_CloseDevice(this);
|
||||
SDL_SetError("XAudio2: Couldn't start source voice");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1; /* good to go. */
|
||||
}
|
||||
|
||||
static void
|
||||
XAUDIO2_Deinitialize(void)
|
||||
{
|
||||
WIN_CoUninitialize();
|
||||
}
|
||||
|
||||
static int
|
||||
XAUDIO2_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* XAudio2Create() is a macro that uses COM; we don't load the .dll */
|
||||
IXAudio2 *ixa2 = NULL;
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
SDL_SetError("XAudio2: CoInitialize() failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
WIN_CoUninitialize();
|
||||
SDL_SetError("XAudio2: XAudio2Create() failed");
|
||||
return 0; /* not available. */
|
||||
}
|
||||
IXAudio2_Release(ixa2);
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = XAUDIO2_DetectDevices;
|
||||
impl->GetDeviceName = XAUDIO2_GetDeviceName;
|
||||
impl->OpenDevice = XAUDIO2_OpenDevice;
|
||||
impl->PlayDevice = XAUDIO2_PlayDevice;
|
||||
impl->WaitDevice = XAUDIO2_WaitDevice;
|
||||
impl->WaitDone = XAUDIO2_WaitDone;
|
||||
impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
|
||||
impl->CloseDevice = XAUDIO2_CloseDevice;
|
||||
impl->Deinitialize = XAUDIO2_Deinitialize;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap XAUDIO2_bootstrap = {
|
||||
"xaudio2", "XAudio2", XAUDIO2_Init, 0
|
||||
};
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
46
src/audio/xaudio2/SDL_xaudio2.h
Normal file
46
src/audio/xaudio2/SDL_xaudio2.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_xaudio2_h
|
||||
#define _SDL_xaudio2_h
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
#include <XAudio2.h>
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
IXAudio2 *ixa2;
|
||||
IXAudio2SourceVoice *source;
|
||||
IXAudio2MasteringVoice *mastering;
|
||||
HANDLE semaphore;
|
||||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
Uint8 *nextbuf;
|
||||
};
|
||||
|
||||
#endif /* _SDL_xaudio2_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
Loading…
Add table
Add a link
Reference in a new issue