diff --git a/VisualC/SDL/SDL_VS2005.vcproj b/VisualC/SDL/SDL_VS2005.vcproj
index 02fe16db2..1de6dc174 100644
--- a/VisualC/SDL/SDL_VS2005.vcproj
+++ b/VisualC/SDL/SDL_VS2005.vcproj
@@ -796,11 +796,11 @@
>
-
+
@@ -377,7 +377,7 @@
-
+
diff --git a/configure.in b/configure.in
index 4bae56ace..dcd39e6b5 100644
--- a/configure.in
+++ b/configure.in
@@ -2057,8 +2057,8 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
fi
# Set up files for the audio library
if test x$enable_audio = xyes; then
- AC_DEFINE(SDL_AUDIO_DRIVER_WINWAVEOUT, 1, [ ])
- SOURCES="$SOURCES $srcdir/src/audio/windib/*.c"
+ AC_DEFINE(SDL_AUDIO_DRIVER_WINMM, 1, [ ])
+ SOURCES="$SOURCES $srcdir/src/audio/winmm/*.c"
if test x$have_dsound = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
@@ -2144,8 +2144,8 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
fi
# Set up files for the audio library
if test x$enable_audio = xyes; then
- AC_DEFINE(SDL_AUDIO_DRIVER_WINWAVEOUT, 1, [ ])
- SOURCES="$SOURCES $srcdir/src/audio/windib/*.c"
+ AC_DEFINE(SDL_AUDIO_DRIVER_WINMM, 1, [ ])
+ SOURCES="$SOURCES $srcdir/src/audio/winmm/*.c"
if test x$have_dsound = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_DSOUND, 1, [ ])
SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c"
diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in
index 6c5714c15..84d921006 100644
--- a/include/SDL_config.h.in
+++ b/include/SDL_config.h.in
@@ -195,7 +195,7 @@
#undef SDL_AUDIO_DRIVER_PAUDIO
#undef SDL_AUDIO_DRIVER_QSA
#undef SDL_AUDIO_DRIVER_SUNAUDIO
-#undef SDL_AUDIO_DRIVER_WINWAVEOUT
+#undef SDL_AUDIO_DRIVER_WINMM
#undef SDL_AUDIO_DRIVER_FUSIONSOUND
#undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC
diff --git a/include/SDL_config_windows.h b/include/SDL_config_windows.h
index b844b2a8e..6b9295150 100644
--- a/include/SDL_config_windows.h
+++ b/include/SDL_config_windows.h
@@ -146,7 +146,7 @@ typedef unsigned int uintptr_t;
#ifndef _WIN32_WCE
#define SDL_AUDIO_DRIVER_DSOUND 1
#endif
-#define SDL_AUDIO_DRIVER_WINWAVEOUT 1
+#define SDL_AUDIO_DRIVER_WINMM 1
#define SDL_AUDIO_DRIVER_DISK 1
#define SDL_AUDIO_DRIVER_DUMMY 1
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 1aaa756c2..7f16a6549 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -53,7 +53,7 @@ extern AudioBootStrap ARTS_bootstrap;
extern AudioBootStrap ESD_bootstrap;
extern AudioBootStrap NAS_bootstrap;
extern AudioBootStrap DSOUND_bootstrap;
-extern AudioBootStrap WINWAVEOUT_bootstrap;
+extern AudioBootStrap WINMM_bootstrap;
extern AudioBootStrap PAUDIO_bootstrap;
extern AudioBootStrap BEOSAUDIO_bootstrap;
extern AudioBootStrap COREAUDIO_bootstrap;
@@ -100,8 +100,8 @@ static const AudioBootStrap *const bootstrap[] = {
#if SDL_AUDIO_DRIVER_DSOUND
&DSOUND_bootstrap,
#endif
-#if SDL_AUDIO_DRIVER_WINWAVEOUT
- &WINWAVEOUT_bootstrap,
+#if SDL_AUDIO_DRIVER_WINMM
+ &WINMM_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_PAUDIO
&PAUDIO_bootstrap,
diff --git a/src/audio/windib/SDL_dibaudio.c b/src/audio/winmm/SDL_winmm.c
similarity index 56%
rename from src/audio/windib/SDL_dibaudio.c
rename to src/audio/winmm/SDL_winmm.c
index f2650586d..4a2c30a4e 100644
--- a/src/audio/windib/SDL_dibaudio.c
+++ b/src/audio/winmm/SDL_winmm.c
@@ -28,23 +28,119 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
-#include "SDL_dibaudio.h"
+#include "SDL_winmm.h"
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
#include "win_ce_semaphore.h"
#endif
-#if defined(_WIN32_WCE)
-#define WINDOWS_OS_NAME "Windows CE/PocketPC"
-#elif defined(WIN64)
-#define WINDOWS_OS_NAME "Win64"
+
+/* !!! 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
+FreeWaveOutAudioDevices(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 char **inputDevices = NULL;
+static int inputDeviceCount = 0;
+
+static int
+DetectWaveOutDevices(void)
+{
+ UINT i;
+ const UINT devcount = waveOutGetNumDevs();
+ WAVEOUTCAPS caps;
+ FreeWaveOutAudioDevices(&outputDevices, &outputDeviceCount);
+ outputDevices = (const char **) SDL_malloc(sizeof (char *) * devcount);
+ for (i = 0; i < devcount; i++) {
+ if (waveOutGetDevCaps(i, &caps, sizeof (caps)) == MMSYSERR_NOERROR) {
+ outputDevices[outputDeviceCount] = WIN_StringToUTF8(caps.szPname);
+ if (outputDevices[outputDeviceCount] != NULL) {
+ outputDeviceCount++;
+ }
+ }
+ }
+ return outputDeviceCount;
+}
+
+static int
+DetectWaveInDevices(void)
+{
+ UINT i;
+ const UINT devcount = waveInGetNumDevs();
+ WAVEINCAPS caps;
+ FreeWaveInAudioDevices(&inputDevices, &inputDeviceCount);
+ inputDevices = (const char **) SDL_malloc(sizeof (char *) * devcount);
+ for (i = 0; i < devcount; i++) {
+ if (waveInGetDevCaps(i, &caps, sizeof (caps)) == MMSYSERR_NOERROR) {
+ inputDevices[inputDeviceCount] = WIN_StringToUTF8(caps.szPname);
+ if (inputDevices[inputDeviceCount] != NULL) {
+ inputDeviceCount++;
+ }
+ }
+ }
+ return inputDeviceCount;
+}
+
+static int
+WINMM_DetectDevices(int iscapture)
+{
+ return (iscapture) ? DetectWaveInDevices() : DetectWaveOutDevices();
+}
+
+static const char *
+WINMM_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 CALLBACK
+CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
+ DWORD_PTR dwParam1, DWORD_PTR dwParam2)
+{
+ SDL_AudioDevice *this = (SDL_AudioDevice *) dwInstance;
+
+ /* Only service "buffer is filled" messages */
+ if (uMsg != WIM_DATA)
+ return;
+
+ /* Signal that we have a new buffer of data */
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+ ReleaseSemaphoreCE(this->hidden->audio_sem, 1, NULL);
#else
-#define WINDOWS_OS_NAME "Win32"
+ ReleaseSemaphore(this->hidden->audio_sem, 1, NULL);
#endif
+}
+
/* The Win32 callback for filling the WAVE device */
static void CALLBACK
FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
SDL_AudioDevice *this = (SDL_AudioDevice *) dwInstance;
@@ -77,15 +173,8 @@ SetMMerror(char *function, MMRESULT code)
SDL_SetError("%s", errbuf);
}
-/* Set high priority for the audio thread */
static void
-WINWAVEOUT_ThreadInit(_THIS)
-{
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
-}
-
-void
-WINWAVEOUT_WaitDevice(_THIS)
+WINMM_WaitDevice(_THIS)
{
/* Wait for an audio chunk to finish */
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
@@ -95,25 +184,25 @@ WINWAVEOUT_WaitDevice(_THIS)
#endif
}
-Uint8 *
-WINWAVEOUT_GetDeviceBuf(_THIS)
+static Uint8 *
+WINMM_GetDeviceBuf(_THIS)
{
return (Uint8 *) (this->hidden->
wavebuf[this->hidden->next_buffer].lpData);
}
-void
-WINWAVEOUT_PlayDevice(_THIS)
+static void
+WINMM_PlayDevice(_THIS)
{
/* Queue it up */
- waveOutWrite(this->hidden->sound,
+ waveOutWrite(this->hidden->hout,
&this->hidden->wavebuf[this->hidden->next_buffer],
sizeof(this->hidden->wavebuf[0]));
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
}
-void
-WINWAVEOUT_WaitDone(_THIS)
+static void
+WINMM_WaitDone(_THIS)
{
int i, left;
@@ -130,8 +219,8 @@ WINWAVEOUT_WaitDone(_THIS)
} while (left > 0);
}
-void
-WINWAVEOUT_CloseDevice(_THIS)
+static void
+WINMM_CloseDevice(_THIS)
{
/* Close up audio */
if (this->hidden != NULL) {
@@ -146,15 +235,20 @@ WINWAVEOUT_CloseDevice(_THIS)
this->hidden->audio_sem = 0;
}
- if (this->hidden->sound) {
- waveOutClose(this->hidden->sound);
- this->hidden->sound = 0;
+ if (this->hidden->hin) {
+ waveInClose(this->hidden->hin);
+ this->hidden->hin = 0;
+ }
+
+ if (this->hidden->hout) {
+ waveOutClose(this->hidden->hout);
+ this->hidden->hout = 0;
}
/* Clean up mixing buffers */
for (i = 0; i < NUM_BUFFERS; ++i) {
if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
- waveOutUnprepareHeader(this->hidden->sound,
+ waveOutUnprepareHeader(this->hidden->hout,
&this->hidden->wavebuf[i],
sizeof(this->hidden->wavebuf[i]));
this->hidden->wavebuf[i].dwUser = 0xFFFF;
@@ -172,15 +266,52 @@ WINWAVEOUT_CloseDevice(_THIS)
}
}
-int
-WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
+static int
+WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
{
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int valid_datatype = 0;
MMRESULT result;
WAVEFORMATEX waveformat;
+ UINT_PTR devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
+ char *utf8 = NULL;
int i;
+ if (devname != NULL) { /* specific device requested? */
+ if (iscapture) {
+ const int devcount = (int) waveInGetNumDevs();
+ WAVEINCAPS caps;
+ for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
+ result = waveInGetDevCaps(i, &caps, sizeof (caps));
+ if (result != MMSYSERR_NOERROR)
+ continue;
+ else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
+ continue;
+ else if (SDL_strcmp(devname, utf8) == 0)
+ devId = (UINT_PTR) i;
+ SDL_free(utf8);
+ }
+ } else {
+ const int devcount = (int) waveOutGetNumDevs();
+ WAVEOUTCAPS caps;
+ for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
+ result = waveOutGetDevCaps(i, &caps, sizeof (caps));
+ if (result != MMSYSERR_NOERROR)
+ continue;
+ else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
+ continue;
+ else if (SDL_strcmp(devname, utf8) == 0)
+ devId = (UINT_PTR) i;
+ SDL_free(utf8);
+ }
+ }
+
+ if (devId == WAVE_MAPPER) {
+ SDL_SetError("Requested device not found");
+ return 0;
+ }
+ }
+
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden));
@@ -211,7 +342,7 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
}
if (!valid_datatype) {
- WINWAVEOUT_CloseDevice(this);
+ WINMM_CloseDevice(this);
SDL_SetError("Unsupported audio format");
return 0;
}
@@ -239,11 +370,18 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
SDL_CalculateAudioSpec(&this->spec);
/* Open the audio device */
- result = waveOutOpen(&this->hidden->sound, WAVE_MAPPER, &waveformat,
- (DWORD_PTR) FillSound, (DWORD_PTR) this,
- CALLBACK_FUNCTION);
+ if (iscapture) {
+ result = waveInOpen(&this->hidden->hin, devId, &waveformat,
+ (DWORD_PTR) CaptureSound, (DWORD_PTR) this,
+ CALLBACK_FUNCTION);
+ } else {
+ result = waveOutOpen(&this->hidden->hout, devId, &waveformat,
+ (DWORD_PTR) FillSound, (DWORD_PTR) this,
+ CALLBACK_FUNCTION);
+ }
+
if (result != MMSYSERR_NOERROR) {
- WINWAVEOUT_CloseDevice(this);
+ WINMM_CloseDevice(this);
SetMMerror("waveOutOpen()", result);
return 0;
}
@@ -252,10 +390,10 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
{
WAVEOUTCAPS caps;
- result = waveOutGetDevCaps((UINT) this->hidden->sound,
+ result = waveOutGetDevCaps((UINT) this->hidden->hout,
&caps, sizeof(caps));
if (result != MMSYSERR_NOERROR) {
- WINWAVEOUT_CloseDevice(this);
+ WINMM_CloseDevice(this);
SetMMerror("waveOutGetDevCaps()", result);
return 0;
}
@@ -271,7 +409,7 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
#endif
if (this->hidden->audio_sem == NULL) {
- WINWAVEOUT_CloseDevice(this);
+ WINMM_CloseDevice(this);
SDL_SetError("Couldn't create semaphore");
return 0;
}
@@ -280,7 +418,7 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
this->hidden->mixbuf =
(Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
if (this->hidden->mixbuf == NULL) {
- WINWAVEOUT_CloseDevice(this);
+ WINMM_CloseDevice(this);
SDL_OutOfMemory();
return 0;
}
@@ -291,11 +429,11 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
this->hidden->wavebuf[i].dwFlags = WHDR_DONE;
this->hidden->wavebuf[i].lpData =
(LPSTR) & this->hidden->mixbuf[i * this->spec.size];
- result = waveOutPrepareHeader(this->hidden->sound,
+ result = waveOutPrepareHeader(this->hidden->hout,
&this->hidden->wavebuf[i],
sizeof(this->hidden->wavebuf[i]));
if (result != MMSYSERR_NOERROR) {
- WINWAVEOUT_CloseDevice(this);
+ WINMM_CloseDevice(this);
SetMMerror("waveOutPrepareHeader()", result);
return 0;
}
@@ -306,23 +444,23 @@ WINWAVEOUT_OpenDevice(_THIS, const char *devname, int iscapture)
static int
-WINWAVEOUT_Init(SDL_AudioDriverImpl * impl)
+WINMM_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
- impl->OpenDevice = WINWAVEOUT_OpenDevice;
- impl->ThreadInit = WINWAVEOUT_ThreadInit;
- impl->PlayDevice = WINWAVEOUT_PlayDevice;
- impl->WaitDevice = WINWAVEOUT_WaitDevice;
- impl->WaitDone = WINWAVEOUT_WaitDone;
- impl->GetDeviceBuf = WINWAVEOUT_GetDeviceBuf;
- impl->CloseDevice = WINWAVEOUT_CloseDevice;
- impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: Is this true? */
+ impl->DetectDevices = WINMM_DetectDevices;
+ impl->GetDeviceName = WINMM_GetDeviceName;
+ impl->OpenDevice = WINMM_OpenDevice;
+ impl->PlayDevice = WINMM_PlayDevice;
+ impl->WaitDevice = WINMM_WaitDevice;
+ impl->WaitDone = WINMM_WaitDone;
+ impl->GetDeviceBuf = WINMM_GetDeviceBuf;
+ impl->CloseDevice = WINMM_CloseDevice;
return 1; /* this audio target is available. */
}
-AudioBootStrap WINWAVEOUT_bootstrap = {
- "waveout", WINDOWS_OS_NAME " WaveOut", WINWAVEOUT_Init, 0
+AudioBootStrap WINMM_bootstrap = {
+ "winmm", "Windows Waveform Audio", WINMM_Init, 0
};
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/audio/windib/SDL_dibaudio.h b/src/audio/winmm/SDL_winmm.h
similarity index 93%
rename from src/audio/windib/SDL_dibaudio.h
rename to src/audio/winmm/SDL_winmm.h
index 8a2fcc91d..f68ed28d7 100644
--- a/src/audio/windib/SDL_dibaudio.h
+++ b/src/audio/winmm/SDL_winmm.h
@@ -20,8 +20,8 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_dibaudio_h
-#define _SDL_dibaudio_h
+#ifndef _SDL_winmm_h
+#define _SDL_winmm_h
#include "../SDL_sysaudio.h"
@@ -32,13 +32,14 @@
struct SDL_PrivateAudioData
{
- HWAVEOUT sound;
+ HWAVEOUT hout;
+ HWAVEIN hin;
HANDLE audio_sem;
Uint8 *mixbuf; /* The raw allocated mixing buffer */
WAVEHDR wavebuf[NUM_BUFFERS]; /* Wave audio fragments */
int next_buffer;
};
-#endif /* _SDL_dibaudio_h */
+#endif /* _SDL_winmm_h */
/* vi: set ts=4 sw=4 expandtab: */