Commit 8e6153c3 authored by Ryan C. Gordon's avatar Ryan C. Gordon

Cleaned up audio device detection. Cleared out a lot of cut-and-paste.

parent 46bb3d87
......@@ -151,10 +151,9 @@ get_audio_device(SDL_AudioDeviceID id)
/* stubs for audio drivers that don't need a specific entry point... */
static int
SDL_AudioDetectDevices_Default(int iscapture)
{
return -1;
static void
SDL_AudioDetectDevices_Default(int iscapture, SDL_AddAudioDevice addfn)
{ /* no-op. */
}
static void
......@@ -199,13 +198,6 @@ SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
return 0;
}
static const char *
SDL_AudioGetDeviceName_Default(int index, int iscapture)
{
SDL_SetError("No such device");
return NULL;
}
static void
SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
{
......@@ -238,7 +230,6 @@ finalize_audio_entry_points(void)
current_audio.impl.x = SDL_Audio##x##_Default; \
}
FILL_STUB(DetectDevices);
FILL_STUB(GetDeviceName);
FILL_STUB(OpenDevice);
FILL_STUB(ThreadInit);
FILL_STUB(WaitDevice);
......@@ -641,13 +632,64 @@ SDL_GetCurrentAudioDriver()
return current_audio.name;
}
static void
free_device_list(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
void SDL_AddCaptureAudioDevice(const char *_name)
{
char *name = NULL;
void *ptr = SDL_realloc(current_audio.inputDevices,
(current_audio.inputDeviceCount+1) * sizeof(char*));
if (ptr == NULL) {
return; /* oh well. */
}
current_audio.inputDevices = (char **) ptr;
name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
current_audio.inputDevices[current_audio.inputDeviceCount++] = name;
}
static
void SDL_AddOutputAudioDevice(const char *_name)
{
char *name = NULL;
void *ptr = SDL_realloc(current_audio.outputDevices,
(current_audio.outputDeviceCount+1) * sizeof(char*));
if (ptr == NULL) {
return; /* oh well. */
}
current_audio.outputDevices = (char **) ptr;
name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
current_audio.outputDevices[current_audio.outputDeviceCount++] = name;
}
int
SDL_GetNumAudioDevices(int iscapture)
{
int retval = 0;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
return -1;
}
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
return 0;
}
......@@ -660,7 +702,19 @@ SDL_GetNumAudioDevices(int iscapture)
return 1;
}
return current_audio.impl.DetectDevices(iscapture);
if (iscapture) {
free_device_list(&current_audio.inputDevices,
&current_audio.inputDeviceCount);
current_audio.impl.DetectDevices(iscapture, SDL_AddCaptureAudioDevice);
retval = current_audio.inputDeviceCount;
} else {
free_device_list(&current_audio.outputDevices,
&current_audio.outputDeviceCount);
current_audio.impl.DetectDevices(iscapture, SDL_AddOutputAudioDevice);
retval = current_audio.outputDeviceCount;
}
return retval;
}
......@@ -678,8 +732,7 @@ SDL_GetAudioDeviceName(int index, int iscapture)
}
if (index < 0) {
SDL_SetError("No such device");
return NULL;
goto no_such_device;
}
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
......@@ -690,7 +743,21 @@ SDL_GetAudioDeviceName(int index, int iscapture)
return DEFAULT_OUTPUT_DEVNAME;
}
return current_audio.impl.GetDeviceName(index, iscapture);
if (iscapture) {
if (index >= current_audio.inputDeviceCount) {
goto no_such_device;
}
return current_audio.inputDevices[index];
} else {
if (index >= current_audio.outputDeviceCount) {
goto no_such_device;
}
return current_audio.outputDevices[index];
}
no_such_device:
SDL_SetError("No such device");
return NULL;
}
......@@ -880,6 +947,11 @@ open_audio_device(const char *devname, int iscapture,
}
}
/* force a device detection if we haven't done one yet. */
if ( ((iscapture) && (current_audio.inputDevices == NULL)) ||
((!iscapture) && (current_audio.outputDevices == NULL)) )
SDL_GetNumAudioDevices(iscapture);
if (!current_audio.impl.OpenDevice(device, devname, iscapture)) {
close_audio_device(device);
return 0;
......@@ -1121,6 +1193,10 @@ SDL_AudioQuit(void)
/* Free the driver data */
current_audio.impl.Deinitialize();
free_device_list(&current_audio.outputDevices,
&current_audio.outputDeviceCount);
free_device_list(&current_audio.inputDevices,
&current_audio.inputDeviceCount);
SDL_memset(&current_audio, '\0', sizeof(current_audio));
SDL_memset(open_devices, '\0', sizeof(open_devices));
}
......
......@@ -48,46 +48,20 @@
static inline void
test_device(const char *fname, int flags, int (*test) (int fd),
char ***devices, int *devCount)
SDL_AddAudioDevice addfn)
{
struct stat sb;
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
int audio_fd = open(fname, flags, 0);
if ((audio_fd >= 0) && (test(audio_fd))) {
void *p =
SDL_realloc(*devices, ((*devCount) + 1) * sizeof(char *));
if (p != NULL) {
size_t len = strlen(fname) + 1;
char *str = (char *) SDL_malloc(len);
*devices = (char **) p;
if (str != NULL) {
SDL_strlcpy(str, fname, len);
(*devices)[(*devCount)++] = str;
}
const int audio_fd = open(fname, flags, 0);
if (audio_fd >= 0) {
if (test(audio_fd)) {
addfn(fname);
}
close(audio_fd);
}
}
}
void
SDL_FreeUnixAudioDevices(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 int
test_stub(int fd)
{
......@@ -95,9 +69,10 @@ test_stub(int fd)
}
void
SDL_EnumUnixAudioDevices(int flags, int classic, int (*test) (int fd),
char ***devices, int *devCount)
SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd),
SDL_AddAudioDevice addfn)
{
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
const char *audiodev;
char audiopath[1024];
......@@ -122,14 +97,14 @@ SDL_EnumUnixAudioDevices(int flags, int classic, int (*test) (int fd),
}
}
}
test_device(audiodev, flags, test, devices, devCount);
test_device(audiodev, flags, test, addfn);
if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) {
int instance = 0;
while (instance++ <= 64) {
SDL_snprintf(audiopath, SDL_arraysize(audiopath),
"%s%d", audiodev, instance);
test_device(audiopath, flags, test, devices, devCount);
test_device(audiopath, flags, test, addfn);
}
}
}
......
......@@ -18,10 +18,22 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL.h"
#include "SDL_config.h"
#include "SDL_sysaudio.h"
void SDL_EnumUnixAudioDevices(int flags, int classic, int (*test) (int fd),
char ***devs, int *count);
void SDL_FreeUnixAudioDevices(char ***devices, int *devCount);
/* Open the audio device for playback, and don't block if busy */
/* #define USE_BLOCKING_WRITES */
#ifdef USE_BLOCKING_WRITES
#define OPEN_FLAGS_OUTPUT O_WRONLY
#define OPEN_FLAGS_INPUT O_RDONLY
#else
#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
#endif
void SDL_EnumUnixAudioDevices(int iscapture, int classic,
int (*test) (int fd), SDL_AddAudioDevice addfn);
/* vi: set ts=4 sw=4 expandtab: */
......@@ -30,10 +30,12 @@
typedef struct SDL_AudioDevice SDL_AudioDevice;
#define _THIS SDL_AudioDevice *_this
/* Used by audio targets during DetectDevices() */
typedef void (*SDL_AddAudioDevice)(const char *name);
typedef struct SDL_AudioDriverImpl
{
int (*DetectDevices) (int iscapture);
const char *(*GetDeviceName) (int index, int iscapture);
void (*DetectDevices) (int iscapture, SDL_AddAudioDevice addfn);
int (*OpenDevice) (_THIS, const char *devname, int iscapture);
void (*ThreadInit) (_THIS); /* Called by audio thread at start */
void (*WaitDevice) (_THIS);
......@@ -67,6 +69,12 @@ typedef struct SDL_AudioDriver
const char *desc;
SDL_AudioDriverImpl impl;
char **outputDevices;
int outputDeviceCount;
char **inputDevices;
int inputDeviceCount;
} SDL_AudioDriver;
......
......@@ -50,91 +50,23 @@
#define BSD_AUDIO_DRIVER_DESC "Native OpenBSD audio"
#endif
/* Open the audio device for playback, and don't block if busy */
/* #define USE_BLOCKING_WRITES */
/* Use timer for synchronization */
/* #define USE_TIMER_SYNC */
/* #define DEBUG_AUDIO */
/* #define DEBUG_AUDIO_STREAM */
#ifdef USE_BLOCKING_WRITES
#define OPEN_FLAGS_OUTPUT O_WRONLY
#define OPEN_FLAGS_INPUT O_RDONLY
#else
#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
#endif
/* !!! FIXME: so much cut and paste with dsp target... */
static char **outputDevices = NULL;
static int outputDeviceCount = 0;
static char **inputDevices = NULL;
static int inputDeviceCount = 0;
static inline void
free_device_list(char ***devs, int *count)
{
SDL_FreeUnixAudioDevices(devs, count);
}
static inline void
build_device_list(int iscapture, char ***devs, int *count)
{
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
free_device_list(devs, count);
SDL_EnumUnixAudioDevices(flags, 0, NULL, devs, count);
}
static inline void
build_device_lists(void)
{
build_device_list(0, &outputDevices, &outputDeviceCount);
build_device_list(1, &inputDevices, &inputDeviceCount);
}
static inline void
free_device_lists(void)
{
free_device_list(&outputDevices, &outputDeviceCount);
free_device_list(&inputDevices, &inputDeviceCount);
}
static void
BSDAUDIO_Deinitialize(void)
{
free_device_lists();
}
static int
BSDAUDIO_DetectDevices(int iscapture)
{
if (iscapture) {
build_device_list(1, &inputDevices, &inputDeviceCount);
return inputDeviceCount;
} else {
build_device_list(0, &outputDevices, &outputDeviceCount);
return outputDeviceCount;
}
return 0; /* shouldn't ever hit this. */
}
static const char *
BSDAUDIO_GetDeviceName(int index, int iscapture)
static void
BSDAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
{
if ((iscapture) && (index < inputDeviceCount)) {
return inputDevices[index];
} else if ((!iscapture) && (index < outputDeviceCount)) {
return outputDevices[index];
}
SDL_SetError("No such device");
return NULL;
SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn);
}
......@@ -318,12 +250,11 @@ BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
/* We don't care what the devname is...we'll try to open anything. */
/* ...but default to first name in the list... */
if (devname == NULL) {
if (((iscapture) && (inputDeviceCount == 0)) ||
((!iscapture) && (outputDeviceCount == 0))) {
devname = SDL_GetAudioDeviceName(0, iscapture);
if (devname == NULL) {
SDL_SetError("No such audio device");
return 0;
}
devname = ((iscapture) ? inputDevices[0] : outputDevices[0]);
}
/* Initialize all variables that we clean on shutdown */
......@@ -434,7 +365,6 @@ BSDAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->DetectDevices = BSDAUDIO_DetectDevices;
impl->GetDeviceName = BSDAUDIO_GetDeviceName;
impl->OpenDevice = BSDAUDIO_OpenDevice;
impl->PlayDevice = BSDAUDIO_PlayDevice;
impl->WaitDevice = BSDAUDIO_WaitDevice;
......@@ -442,8 +372,6 @@ BSDAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = BSDAUDIO_CloseDevice;
impl->Deinitialize = BSDAUDIO_Deinitialize;
build_device_lists();
return 1; /* this audio target is available. */
}
......
......@@ -148,96 +148,28 @@ SetDSerror(const char *function, int code)
}
/* !!! 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)
static BOOL CALLBACK
FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
{
int i = *devCount;
if ((i > 0) && (*devices != NULL)) {
while (i--) {
SDL_free((*devices)[i]);
SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data;
if (guid != NULL) { /* skip default device */
char *str = utf16_to_utf8(desc);
if (str != NULL) {
addfn(str);
SDL_free(str); /* addfn() makes a copy of this string. */
}
}
if (*devices != NULL) {
SDL_free(*devices);
}
*devices = NULL;
*devCount = 0;
}
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)
static void
DSOUND_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
{
FindAllDevsData data;
data.devs = NULL;
data.devcount = 0;
if (iscapture) {
FreeDSoundAudioDevices(&inputDevices, &inputDeviceCount);
pDirectSoundCaptureEnumerateW(FindAllDevs, &devs);
inputDevices = data.devs;
inputDeviceCount = data.devcount;
pDirectSoundCaptureEnumerateW(FindAllDevs, addfn);
} else {
FreeDSoundAudioDevices(&outputDevices, &outputDeviceCount);
pDirectSoundEnumerateW(FindAllDevs, &devs);
outputDevices = data.devs;
outputDeviceCount = data.devcount;
pDirectSoundEnumerateW(FindAllDevs, addfn);
}
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;
}
......@@ -589,8 +521,6 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
static void
DSOUND_Deinitialize(void)
{
FreeDSoundAudioDevices(&inputDevices, &inputDeviceCount);
FreeDSoundAudioDevices(&outputDevices, &outputDeviceCount);
DSOUND_Unload();
}
......@@ -604,7 +534,6 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
/* Set the function pointers */
impl->DetectDevices = DSOUND_DetectDevices;
impl->GetDeviceName = DSOUND_GetDeviceName;
impl->OpenDevice = DSOUND_OpenDevice;
impl->PlayDevice = DSOUND_PlayDevice;
impl->WaitDevice = DSOUND_WaitDevice;
......
......@@ -50,77 +50,16 @@
/* The tag name used by DSP audio */
#define DSP_DRIVER_NAME "dsp"
/* Open the audio device for playback, and don't block if busy */
#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
static char **outputDevices = NULL;
static int outputDeviceCount = 0;
static char **inputDevices = NULL;
static int inputDeviceCount = 0;
static inline void
free_device_list(char ***devs, int *count)
{
SDL_FreeUnixAudioDevices(devs, count);
}
static inline void
build_device_list(int iscapture, char ***devs, int *count)
{
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
free_device_list(devs, count);
SDL_EnumUnixAudioDevices(flags, 0, NULL, devs, count);
}
static inline void
build_device_lists(void)
{
build_device_list(0, &outputDevices, &outputDeviceCount);
build_device_list(1, &inputDevices, &inputDeviceCount);
}
static inline void
free_device_lists(void)
{
free_device_list(&outputDevices, &outputDeviceCount);
free_device_list(&inputDevices, &inputDeviceCount);
}
static void
DSP_Deinitialize(void)
{
free_device_lists();
}
static int
static void
DSP_DetectDevices(int iscapture)
{
if (iscapture) {
build_device_list(1, &inputDevices, &inputDeviceCount);
return inputDeviceCount;
} else {
build_device_list(0, &outputDevices, &outputDeviceCount);
return outputDeviceCount;
}
return 0; /* shouldn't ever hit this. */
}
static const char *
DSP_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;
SDL_EnumUnixAudioDevices(iscapture, 0, NULL);
}
......@@ -154,12 +93,11 @@ DSP_OpenDevice(_THIS, const char *devname, int iscapture)
/* We don't care what the devname is...we'll try to open anything. */
/* ...but default to first name in the list... */
if (devname == NULL) {
if (((iscapture) && (inputDeviceCount == 0)) ||
((!iscapture) && (outputDeviceCount == 0))) {
devname = SDL_GetAudioDeviceName(0, iscapture);
if (devname == NULL) {
SDL_SetError("No such audio device");
return 0;
}
devname = ((iscapture) ? inputDevices[0] : outputDevices[0]);
}
/* Make sure fragment size stays a power of 2, or OSS fails. */
......@@ -369,15 +307,12 @@ DSP_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->DetectDevices = DSP_DetectDevices;
impl->GetDeviceName = DSP_GetDeviceName;
impl->OpenDevice = DSP_OpenDevice;
impl->PlayDevice = DSP_PlayDevice;
impl->GetDeviceBuf = DSP_GetDeviceBuf;
impl->CloseDevice = DSP_CloseDevice;
impl->Deinitialize = DSP_Deinitialize;
build_device_lists();
return 1; /* this audio target is available. */
}
......
......@@ -34,34 +34,36 @@
#define DEBUG_COREAUDIO 0
typedef struct COREAUDIO_DeviceList
typedef void (*addDevFn)(const char *name, AudioDeviceID devId, void *data);
static void
addToDevList(const char *name, AudioDeviceID devId, void *data)
{
AudioDeviceID id;
const char *name;
} COREAUDIO_DeviceList;
SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data;
addfn(name);
}
static COREAUDIO_DeviceList *inputDevices = NULL;
static int inputDeviceCount = 0;
static COREAUDIO_DeviceList *outputDevices = NULL;
static int outputDeviceCount = 0;
typedef struct
{
const char *findname;
AudioDeviceID devId;
int found;
} FindDevIdData;
static void
free_device_list(COREAUDIO_DeviceList ** devices, int *devCount)
findDevId(const char *name, AudioDeviceID devId, void *_data)
{
if (*devices) {
int i = *devCount;
while (i--)
SDL_free((void *) (*devices)[i].name);
SDL_free(*devices);
*devices = NULL;
FindDevIdData *data = (FindDevIdData *) _data;
if (!data->found) {
if (SDL_strcmp(name, data->findname) == 0) {
data->found = 1;
data->devId = devId;
}
}
*devCount = 0;
}
static void
build_device_list(int iscapture, COREAUDIO_DeviceList ** devices,
int *devCount)
build_device_list(int iscapture, addDevFn addfn, void *addfndata)
{
Boolean outWritable = 0;
OSStatus result = noErr;
......@@ -70,8 +72,6 @@ build_device_list(int iscapture, COREAUDIO_DeviceList ** devices,
UInt32 i = 0;
UInt32 max = 0;
free_device_list(devices, devCount);
result = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
&size, &outWritable);
......@@ -82,16 +82,12 @@ build_device_list(int iscapture, COREAUDIO_DeviceList ** devices,
if (devs == NULL)
return;
max = size / sizeof(AudioDeviceID);
*devices = (COREAUDIO_DeviceList *) SDL_malloc(max * sizeof(**devices));
if (*devices == NULL)
return;
result = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
&size, devs);
if (result != kAudioHardwareNoError)
return;
max = size / sizeof (AudioDeviceID);
for (i = 0; i < max; i++) {
CFStringRef cfstr = NULL;
char *ptr = NULL;
......@@ -156,9 +152,7 @@ build_device_list(int iscapture, COREAUDIO_DeviceList ** devices,
usable = (len > 0);
}
if (!usable) {
SDL_free(ptr);
} else {
if (usable) {
ptr[len] = '\0';
#if DEBUG_COREAUDIO
......@@ -166,80 +160,22 @@ build_device_list(int iscapture, COREAUDIO_DeviceList ** devices,
((iscapture) ? "capture" : "output"),
(int) *devCount, ptr, (int) dev);
#endif
(*devices)[*devCount].id = dev;
(*devices)[*devCount].name = ptr;
(*devCount)++;
}
}
}
static inline void
build_device_lists(void)
{
build_device_list(0, &outputDevices, &outputDeviceCount);
build_device_list(1, &inputDevices, &inputDeviceCount);
}
static inline void
free_device_lists(void)
{
free_device_list(&outputDevices, &outputDeviceCount);
free_device_list(&inputDevices, &inputDeviceCount);
}
static int
find_device_id(const char *devname, int iscapture, AudioDeviceID * id)
{
int i = ((iscapture) ? inputDeviceCount : outputDeviceCount);
COREAUDIO_DeviceList *devs = ((iscapture) ? inputDevices : outputDevices);
while (i--) {
if (SDL_strcmp(devname, devs->name) == 0) {
*id = devs->id;
return 1;
addfn(ptr, dev, addfndata);
}
devs++;
}
return 0;
}
static int
COREAUDIO_DetectDevices(int iscapture)
{
if (iscapture) {
build_device_list(1, &inputDevices, &inputDeviceCount);
return inputDeviceCount;
} else {
build_device_list(0, &outputDevices, &outputDeviceCount);
return outputDeviceCount;
SDL_free(ptr); /* addfn() would have copied the string. */
}
return 0; /* shouldn't ever hit this. */
}
static const char *
COREAUDIO_GetDeviceName(int index, int iscapture)
static void
COREAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
{
if ((iscapture) && (index < inputDeviceCount)) {
return inputDevices[index].name;
} else if ((!iscapture) && (index < outputDeviceCount)) {
return outputDevices[index].name;
}
SDL_SetError("No such device");
return NULL;
build_device_list(iscapture, addToDevList, addfn);
}
static void
COREAUDIO_Deinitialize(void)
{
free_device_lists();
}
......@@ -378,10 +314,15 @@ find_device_by_name(_THIS, const char *devname, int iscapture)
result = AudioHardwareGetProperty(propid, &size, &devid);
CHECK_RESULT("AudioHardwareGetProperty (default device)");
} else {
if (!find_device_id(devname, iscapture, &devid)) {
FindDevIdData data;
SDL_zero(data);
data.findname = devname;
build_device_list(iscapture, findDevId, &data);
if (!data.found) {
SDL_SetError("CoreAudio: No such audio device.");
return 0;
}
devid = data.devId;
}
size = sizeof(alive);
......@@ -565,14 +506,11 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->DetectDevices = COREAUDIO_DetectDevices;
impl->GetDeviceName = COREAUDIO_GetDeviceName;
impl->OpenDevice = COREAUDIO_OpenDevice;
impl->CloseDevice = COREAUDIO_CloseDevice;
impl->Deinitialize = COREAUDIO_Deinitialize;
impl->ProvidesOwnCallbackThread = 1;
build_device_lists(); /* do an initial check for devices... */
return 1; /* this audio target is available. */
}
......
......@@ -651,8 +651,8 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture)
return 1;
}
static int
QSA_DetectDevices(int iscapture)
static void
QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
{
uint32_t it;
uint32_t cards;
......@@ -667,7 +667,7 @@ QSA_DetectDevices(int iscapture)
/* of available audio devices */
if (cards == 0) {
/* We have no any available audio devices */
return 0;
return;
}
/* Find requested devices by type */
......@@ -702,6 +702,7 @@ QSA_DetectDevices(int iscapture)
devices;
status = snd_pcm_close(handle);
if (status == EOK) {
addfn(qsa_playback_device[qsa_playback_devices].name);
qsa_playback_devices++;
}
} else {
......@@ -757,6 +758,7 @@ QSA_DetectDevices(int iscapture)
devices;
status = snd_pcm_close(handle);
if (status == EOK) {
addfn(qsa_capture_device[qsa_capture_devices].name);
qsa_capture_devices++;
}
} else {
......@@ -782,31 +784,6 @@ QSA_DetectDevices(int iscapture)
}
}
}
/* Return amount of available playback or capture devices */
if (!iscapture) {
return qsa_playback_devices;
} else {
return qsa_capture_devices;
}
}
static const char *
QSA_GetDeviceName(int index, int iscapture)
{
if (!iscapture) {
if (index >= qsa_playback_devices) {
return "No such playback device";
}
return qsa_playback_device[index].name;
} else {
if (index >= qsa_capture_devices) {
return "No such capture device";
}
return qsa_capture_device[index].name;
}
}
static void
......@@ -857,7 +834,6 @@ QSA_Init(SDL_AudioDriverImpl * impl)
/* DeviceLock and DeviceUnlock functions are used default, */
/* provided by SDL, which uses pthread_mutex for lock/unlock */
impl->DetectDevices = QSA_DetectDevices;
impl->GetDeviceName = QSA_GetDeviceName;
impl->OpenDevice = QSA_OpenDevice;
impl->ThreadInit = QSA_ThreadInit;
impl->WaitDevice = QSA_WaitDevice;
......
......@@ -33,89 +33,33 @@
#include "win_ce_semaphore.h"
#endif
/* !!! 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;
#define DETECT_DEV_IMPL(typ, capstyp) \
static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
const UINT devcount = wave##typ##GetNumDevs(); \
capstyp caps; \
UINT i; \
for (i = 0; i < devcount; i++) { \
if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
char *name = WIN_StringToUTF8(caps.szPname); \
if (name != NULL) { \
addfn(name); \
SDL_free(name); \
} \
} \
} \
}
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;
}
DETECT_DEV_IMPL(Out, WAVEOUTCAPS)
DETECT_DEV_IMPL(In, WAVEINCAPS)
static int
WINMM_DetectDevices(int iscapture)
{
return (iscapture) ? DetectWaveInDevices() : DetectWaveOutDevices();
}
static const char *
WINMM_GetDeviceName(int index, int iscapture)
static void
WINMM_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
{
if ((iscapture) && (index < inputDeviceCount)) {
return inputDevices[index];
} else if ((!iscapture) && (index < outputDeviceCount)) {
return outputDevices[index];
if (iscapture) {
DetectWaveInDevs(addfn);
} else {
DetectWaveOutDevs(addfn);
}
SDL_SetError("No such device");
return NULL;
}
static void CALLBACK
......@@ -448,7 +392,6 @@ WINMM_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->DetectDevices = WINMM_DetectDevices;
impl->GetDeviceName = WINMM_GetDeviceName;
impl->OpenDevice = WINMM_OpenDevice;
impl->PlayDevice = WINMM_PlayDevice;
impl->WaitDevice = WINMM_WaitDevice;
......
......@@ -24,35 +24,9 @@
#include "../SDL_audio_c.h"
#include "SDL_assert.h"
#define INITGUID 1
#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)
{
......@@ -61,59 +35,38 @@ utf16_to_utf8(const WCHAR *S)
(SDL_wcslen(S)+1)*sizeof(WCHAR));
}
static int
XAUDIO2_DetectDevices(int iscapture)
static void
XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
{
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;
return;
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
SDL_SetError("XAudio2: XAudio2Create() failed.");
return 0;
return;
} 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;
return;
}
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;
addfn(str);
SDL_free(str); /* addfn() made a copy of the string. */
}
}
}
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
......@@ -436,7 +389,6 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl)
/* Set the function pointers */
impl->DetectDevices = XAUDIO2_DetectDevices;
impl->GetDeviceName = XAUDIO2_GetDeviceName;
impl->OpenDevice = XAUDIO2_OpenDevice;
impl->PlayDevice = XAUDIO2_PlayDevice;
impl->WaitDevice = XAUDIO2_WaitDevice;
......
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