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