23 #if SDL_AUDIO_DRIVER_XAUDIO2
25 #include "../../core/windows/SDL_windows.h"
27 #include "../SDL_audio_c.h"
28 #include "../SDL_sysaudio.h"
33 # define SDL_XAUDIO2_HAS_SDK 1
36 #if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
37 # pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
39 # define SDL_XAUDIO2_HAS_SDK 1
43 #ifdef SDL_XAUDIO2_HAS_SDK
49 #define _THIS SDL_AudioDevice *this
54 IXAudio2SourceVoice *
source;
55 IXAudio2MasteringVoice *mastering;
66 IXAudio2 *ixa2 =
NULL;
74 SDL_SetError(
"XAudio2: XAudio2Create() failed at detection.");
77 SDL_SetError(
"XAudio2: IXAudio2::GetDeviceCount() failed.");
82 for (i = 0; i < devcount; i++) {
96 static void STDMETHODCALLTYPE
97 VoiceCBOnBufferEnd(THIS_
void *
data)
101 ReleaseSemaphore(this->hidden->semaphore, 1,
NULL);
104 static void STDMETHODCALLTYPE
105 VoiceCBOnVoiceError(THIS_
void *
data,
HRESULT Error)
112 static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
113 static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32
b) {}
114 static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
115 static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_
void *
data) {}
116 static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_
void *
data) {}
120 XAUDIO2_GetDeviceBuf(
_THIS)
122 return this->hidden->nextbuf;
126 XAUDIO2_PlayDevice(
_THIS)
129 Uint8 *mixbuf = this->hidden->mixbuf;
130 Uint8 *nextbuf = this->hidden->nextbuf;
131 const int mixlen = this->hidden->mixlen;
132 IXAudio2SourceVoice *
source = this->hidden->source;
145 if (nextbuf == mixbuf) {
150 this->hidden->nextbuf = nextbuf;
157 if (result != S_OK) {
164 XAUDIO2_WaitDevice(
_THIS)
167 WaitForSingleObject(this->hidden->semaphore, INFINITE);
172 XAUDIO2_WaitDone(
_THIS)
174 IXAudio2SourceVoice *source = this->hidden->source;
180 WaitForSingleObject(this->hidden->semaphore, INFINITE);
187 XAUDIO2_CloseDevice(
_THIS)
189 if (this->hidden !=
NULL) {
190 IXAudio2 *ixa2 = this->hidden->ixa2;
191 IXAudio2SourceVoice *source = this->hidden->source;
192 IXAudio2MasteringVoice *mastering = this->hidden->mastering;
194 if (source !=
NULL) {
202 if (mastering !=
NULL) {
209 if (this->hidden->semaphore !=
NULL) {
210 CloseHandle(this->hidden->semaphore);
219 XAUDIO2_OpenDevice(
_THIS,
const char *devname,
int iscapture)
223 int valid_format = 0;
225 IXAudio2 *ixa2 =
NULL;
226 IXAudio2SourceVoice *source =
NULL;
229 static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
230 VoiceCBOnVoiceProcessPassStart,
231 VoiceCBOnVoiceProcessPassEnd,
233 VoiceCBOnBufferStart,
239 static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
242 return SDL_SetError(
"XAudio2: capture devices unsupported.");
244 return SDL_SetError(
"XAudio2: XAudio2Create() failed at open.");
247 if (devname !=
NULL) {
253 return SDL_SetError(
"XAudio2: IXAudio2_GetDeviceCount() failed.");
255 for (i = 0; i < devcount; i++) {
260 const int match = (
SDL_strcmp(str, devname) == 0);
272 return SDL_SetError(
"XAudio2: Requested device not found.");
279 if (this->hidden ==
NULL) {
283 SDL_memset(this->hidden, 0, (
sizeof *this->hidden));
285 this->hidden->ixa2 = ixa2;
286 this->hidden->semaphore = CreateSemaphore(
NULL, 1, 2,
NULL);
287 if (this->hidden->semaphore ==
NULL) {
288 XAUDIO2_CloseDevice(
this);
289 return SDL_SetError(
"XAudio2: CreateSemaphore() failed!");
292 while ((!valid_format) && (test_format)) {
293 switch (test_format) {
298 this->spec.format = test_format;
306 XAUDIO2_CloseDevice(
this);
307 return SDL_SetError(
"XAudio2: Unsupported audio format");
314 this->hidden->mixlen = this->spec.size;
316 if (this->hidden->mixbuf ==
NULL) {
317 XAUDIO2_CloseDevice(
this);
320 this->hidden->nextbuf = this->hidden->mixbuf;
321 SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
331 this->spec.freq, 0, devId,
NULL);
332 if (result != S_OK) {
333 XAUDIO2_CloseDevice(
this);
334 return SDL_SetError(
"XAudio2: Couldn't create mastering voice");
344 waveformat.
nChannels = this->spec.channels;
355 if (result != S_OK) {
356 XAUDIO2_CloseDevice(
this);
357 return SDL_SetError(
"XAudio2: Couldn't create source voice");
359 this->hidden->source =
source;
363 if (result != S_OK) {
364 XAUDIO2_CloseDevice(
this);
369 if (result != S_OK) {
370 XAUDIO2_CloseDevice(
this);
371 return SDL_SetError(
"XAudio2: Couldn't start source voice");
378 XAUDIO2_Deinitialize(
void)
389 #ifndef SDL_XAUDIO2_HAS_SDK
390 SDL_SetError(
"XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
394 IXAudio2 *ixa2 =
NULL;
402 SDL_SetError(
"XAudio2: XAudio2Create() failed at initialization");
422 "xaudio2",
"XAudio2", XAUDIO2_Init, 0
void(* CloseDevice)(_THIS)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
void(* SDL_AddAudioDevice)(const char *name)
void(* WaitDevice)(_THIS)
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
#define IXAudio2_StopEngine(This)
GLenum GLsizei const GLuint GLboolean enabled
Uint8 *(* GetDeviceBuf)(_THIS)
#define IXAudio2SourceVoice_Discontinuity(This)
#define IXAudio2SourceVoice_FlushSourceBuffers(This)
DECLSPEC void SDLCALL SDL_free(void *mem)
#define IXAudio2SourceVoice_GetState(This, pVoiceState)
Uint16 SDL_AudioFormat
Audio format flags.
#define IXAudio2_GetDeviceCount(This, puCount)
int(* OpenDevice)(_THIS, const char *devname, int iscapture)
SDL_AudioFormat SDL_NextAudioFormat(void)
#define IXAudio2_StartEngine(This)
#define IXAudio2_Release(This)
#define IXAudio2_CreateSourceVoice(This, ppSourceVoice, pSourceFormat, Flags, MaxFrequencyRatio, pCallback, pSendList, pEffectChain)
#define SDL_AUDIO_ISFLOAT(x)
void(* PlayDevice)(_THIS)
#define XAUDIO2_DEFAULT_CHANNELS
EGLContext EGLenum EGLClientBuffer buffer
void(* DetectDevices)(int iscapture, SDL_AddAudioDevice addfn)
#define IXAudio2_CreateMasteringVoice(This, ppMasteringVoice, InputChannels, InputSampleRate, Flags, DeviceIndex, pEffectChain)
__inline HRESULT XAudio2Create(__deref_out IXAudio2 **ppXAudio2, UINT32 Flags X2DEFAULT(0), XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR))
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
HRESULT WIN_CoInitialize(void)
#define IXAudio2SourceVoice_Start(This, Flags, OperationSet)
#define SDL_AUDIO_BITSIZE(x)
#define XAUDIO2_COMMIT_NOW
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
#define IXAudio2SourceVoice_DestroyVoice
#define WIN_StringToUTF8(S)
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
void(* Deinitialize)(void)
#define XAUDIO2_E_DEVICE_INVALIDATED
#define IXAudio2_GetDeviceDetails(This, Index, pDeviceDetails)
#define SDL_assert(condition)
#define SDL_OutOfMemory()
void WIN_CoUninitialize(void)
#define WAVE_FORMAT_IEEE_FLOAT
#define XAUDIO2_VOICE_NOPITCH
#define IXAudio2SourceVoice_SubmitSourceBuffer(This, pBuffer, pBufferWMA)
uint8_t Uint8
An unsigned 8-bit integer type.
#define IXAudio2SourceVoice_Stop(This, Flags, OperationSet)
AudioBootStrap XAUDIO2_bootstrap
GLdouble GLdouble GLdouble b
#define XAUDIO2_VOICE_NOSRC
GLsizei GLsizei GLchar * source
#define IXAudio2MasteringVoice_DestroyVoice