Commit ac93bd6e authored by Ryan C. Gordon's avatar Ryan C. Gordon

Reworked Windows DirectSound code.

Now supports multiple devices, and uses DirectSound 8 instead of 5. Changed
name to "directsound" and renamed source directory.

--HG--
rename : src/audio/windx5/SDL_dx5audio.c => src/audio/directsound/SDL_directsound.c
rename : src/audio/windx5/SDL_dx5audio.h => src/audio/directsound/SDL_directsound.h
rename : src/audio/windx5/directx.h => src/audio/directsound/directx.h
parent 55419dbf
...@@ -580,7 +580,7 @@ ...@@ -580,7 +580,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\audio\windx5\directx.h" RelativePath="..\..\src\audio\directsound\directx.h"
> >
</File> </File>
<File <File
...@@ -840,11 +840,11 @@ ...@@ -840,11 +840,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\audio\windx5\SDL_dx5audio.c" RelativePath="..\..\src\audio\directsound\SDL_directsound.c"
> >
</File> </File>
<File <File
RelativePath="..\..\src\audio\windx5\SDL_dx5audio.h" RelativePath="..\..\src\audio\directsound\SDL_directsound.h"
> >
</File> </File>
<File <File
......
...@@ -569,7 +569,7 @@ ...@@ -569,7 +569,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\audio\windx5\directx.h" RelativePath="..\..\src\audio\directsound\directx.h"
> >
</File> </File>
<File <File
...@@ -829,11 +829,11 @@ ...@@ -829,11 +829,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\audio\windx5\SDL_dx5audio.c" RelativePath="..\..\src\audio\directsound\SDL_directsound.c"
> >
</File> </File>
<File <File
RelativePath="..\..\src\audio\windx5\SDL_dx5audio.h" RelativePath="..\..\src\audio\directsound\SDL_directsound.h"
> >
</File> </File>
<File <File
......
...@@ -250,7 +250,7 @@ ...@@ -250,7 +250,7 @@
<ClInclude Include="..\..\src\core\windows\SDL_windows.h" /> <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
<ClInclude Include="..\..\src\events\blank_cursor.h" /> <ClInclude Include="..\..\src\events\blank_cursor.h" />
<ClInclude Include="..\..\src\events\default_cursor.h" /> <ClInclude Include="..\..\src\events\default_cursor.h" />
<ClInclude Include="..\..\src\audio\windx5\directx.h" /> <ClInclude Include="..\..\src\audio\directsound\directx.h" />
<ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" /> <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_gesture_c.h" /> <ClInclude Include="..\..\src\events\SDL_gesture_c.h" />
<ClInclude Include="..\..\src\events\SDL_touch_c.h" /> <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
...@@ -279,7 +279,7 @@ ...@@ -279,7 +279,7 @@
<ClInclude Include="..\..\src\audio\windib\SDL_dibaudio.h" /> <ClInclude Include="..\..\src\audio\windib\SDL_dibaudio.h" />
<ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" /> <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
<ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" /> <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
<ClInclude Include="..\..\src\audio\windx5\SDL_dx5audio.h" /> <ClInclude Include="..\..\src\audio\directsound\SDL_directsound.h" />
<ClInclude Include="..\..\src\SDL_error_c.h" /> <ClInclude Include="..\..\src\SDL_error_c.h" />
<ClInclude Include="..\..\src\SDL_hints_c.h" /> <ClInclude Include="..\..\src\SDL_hints_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" /> <ClInclude Include="..\..\src\events\SDL_events_c.h" />
...@@ -380,7 +380,7 @@ ...@@ -380,7 +380,7 @@
<ClCompile Include="..\..\src\audio\windib\SDL_dibaudio.c" /> <ClCompile Include="..\..\src\audio\windib\SDL_dibaudio.c" />
<ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c" /> <ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c" />
<ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c" /> <ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c" />
<ClCompile Include="..\..\src\audio\windx5\SDL_dx5audio.c" /> <ClCompile Include="..\..\src\audio\directsound\SDL_directsound.c" />
<ClCompile Include="..\..\src\joystick\windows\SDL_dxjoystick.c" /> <ClCompile Include="..\..\src\joystick\windows\SDL_dxjoystick.c" />
<ClCompile Include="..\..\src\SDL_error.c" /> <ClCompile Include="..\..\src\SDL_error.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" /> <ClCompile Include="..\..\src\events\SDL_events.c" />
......
...@@ -2061,7 +2061,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ...@@ -2061,7 +2061,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
SOURCES="$SOURCES $srcdir/src/audio/windib/*.c" SOURCES="$SOURCES $srcdir/src/audio/windib/*.c"
if test x$have_dsound = xyes; then if test x$have_dsound = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ]) AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
SOURCES="$SOURCES $srcdir/src/audio/windx5/*.c" SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
fi fi
have_audio=yes have_audio=yes
fi fi
...@@ -2148,7 +2148,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ...@@ -2148,7 +2148,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
SOURCES="$SOURCES $srcdir/src/audio/windib/*.c" SOURCES="$SOURCES $srcdir/src/audio/windib/*.c"
if test x$have_dsound = xyes; then if test x$have_dsound = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ]) AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
SOURCES="$SOURCES $srcdir/src/audio/windx5/*.c" SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
fi fi
have_audio=yes have_audio=yes
fi fi
......
...@@ -26,26 +26,23 @@ ...@@ -26,26 +26,23 @@
#include "SDL_loadso.h" #include "SDL_loadso.h"
#include "SDL_audio.h" #include "SDL_audio.h"
#include "../SDL_audio_c.h" #include "../SDL_audio_c.h"
#include "SDL_dx5audio.h" #include "SDL_directsound.h"
/* !!! FIXME: move this somewhere that other drivers can use it... */
#if defined(_WIN32_WCE)
#define WINDOWS_OS_NAME "Windows CE/PocketPC"
#elif defined(WIN64)
#define WINDOWS_OS_NAME "Win64"
#else
#define WINDOWS_OS_NAME "Win32"
#endif
/* DirectX function pointers for audio */ /* DirectX function pointers for audio */
static void* DSoundDLL = NULL; static void* DSoundDLL = NULL;
static HRESULT(WINAPI * DSoundCreate) (LPGUID, LPDIRECTSOUND *, LPUNKNOWN) = typedef HRESULT(WINAPI*fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
NULL; typedef HRESULT(WINAPI*fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT(WINAPI*fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
static void static void
DSOUND_Unload(void) DSOUND_Unload(void)
{ {
DSoundCreate = NULL; pDirectSoundCreate8 = NULL;
pDirectSoundEnumerateW = NULL;
pDirectSoundCaptureEnumerateW = NULL;
if (DSoundDLL != NULL) { if (DSoundDLL != NULL) {
SDL_UnloadObject(DSoundDLL); SDL_UnloadObject(DSoundDLL);
...@@ -65,18 +62,19 @@ DSOUND_Load(void) ...@@ -65,18 +62,19 @@ DSOUND_Load(void)
if (DSoundDLL == NULL) { if (DSoundDLL == NULL) {
SDL_SetError("DirectSound: failed to load DSOUND.DLL"); SDL_SetError("DirectSound: failed to load DSOUND.DLL");
} else { } else {
/* Now make sure we have DirectX 5 or better... */ /* Now make sure we have DirectX 8 or better... */
/* (DirectSoundCaptureCreate was added in DX5) */ #define DSOUNDLOAD(f) { \
if (!SDL_LoadFunction(DSoundDLL, "DirectSoundCaptureCreate")) { p##f = (fn##f) SDL_LoadFunction(DSoundDLL, #f); \
SDL_SetError("DirectSound: System doesn't appear to have DX5."); if (!p##f) loaded = 0; \
} else {
DSoundCreate = SDL_LoadFunction(DSoundDLL, "DirectSoundCreate");
} }
loaded = 1; /* will reset if necessary. */
if (!DSoundCreate) { DSOUNDLOAD(DirectSoundCreate8);
SDL_SetError("DirectSound: Failed to find DirectSoundCreate"); DSOUNDLOAD(DirectSoundEnumerateW);
} else { DSOUNDLOAD(DirectSoundCaptureEnumerateW);
loaded = 1; #undef DSOUNDLOAD
if (!loaded) {
SDL_SetError("DirectSound: System doesn't appear to have DX8.");
} }
} }
...@@ -87,6 +85,13 @@ DSOUND_Load(void) ...@@ -87,6 +85,13 @@ DSOUND_Load(void)
return loaded; return loaded;
} }
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 static void
SetDSerror(const char *function, int code) SetDSerror(const char *function, int code)
...@@ -97,7 +102,7 @@ SetDSerror(const char *function, int code) ...@@ -97,7 +102,7 @@ SetDSerror(const char *function, int code)
errbuf[0] = 0; errbuf[0] = 0;
switch (code) { switch (code) {
case E_NOINTERFACE: case E_NOINTERFACE:
error = "Unsupported interface -- Is DirectX 5.0 or later installed?"; error = "Unsupported interface -- Is DirectX 8.0 or later installed?";
break; break;
case DSERR_ALLOCATED: case DSERR_ALLOCATED:
error = "Audio device in use"; error = "Audio device in use";
...@@ -142,23 +147,100 @@ SetDSerror(const char *function, int code) ...@@ -142,23 +147,100 @@ SetDSerror(const char *function, int code)
return; return;
} }
/* DirectSound needs to be associated with a window */
static HWND mainwin = NULL;
/* */
void
DSOUND_SoundFocus(HWND hwnd) /* !!! 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
FreeDSoundAudioDevices(char ***devices, int *devCount)
{ {
/* !!! FIXME: probably broken with multi-window support in SDL 1.3 ... */ int i = *devCount;
mainwin = hwnd; if ((i > 0) && (*devices != NULL)) {
while (i--) {
SDL_free((*devices)[i]);
}
}
if (*devices != NULL) {
SDL_free(*devices);
}
*devices = NULL;
*devCount = 0;
} }
static void
DSOUND_ThreadInit(_THIS) typedef struct FindAllDevsData
{
const char **devs;
unsigned int devcount;
} FindAllDevsData;
static BOOL CALLBACK
FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID _data)
{
FindAllDevsData *data = (FindAllDevsData *) _data;
void *ptr;
char *name;
if (guid == NULL)
return TRUE; /* skip default device, go to the next one. */
ptr = SDL_realloc(data->devs, ((data->devcount) + 1) * sizeof(char *));
if (ptr == NULL)
return TRUE; /* oh well. */
data->devs = (const char **) ptr;
name = utf16_to_utf8(desc);
if (name != NULL)
data->devs[data->devcount++] = name;
return TRUE; /* keep enumerating. */
}
static char **outputDevices = NULL;
static int outputDeviceCount = 0;
static char **inputDevices = NULL;
static int inputDeviceCount = 0;
static int
DSOUND_DetectDevices(int iscapture)
{ {
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); FindAllDevsData data;
data.devs = NULL;
data.devcount = 0;
if (iscapture) {
FreeDSoundAudioDevices(&inputDevices, &inputDeviceCount);
pDirectSoundCaptureEnumerateW(FindAllDevs, &devs);
inputDevices = data.devs;
inputDeviceCount = data.devcount;
} else {
FreeDSoundAudioDevices(&outputDevices, &outputDeviceCount);
pDirectSoundEnumerateW(FindAllDevs, &devs);
outputDevices = data.devs;
outputDeviceCount = data.devcount;
}
return data.devcount;
}
static const char *
DSOUND_GetDeviceName(int index, int iscapture)
{
if ((iscapture) && (index < inputDeviceCount)) {
return inputDevices[index];
} else if ((!iscapture) && (index < outputDeviceCount)) {
return outputDevices[index];
}
SDL_SetError("No such device");
return NULL;
} }
static void static void
DSOUND_WaitDevice(_THIS) DSOUND_WaitDevice(_THIS)
{ {
...@@ -393,6 +475,30 @@ CreateSecondary(_THIS, HWND focus, WAVEFORMATEX * wavefmt) ...@@ -393,6 +475,30 @@ CreateSecondary(_THIS, HWND focus, WAVEFORMATEX * wavefmt)
return (numchunks); return (numchunks);
} }
typedef struct FindDevGUIDData
{
const char *devname;
GUID guid;
int found;
} FindDevGUIDData;
static BOOL CALLBACK
FindDevGUID(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID _data)
{
if (guid != NULL) { /* skip the default device. */
FindDevGUIDData *data = (FindDevGUIDData *) _data;
char *str = utf16_to_utf8(desc);
const int match = (SDL_strcmp(str, data->devname) == 0);
SDL_free(str);
if (match) {
data->found = 1;
SDL_memcpy(&data->guid, guid, sizeof (data->guid));
return FALSE; /* found it! stop enumerating. */
}
}
return TRUE; /* keep enumerating. */
}
static int static int
DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
{ {
...@@ -400,9 +506,23 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) ...@@ -400,9 +506,23 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
WAVEFORMATEX waveformat; WAVEFORMATEX waveformat;
int valid_format = 0; int valid_format = 0;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
FindDevGUIDData devguid;
/* !!! FIXME: handle devname */ LPGUID guid = NULL;
/* !!! FIXME: handle iscapture */
if (devname != NULL) {
devguid.found = 0;
devguid.devname = devname;
if (iscapture)
pDirectSoundCaptureEnumerateW(FindDevGUID, &devguid);
else
pDirectSoundEnumerateW(FindDevGUID, &devguid);
if (!devguid.found) {
SDL_SetError("DirectSound: Requested device not found");
return 0;
}
guid = &devguid.guid;
}
/* Initialize all variables that we clean on shutdown */ /* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *) this->hidden = (struct SDL_PrivateAudioData *)
...@@ -445,7 +565,7 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) ...@@ -445,7 +565,7 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
SDL_CalculateAudioSpec(&this->spec); SDL_CalculateAudioSpec(&this->spec);
/* Open the audio device */ /* Open the audio device */
result = DSoundCreate(NULL, &this->hidden->sound, NULL); result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
if (result != DS_OK) { if (result != DS_OK) {
DSOUND_CloseDevice(this); DSOUND_CloseDevice(this);
SetDSerror("DirectSoundCreate", result); SetDSerror("DirectSoundCreate", result);
...@@ -469,6 +589,8 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) ...@@ -469,6 +589,8 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
static void static void
DSOUND_Deinitialize(void) DSOUND_Deinitialize(void)
{ {
FreeDSoundAudioDevices(&inputDevices, &inputDeviceCount);
FreeDSoundAudioDevices(&outputDevices, &outputDeviceCount);
DSOUND_Unload(); DSOUND_Unload();
} }
...@@ -476,42 +598,26 @@ DSOUND_Deinitialize(void) ...@@ -476,42 +598,26 @@ DSOUND_Deinitialize(void)
static int static int
DSOUND_Init(SDL_AudioDriverImpl * impl) DSOUND_Init(SDL_AudioDriverImpl * impl)
{ {
OSVERSIONINFO ver;
/*
* Unfortunately, the sound drivers on NT have higher latencies than the
* audio buffers used by many SDL applications, so there are gaps in the
* audio - it sounds terrible. Punt for now.
*/
SDL_memset(&ver, '\0', sizeof(OSVERSIONINFO));
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&ver);
if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
if (ver.dwMajorVersion <= 4) {
return 0; /* NT4.0 or earlier. Disable dsound support. */
}
}
if (!DSOUND_Load()) { if (!DSOUND_Load()) {
return 0; return 0;
} }
/* Set the function pointers */ /* Set the function pointers */
impl->DetectDevices = DSOUND_DetectDevices;
impl->GetDeviceName = DSOUND_GetDeviceName;
impl->OpenDevice = DSOUND_OpenDevice; impl->OpenDevice = DSOUND_OpenDevice;
impl->PlayDevice = DSOUND_PlayDevice; impl->PlayDevice = DSOUND_PlayDevice;
impl->WaitDevice = DSOUND_WaitDevice; impl->WaitDevice = DSOUND_WaitDevice;
impl->WaitDone = DSOUND_WaitDone; impl->WaitDone = DSOUND_WaitDone;
impl->ThreadInit = DSOUND_ThreadInit;
impl->GetDeviceBuf = DSOUND_GetDeviceBuf; impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
impl->CloseDevice = DSOUND_CloseDevice; impl->CloseDevice = DSOUND_CloseDevice;
impl->Deinitialize = DSOUND_Deinitialize; impl->Deinitialize = DSOUND_Deinitialize;
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME */
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
} }
AudioBootStrap DSOUND_bootstrap = { AudioBootStrap DSOUND_bootstrap = {
"dsound", WINDOWS_OS_NAME "DirectSound", DSOUND_Init, 0 "directsound", "DirectSound", DSOUND_Init, 0
}; };
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
*/ */
#include "SDL_config.h" #include "SDL_config.h"
#ifndef _SDL_dx5audio_h #ifndef _SDL_directsound_h
#define _SDL_dx5audio_h #define _SDL_directsound_h
#include "directx.h" #include "directx.h"
...@@ -41,6 +41,6 @@ struct SDL_PrivateAudioData ...@@ -41,6 +41,6 @@ struct SDL_PrivateAudioData
Uint8 *locked_buf; Uint8 *locked_buf;
}; };
#endif /* _SDL_dx5audio_h */ #endif /* _SDL_directsound_h */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#ifndef _directx_h #ifndef _directx_h
#define _directx_h #define _directx_h
/* Include all of the DirectX 5.0 headers and adds any necessary tweaks */ /* Include all of the DirectX 8.0 headers and adds any necessary tweaks */
#include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_windows.h"
#include <mmsystem.h> #include <mmsystem.h>
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
*/ */
/* We need these defines to mark what version of DirectX API we use */ /* We need these defines to mark what version of DirectX API we use */
#define DIRECTDRAW_VERSION 0x0700 #define DIRECTDRAW_VERSION 0x0700
#define DIRECTSOUND_VERSION 0x0500 #define DIRECTSOUND_VERSION 0x0800
#define DIRECTINPUT_VERSION 0x0500 #define DIRECTINPUT_VERSION 0x0500
#include <ddraw.h> #include <ddraw.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment