diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 519e86a22..af88bb0e8 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -161,8 +161,16 @@ get_audio_device(SDL_AudioDeviceID id) /* stubs for audio drivers that don't need a specific entry point... */ static void -SDL_AudioDetectDevices_Default(int iscapture, SDL_AddAudioDevice addfn) -{ /* no-op. */ +SDL_AudioDetectDevices_Default(void) +{ + /* you have to write your own implementation if these assertions fail. */ + SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice); + SDL_assert(current_audio.impl.OnlyHasDefaultInputDevice || !current_audio.impl.HasCaptureSupport); + + SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1)); + if (current_audio.impl.HasCaptureSupport) { + SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2)); + } } static void @@ -207,10 +215,16 @@ SDL_AudioDeinitialize_Default(void) { /* no-op. */ } +static void +SDL_AudioFreeDeviceHandle_Default(void *handle) +{ /* no-op. */ +} + + static int -SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture) +SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture) { - return -1; + return SDL_Unsupported(); } static SDL_INLINE SDL_bool @@ -267,6 +281,7 @@ finalize_audio_entry_points(void) FILL_STUB(CloseDevice); FILL_STUB(LockDevice); FILL_STUB(UnlockDevice); + FILL_STUB(FreeDeviceHandle); FILL_STUB(Deinitialize); #undef FILL_STUB } @@ -335,94 +350,64 @@ SDL_StreamDeinit(SDL_AudioStreamer * stream) /* device hotplug support... */ -/* this function expects its caller to hold current_audio.detection_lock */ static int -add_audio_device(const char *_name, char ***_devices, int *_devCount) +add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount) { - char *name = SDL_strdup(_name); int retval = -1; - - if (name != NULL) { - char **devices = *_devices; - int devCount = *_devCount; - void *ptr = SDL_realloc(devices, (devCount+1) * sizeof(char*)); - if (ptr == NULL) { - SDL_free(name); - } else { - retval = devCount; - devices = (char **) ptr; - devices[devCount++] = name; - *_devices = devices; - *_devCount = devCount; - } + const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1; + SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size); + if (item == NULL) { + return -1; } + SDL_assert(handle != NULL); + + item->handle = handle; + SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem)); + + SDL_LockMutex(current_audio.detectionLock); + item->next = *devices; + *devices = item; + retval = (*devCount)++; + SDL_UnlockMutex(current_audio.detectionLock); + return retval; } -static int -add_capture_device(const char *name) +static SDL_INLINE int +add_capture_device(const char *name, void *handle) { /* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/ - return add_audio_device(name, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); + return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); } -static int -add_output_device(const char *name) +static SDL_INLINE int +add_output_device(const char *name, void *handle) { - return add_audio_device(name, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); + return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); } static void -free_device_list(char ***devices, int *devCount) +free_device_list(SDL_AudioDeviceItem **devices, int *devCount) { - int i = *devCount; - if ((i > 0) && (*devices != NULL)) { - while (i--) { - SDL_free((*devices)[i]); + SDL_AudioDeviceItem *item, *next; + for (item = *devices; item != NULL; item = next) { + next = item->next; + if (item->handle != NULL) { + current_audio.impl.FreeDeviceHandle(item->handle); } + SDL_free(item); } - - SDL_free(*devices); - *devices = NULL; *devCount = 0; } -static void -perform_full_device_redetect(const int iscapture) -{ - SDL_LockMutex(current_audio.detection_lock); - - if (iscapture) { - if (!current_audio.impl.OnlyHasDefaultOutputDevice) { - free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); - current_audio.impl.DetectDevices(SDL_FALSE, add_output_device); - } - } else { - if ((current_audio.impl.HasCaptureSupport) && (!current_audio.impl.OnlyHasDefaultInputDevice)) { - free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); - current_audio.impl.DetectDevices(SDL_TRUE, add_capture_device); - } - } - - SDL_UnlockMutex(current_audio.detection_lock); -} /* The audio backends call this when a new device is plugged in. */ void -SDL_AudioDeviceConnected(const int iscapture, const char *name) +SDL_AddAudioDevice(const int iscapture, const char *name, void *handle) { - int device_index = -1; - - SDL_LockMutex(current_audio.detection_lock); - if (iscapture) { - device_index = add_capture_device(name); - } else { - device_index = add_output_device(name); - } - SDL_UnlockMutex(current_audio.detection_lock); - + const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle); if (device_index != -1) { /* Post the event, if desired */ if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) { @@ -435,39 +420,51 @@ SDL_AudioDeviceConnected(const int iscapture, const char *name) } } -/* The audio backends call this when a device is unplugged. */ -void -SDL_AudioDeviceDisconnected(const int iscapture, SDL_AudioDevice *device) +/* The audio backends call this when a currently-opened device is lost. */ +void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device) { - /* device==NULL means an unopened device was lost; do the redetect only. */ - if (device != NULL) { - SDL_assert(get_audio_device(device->id) == device); - SDL_assert(device->enabled); /* called more than once?! */ + SDL_assert(get_audio_device(device->id) == device); + SDL_assert(device->enabled); /* called more than once?! */ - /* Ends the audio callback and mark the device as STOPPED, but the - app still needs to close the device to free resources. */ - current_audio.impl.LockDevice(device); - device->enabled = 0; - current_audio.impl.UnlockDevice(device); + /* Ends the audio callback and mark the device as STOPPED, but the + app still needs to close the device to free resources. */ + current_audio.impl.LockDevice(device); + device->enabled = 0; + current_audio.impl.UnlockDevice(device); - /* Post the event, if desired */ - if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) { - SDL_Event event; - event.adevice.type = SDL_AUDIODEVICEREMOVED; - event.adevice.which = device->id; - event.adevice.iscapture = device->iscapture ? 1 : 0; - SDL_PushEvent(&event); + /* Post the event, if desired */ + if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) { + SDL_Event event; + event.adevice.type = SDL_AUDIODEVICEREMOVED; + event.adevice.which = device->id; + event.adevice.iscapture = device->iscapture ? 1 : 0; + SDL_PushEvent(&event); + } +} + +static void +mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag) +{ + SDL_AudioDeviceItem *item; + SDL_assert(handle != NULL); + for (item = devices; item != NULL; item = item->next) { + if (item->handle == handle) { + item->handle = NULL; + *removedFlag = SDL_TRUE; + return; } } +} - /* we don't really know which name (if any) was associated with this - device in the device list, so drop the entire list and rebuild it. - (we should probably change the API in 2.1 to make this more clear?) */ - if (iscapture) { - current_audio.need_capture_device_redetect = SDL_TRUE; - } else { - current_audio.need_output_device_redetect = SDL_TRUE; - } +/* The audio backends call this when a device is removed from the system. */ +void +SDL_RemoveAudioDevice(void *handle) +{ + SDL_LockMutex(current_audio.detectionLock); + mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved); + mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); + SDL_UnlockMutex(current_audio.detectionLock); + current_audio.impl.FreeDeviceHandle(handle); } @@ -966,33 +963,12 @@ SDL_AudioInit(const char *driver_name) return -1; /* No driver was available, so fail. */ } - current_audio.detection_lock = SDL_CreateMutex(); + current_audio.detectionLock = SDL_CreateMutex(); finalize_audio_entry_points(); /* Make sure we have a list of devices available at startup. */ - perform_full_device_redetect(SDL_TRUE); - perform_full_device_redetect(SDL_FALSE); - - /* Post an add event for each initial device, if desired */ - if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) { - SDL_Event event; - - SDL_zero(event); - event.adevice.type = SDL_AUDIODEVICEADDED; - - event.adevice.iscapture = 0; - for (i = 0; i < current_audio.outputDeviceCount; i++) { - event.adevice.which = i; - SDL_PushEvent(&event); - } - - event.adevice.iscapture = 1; - for (i = 0; i < current_audio.inputDeviceCount; i++) { - event.adevice.which = i; - SDL_PushEvent(&event); - } - } + current_audio.impl.DetectDevices(); return 0; } @@ -1006,6 +982,35 @@ SDL_GetCurrentAudioDriver() return current_audio.name; } +/* Clean out devices that we've removed but had to keep around for stability. */ +static void +clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag) +{ + SDL_AudioDeviceItem *item = *devices; + SDL_AudioDeviceItem *prev = NULL; + int total = 0; + + while (item) { + SDL_AudioDeviceItem *next = item->next; + if (item->handle != NULL) { + total++; + prev = item; + } else { + if (prev) { + prev->next = next; + } else { + *devices = next; + } + SDL_free(item); + } + item = next; + } + + *devCount = total; + *removedFlag = SDL_FALSE; +} + + int SDL_GetNumAudioDevices(int iscapture) { @@ -1015,31 +1020,18 @@ SDL_GetNumAudioDevices(int iscapture) return -1; } - if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { - return 0; + SDL_LockMutex(current_audio.detectionLock); + if (iscapture && current_audio.captureDevicesRemoved) { + clean_out_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount, ¤t_audio.captureDevicesRemoved); } - if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { - return 1; + if (!iscapture && current_audio.outputDevicesRemoved) { + clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved); + current_audio.outputDevicesRemoved = SDL_FALSE; } - if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { - return 1; - } - - if (current_audio.need_capture_device_redetect) { - current_audio.need_capture_device_redetect = SDL_FALSE; - perform_full_device_redetect(SDL_TRUE); - } - - if (current_audio.need_output_device_redetect) { - current_audio.need_output_device_redetect = SDL_FALSE; - perform_full_device_redetect(SDL_FALSE); - } - - SDL_LockMutex(current_audio.detection_lock); retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; - SDL_UnlockMutex(current_audio.detection_lock); + SDL_UnlockMutex(current_audio.detectionLock); return retval; } @@ -1060,41 +1052,28 @@ SDL_GetAudioDeviceName(int index, int iscapture) return NULL; } - if (index < 0) { - goto no_such_device; - } + if (index >= 0) { + SDL_AudioDeviceItem *item; + int i; - if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { - if (index > 0) { - goto no_such_device; + SDL_LockMutex(current_audio.detectionLock); + item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; + i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; + if (index < i) { + for (i--; i > index; i--, item = item->next) { + SDL_assert(item != NULL); + } + SDL_assert(item != NULL); + retval = item->name; } - return DEFAULT_INPUT_DEVNAME; + SDL_UnlockMutex(current_audio.detectionLock); } - if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { - if (index > 0) { - goto no_such_device; - } - return DEFAULT_OUTPUT_DEVNAME; + if (retval == NULL) { + SDL_SetError("No such device"); } - SDL_LockMutex(current_audio.detection_lock); - if (iscapture && (index < current_audio.inputDeviceCount)) { - retval = current_audio.inputDevices[index]; - } else if (!iscapture && (index < current_audio.outputDeviceCount)) { - retval = current_audio.outputDevices[index]; - } - SDL_UnlockMutex(current_audio.detection_lock); - - /* !!! FIXME: a device could be removed after being returned here, freeing retval's pointer. */ - - if (retval != NULL) { - return retval; - } - -no_such_device: - SDL_SetError("No such device"); - return NULL; + return retval; } @@ -1195,6 +1174,7 @@ open_audio_device(const char *devname, int iscapture, SDL_AudioSpec _obtained; SDL_AudioDevice *device; SDL_bool build_cvt; + void *handle = NULL; int i = 0; if (!SDL_WasInit(SDL_INIT_AUDIO)) { @@ -1254,9 +1234,7 @@ open_audio_device(const char *devname, int iscapture, return 0; } } - } - - if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { + } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { SDL_SetError("No such device"); return 0; @@ -1269,6 +1247,30 @@ open_audio_device(const char *devname, int iscapture, return 0; } } + } else if (devname != NULL) { + /* if the app specifies an exact string, we can pass the backend + an actual device handle thingey, which saves them the effort of + figuring out what device this was (such as, reenumerating + everything again to find the matching human-readable name). + It might still need to open a device based on the string for, + say, a network audio server, but this optimizes some cases. */ + SDL_AudioDeviceItem *item; + SDL_LockMutex(current_audio.detectionLock); + for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) { + if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) { + handle = item->handle; + break; + } + } + SDL_UnlockMutex(current_audio.detectionLock); + } + + if (!current_audio.impl.AllowsArbitraryDeviceNames) { + /* has to be in our device list, or the default device. */ + if ((handle == NULL) && (devname != NULL)) { + SDL_SetError("No such device."); + return 0; + } } device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice)); @@ -1293,7 +1295,7 @@ open_audio_device(const char *devname, int iscapture, } } - if (current_audio.impl.OpenDevice(device, devname, iscapture) < 0) { + if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) { close_audio_device(device); return 0; } @@ -1555,15 +1557,13 @@ SDL_AudioQuit(void) } } + free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); + free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); + /* Free the driver data */ current_audio.impl.Deinitialize(); - free_device_list(¤t_audio.outputDevices, - ¤t_audio.outputDeviceCount); - free_device_list(¤t_audio.inputDevices, - ¤t_audio.inputDeviceCount); - - SDL_DestroyMutex(current_audio.detection_lock); + SDL_DestroyMutex(current_audio.detectionLock); SDL_zero(current_audio); SDL_zero(open_devices); diff --git a/src/audio/SDL_audiodev.c b/src/audio/SDL_audiodev.c index e9af62119..4a50c097d 100644 --- a/src/audio/SDL_audiodev.c +++ b/src/audio/SDL_audiodev.c @@ -46,18 +46,21 @@ #define _PATH_DEV_AUDIO "/dev/audio" #endif -static SDL_INLINE void -test_device(const char *fname, int flags, int (*test) (int fd), - SDL_AddAudioDevice addfn) +static void +test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd)) { struct stat sb; if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) { const int audio_fd = open(fname, flags, 0); if (audio_fd >= 0) { - if (test(audio_fd)) { - addfn(fname); - } + const int okay = test(audio_fd); close(audio_fd); + if (okay) { + static size_t dummyhandle = 0; + dummyhandle++; + SDL_assert(dummyhandle != 0); + SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle); + } } } } @@ -68,11 +71,10 @@ test_stub(int fd) return 1; } -void -SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd), - SDL_AddAudioDevice addfn) +static void +SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int)) { - const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); + const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; const char *audiodev; char audiopath[1024]; @@ -97,17 +99,25 @@ SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd), } } } - test_device(audiodev, flags, test, addfn); + test_device(iscapture, audiodev, flags, test); 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, addfn); + test_device(iscapture, audiopath, flags, test); } } } +void +SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)) +{ + SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test); + SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test); +} + #endif /* Audio driver selection */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/SDL_audiodev_c.h b/src/audio/SDL_audiodev_c.h index 1ad0dc101..3544bfab8 100644 --- a/src/audio/SDL_audiodev_c.h +++ b/src/audio/SDL_audiodev_c.h @@ -33,7 +33,6 @@ #define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK) #endif -void SDL_EnumUnixAudioDevices(int iscapture, int classic, - int (*test) (int fd), SDL_AddAudioDevice addfn); +extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 55cb2ecce..fd8e68708 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -30,16 +30,20 @@ typedef struct SDL_AudioDevice SDL_AudioDevice; #define _THIS SDL_AudioDevice *_this -/* Used by audio targets during DetectDevices() */ -typedef int (*SDL_AddAudioDevice)(const char *name); +/* Audio targets should call this as devices are added to the system (such as + a USB headset being plugged in), and should also be called for + for every device found during DetectDevices(). */ +extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle); -/* Audio targets should call this as devices are hotplugged. Don't call - during DetectDevices(), this is for hotplugging a device later. */ -extern void SDL_AudioDeviceConnected(const int iscapture, const char *name); +/* Audio targets should call this as devices are removed, so SDL can update + its list of available devices. */ +extern void SDL_RemoveAudioDevice(void *handle); -/* Audio targets should call this as devices are unplugged. - (device) can be NULL if an unopened device is lost. */ -extern void SDL_AudioDeviceDisconnected(const int iscapture, SDL_AudioDevice *device); +/* Audio targets should call this if an opened audio device is lost while + being used. This can happen due to i/o errors, or a device being unplugged, + etc. If the device is totally gone, please also call SDL_RemoveAudioDevice() + as appropriate so SDL's list of devices is accurate. */ +extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device); /* This is the size of a packet when using SDL_QueueAudio(). We allocate @@ -64,8 +68,8 @@ typedef struct SDL_AudioBufferQueue typedef struct SDL_AudioDriverImpl { - void (*DetectDevices) (int iscapture, SDL_AddAudioDevice addfn); - int (*OpenDevice) (_THIS, const char *devname, int iscapture); + void (*DetectDevices) (void); + int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture); void (*ThreadInit) (_THIS); /* Called by audio thread at start */ void (*WaitDevice) (_THIS); void (*PlayDevice) (_THIS); @@ -75,6 +79,7 @@ typedef struct SDL_AudioDriverImpl void (*CloseDevice) (_THIS); void (*LockDevice) (_THIS); void (*UnlockDevice) (_THIS); + void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */ void (*Deinitialize) (void); /* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */ @@ -86,9 +91,18 @@ typedef struct SDL_AudioDriverImpl int HasCaptureSupport; int OnlyHasDefaultOutputDevice; int OnlyHasDefaultInputDevice; + int AllowsArbitraryDeviceNames; } SDL_AudioDriverImpl; +typedef struct SDL_AudioDeviceItem +{ + void *handle; + struct SDL_AudioDeviceItem *next; + char name[]; +} SDL_AudioDeviceItem; + + typedef struct SDL_AudioDriver { /* * * */ @@ -102,16 +116,13 @@ typedef struct SDL_AudioDriver SDL_AudioDriverImpl impl; /* A mutex for device detection */ - SDL_mutex *detection_lock; - - SDL_bool need_capture_device_redetect; - SDL_bool need_output_device_redetect; - - char **outputDevices; + SDL_mutex *detectionLock; + SDL_bool captureDevicesRemoved; + SDL_bool outputDevicesRemoved; int outputDeviceCount; - - char **inputDevices; int inputDeviceCount; + SDL_AudioDeviceItem *outputDevices; + SDL_AudioDeviceItem *inputDevices; } SDL_AudioDriver; diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index b600474d2..216383cae 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -320,7 +320,7 @@ ALSA_PlayDevice(_THIS) /* Hmm, not much we can do - abort */ fprintf(stderr, "ALSA write failed (unrecoverable): %s\n", ALSA_snd_strerror(status)); - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); return; } continue; @@ -465,7 +465,7 @@ ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params, int override) } static int -ALSA_OpenDevice(_THIS, const char *devname, int iscapture) +ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { int status = 0; snd_pcm_t *pcm_handle = NULL; diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c index fe66763b8..00537baa3 100644 --- a/src/audio/android/SDL_androidaudio.c +++ b/src/audio/android/SDL_androidaudio.c @@ -35,7 +35,7 @@ static SDL_AudioDevice* audioDevice = NULL; static int -AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture) +AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_AudioFormat test_format; diff --git a/src/audio/arts/SDL_artsaudio.c b/src/audio/arts/SDL_artsaudio.c index 7a8cf6605..628d6e6ec 100644 --- a/src/audio/arts/SDL_artsaudio.c +++ b/src/audio/arts/SDL_artsaudio.c @@ -151,7 +151,7 @@ ARTS_WaitDevice(_THIS) /* Check every 10 loops */ if (this->hidden->parent && (((++cnt) % 10) == 0)) { if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } } } @@ -179,7 +179,7 @@ ARTS_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if (written < 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); @@ -229,7 +229,7 @@ ARTS_Suspend(void) } static int -ARTS_OpenDevice(_THIS, const char *devname, int iscapture) +ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { int rc = 0; int bits = 0, frag_spec = 0; diff --git a/src/audio/bsd/SDL_bsdaudio.c b/src/audio/bsd/SDL_bsdaudio.c index 2488bef6c..d1159e995 100644 --- a/src/audio/bsd/SDL_bsdaudio.c +++ b/src/audio/bsd/SDL_bsdaudio.c @@ -51,9 +51,9 @@ static void -BSDAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +BSDAUDIO_DetectDevices(void) { - SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn); + SDL_EnumUnixAudioDevices(0, NULL); } @@ -150,7 +150,7 @@ BSDAUDIO_WaitDevice(_THIS) the user know what happened. */ fprintf(stderr, "SDL: %s\n", message); - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); /* Don't try to close - may hang */ this->hidden->audio_fd = -1; #ifdef DEBUG_AUDIO @@ -195,7 +195,7 @@ BSDAUDIO_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if (written < 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); @@ -224,7 +224,7 @@ BSDAUDIO_CloseDevice(_THIS) } static int -BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) +BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); SDL_AudioFormat format = 0; @@ -348,6 +348,8 @@ BSDAUDIO_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf; impl->CloseDevice = BSDAUDIO_CloseDevice; + impl->AllowsArbitraryDeviceNames = 1; + return 1; /* this audio target is available. */ } diff --git a/src/audio/coreaudio/SDL_coreaudio.c b/src/audio/coreaudio/SDL_coreaudio.c index 5493d3c59..afd2565dd 100644 --- a/src/audio/coreaudio/SDL_coreaudio.c +++ b/src/audio/coreaudio/SDL_coreaudio.c @@ -80,28 +80,8 @@ add_to_internal_dev_list(const int iscapture, AudioDeviceID devId) static void addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data) { - SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data; if (add_to_internal_dev_list(iscapture, devId)) { - addfn(name); - } -} - -typedef struct -{ - const char *findname; - AudioDeviceID devId; - int found; -} FindDevIdData; - -static void -findDevId(const char *name, const int iscapture, AudioDeviceID devId, void *_data) -{ - FindDevIdData *data = (FindDevIdData *) _data; - if (!data->found) { - if (SDL_strcmp(name, data->findname) == 0) { - data->found = 1; - data->devId = devId; - } + SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); } } @@ -226,10 +206,10 @@ free_audio_device_list(AudioDeviceList **list) } static void -COREAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +COREAUDIO_DetectDevices(void) { - free_audio_device_list(iscapture ? &capture_devs : &output_devs); - build_device_list(iscapture, addToDevList, addfn); + build_device_list(SDL_TRUE, addToDevList, NULL); + build_device_list(SDL_FALSE, addToDevList, NULL); } static void @@ -245,13 +225,12 @@ build_device_change_list(const char *name, const int iscapture, AudioDeviceID de } add_to_internal_dev_list(iscapture, devId); /* new device, add it. */ - SDL_AudioDeviceConnected(iscapture, name); + SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); } -static SDL_bool +static void reprocess_device_list(const int iscapture, AudioDeviceList **list) { - SDL_bool was_disconnect = SDL_FALSE; AudioDeviceList *item; AudioDeviceList *prev = NULL; for (item = *list; item != NULL; item = item->next) { @@ -267,7 +246,7 @@ reprocess_device_list(const int iscapture, AudioDeviceList **list) if (item->alive) { prev = item; } else { - was_disconnect = SDL_TRUE; + SDL_RemoveAudioDevice((void *) ((size_t) item->devid)); if (prev) { prev->next = item->next; } else { @@ -277,88 +256,16 @@ reprocess_device_list(const int iscapture, AudioDeviceList **list) } item = next; } - - return was_disconnect; } - /* this is called when the system's list of available audio devices changes. */ static OSStatus device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) { - if (reprocess_device_list(SDL_TRUE, &capture_devs)) { - SDL_AudioDeviceDisconnected(SDL_TRUE, NULL); - } - - if (reprocess_device_list(SDL_FALSE, &output_devs)) { - SDL_AudioDeviceDisconnected(SDL_FALSE, NULL); - } - + reprocess_device_list(SDL_TRUE, &capture_devs); + reprocess_device_list(SDL_FALSE, &output_devs); return 0; } - -static int -find_device_by_name(_THIS, const char *devname, int iscapture) -{ - AudioDeviceID devid = 0; - OSStatus result = noErr; - UInt32 size = 0; - UInt32 alive = 0; - pid_t pid = 0; - - AudioObjectPropertyAddress addr = { - 0, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - - if (devname == NULL) { - size = sizeof (AudioDeviceID); - addr.mSelector = - ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : - kAudioHardwarePropertyDefaultOutputDevice); - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, - 0, NULL, &size, &devid); - CHECK_RESULT("AudioHardwareGetProperty (default device)"); - } else { - 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; - } - - addr.mSelector = kAudioDevicePropertyDeviceIsAlive; - addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : - kAudioDevicePropertyScopeOutput; - - size = sizeof (alive); - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); - CHECK_RESULT - ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); - - if (!alive) { - SDL_SetError("CoreAudio: requested device exists, but isn't alive."); - return 0; - } - - addr.mSelector = kAudioDevicePropertyHogMode; - size = sizeof (pid); - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid); - - /* some devices don't support this property, so errors are fine here. */ - if ((result == noErr) && (pid != -1)) { - SDL_SetError("CoreAudio: requested device is being hogged."); - return 0; - } - - this->hidden->deviceID = devid; - return 1; -} #endif /* The CoreAudio callback */ @@ -464,7 +371,7 @@ device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectProperty } if (dead) { - SDL_AudioDeviceDisconnected(this->iscapture, this); + SDL_OpenedAudioDeviceDisconnected(this); } return 0; @@ -514,8 +421,63 @@ COREAUDIO_CloseDevice(_THIS) } } +#if MACOSX_COREAUDIO static int -prepare_audiounit(_THIS, const char *devname, int iscapture, +prepare_device(_THIS, void *handle, int iscapture) +{ + AudioDeviceID devid = (AudioDeviceID) ((size_t) handle); + OSStatus result = noErr; + UInt32 size = 0; + UInt32 alive = 0; + pid_t pid = 0; + + AudioObjectPropertyAddress addr = { + 0, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + + if (handle == NULL) { + size = sizeof (AudioDeviceID); + addr.mSelector = + ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : + kAudioHardwarePropertyDefaultOutputDevice); + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, + 0, NULL, &size, &devid); + CHECK_RESULT("AudioHardwareGetProperty (default device)"); + } + + addr.mSelector = kAudioDevicePropertyDeviceIsAlive; + addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : + kAudioDevicePropertyScopeOutput; + + size = sizeof (alive); + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); + CHECK_RESULT + ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); + + if (!alive) { + SDL_SetError("CoreAudio: requested device exists, but isn't alive."); + return 0; + } + + addr.mSelector = kAudioDevicePropertyHogMode; + size = sizeof (pid); + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid); + + /* some devices don't support this property, so errors are fine here. */ + if ((result == noErr) && (pid != -1)) { + SDL_SetError("CoreAudio: requested device is being hogged."); + return 0; + } + + this->hidden->deviceID = devid; + return 1; +} +#endif + +static int +prepare_audiounit(_THIS, void *handle, int iscapture, const AudioStreamBasicDescription * strdesc) { OSStatus result = noErr; @@ -534,8 +496,7 @@ prepare_audiounit(_THIS, const char *devname, int iscapture, kAudioUnitScope_Input); #if MACOSX_COREAUDIO - if (!find_device_by_name(this, devname, iscapture)) { - SDL_SetError("Couldn't find requested CoreAudio device"); + if (!prepare_device(this, handle, iscapture)) { return 0; } #endif @@ -623,7 +584,7 @@ prepare_audiounit(_THIS, const char *devname, int iscapture, static int -COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) +COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { AudioStreamBasicDescription strdesc; SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); @@ -682,7 +643,7 @@ COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket; - if (!prepare_audiounit(this, devname, iscapture, &strdesc)) { + if (!prepare_audiounit(this, handle, iscapture, &strdesc)) { COREAUDIO_CloseDevice(this); return -1; /* prepare_audiounit() will call SDL_SetError()... */ } diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c index 067683ccc..99e34521f 100644 --- a/src/audio/directsound/SDL_directsound.c +++ b/src/audio/directsound/SDL_directsound.c @@ -144,15 +144,22 @@ SetDSerror(const char *function, int code) return SDL_SetError("%s", errbuf); } +static void +DSOUND_FreeDeviceHandle(void *handle) +{ + SDL_free(handle); +} static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) { - SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data; + const int iscapture = (int) ((size_t) data); if (guid != NULL) { /* skip default device */ char *str = WIN_StringToUTF8(desc); if (str != NULL) { - addfn(str); + LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID)); + SDL_memcpy(cpyguid, guid, sizeof (GUID)); + SDL_AddAudioDevice(iscapture, str, cpyguid); SDL_free(str); /* addfn() makes a copy of this string. */ } } @@ -160,13 +167,10 @@ FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) } static void -DSOUND_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +DSOUND_DetectDevices(void) { - if (iscapture) { - pDirectSoundCaptureEnumerateW(FindAllDevs, addfn); - } else { - pDirectSoundEnumerateW(FindAllDevs, addfn); - } + pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1)); + pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0)); } @@ -419,53 +423,14 @@ CreateSecondary(_THIS, HWND focus) 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 = WIN_StringToUTF8(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 -DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) +DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { HRESULT result; SDL_bool valid_format = SDL_FALSE; SDL_bool tried_format = SDL_FALSE; SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - FindDevGUIDData devguid; - LPGUID guid = NULL; - - if (devname != NULL) { - devguid.found = 0; - devguid.devname = devname; - if (iscapture) - pDirectSoundCaptureEnumerateW(FindDevGUID, &devguid); - else - pDirectSoundEnumerateW(FindDevGUID, &devguid); - - if (!devguid.found) { - return SDL_SetError("DirectSound: Requested device not found"); - } - guid = &devguid.guid; - } + LPGUID guid = (LPGUID) handle; /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) @@ -536,6 +501,8 @@ DSOUND_Init(SDL_AudioDriverImpl * impl) impl->WaitDone = DSOUND_WaitDone; impl->GetDeviceBuf = DSOUND_GetDeviceBuf; impl->CloseDevice = DSOUND_CloseDevice; + impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle; + impl->Deinitialize = DSOUND_Deinitialize; return 1; /* this audio target is available. */ diff --git a/src/audio/disk/SDL_diskaudio.c b/src/audio/disk/SDL_diskaudio.c index 4b9214819..1577b6f23 100644 --- a/src/audio/disk/SDL_diskaudio.c +++ b/src/audio/disk/SDL_diskaudio.c @@ -71,7 +71,7 @@ DISKAUD_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if (written != this->hidden->mixlen) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); @@ -100,7 +100,7 @@ DISKAUD_CloseDevice(_THIS) } static int -DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture) +DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const char *envr = SDL_getenv(DISKENVR_WRITEDELAY); const char *fname = DISKAUD_GetOutputFilename(devname); @@ -151,6 +151,8 @@ DISKAUD_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = DISKAUD_GetDeviceBuf; impl->CloseDevice = DISKAUD_CloseDevice; + impl->AllowsArbitraryDeviceNames = 1; + return 1; /* this audio target is available. */ } diff --git a/src/audio/dsp/SDL_dspaudio.c b/src/audio/dsp/SDL_dspaudio.c index 5807a571c..0d34e9512 100644 --- a/src/audio/dsp/SDL_dspaudio.c +++ b/src/audio/dsp/SDL_dspaudio.c @@ -51,9 +51,9 @@ static void -DSP_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +DSP_DetectDevices(void) { - SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn); + SDL_EnumUnixAudioDevices(0, NULL); } @@ -74,7 +74,7 @@ DSP_CloseDevice(_THIS) static int -DSP_OpenDevice(_THIS, const char *devname, int iscapture) +DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); int format; @@ -270,7 +270,7 @@ DSP_PlayDevice(_THIS) const int mixlen = this->hidden->mixlen; if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) { perror("Audio write"); - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen); @@ -293,6 +293,8 @@ DSP_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = DSP_GetDeviceBuf; impl->CloseDevice = DSP_CloseDevice; + impl->AllowsArbitraryDeviceNames = 1; + return 1; /* this audio target is available. */ } diff --git a/src/audio/dummy/SDL_dummyaudio.c b/src/audio/dummy/SDL_dummyaudio.c index 671e222cf..965b4ce56 100644 --- a/src/audio/dummy/SDL_dummyaudio.c +++ b/src/audio/dummy/SDL_dummyaudio.c @@ -27,7 +27,7 @@ #include "SDL_dummyaudio.h" static int -DUMMYAUD_OpenDevice(_THIS, const char *devname, int iscapture) +DUMMYAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { return 0; /* always succeeds. */ } diff --git a/src/audio/emscripten/SDL_emscriptenaudio.c b/src/audio/emscripten/SDL_emscriptenaudio.c index f1ae929f3..2147baedb 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/src/audio/emscripten/SDL_emscriptenaudio.c @@ -151,7 +151,7 @@ Emscripten_CloseDevice(_THIS) } static int -Emscripten_OpenDevice(_THIS, const char *devname, int iscapture) +Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_bool valid_format = SDL_FALSE; SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); diff --git a/src/audio/esd/SDL_esdaudio.c b/src/audio/esd/SDL_esdaudio.c index 69c672a70..7f18337d9 100644 --- a/src/audio/esd/SDL_esdaudio.c +++ b/src/audio/esd/SDL_esdaudio.c @@ -129,7 +129,7 @@ ESD_WaitDevice(_THIS) /* Check every 10 loops */ if (this->hidden->parent && (((++cnt) % 10) == 0)) { if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } } } @@ -161,7 +161,7 @@ ESD_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if (written < 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } } @@ -215,7 +215,7 @@ get_progname(void) static int -ESD_OpenDevice(_THIS, const char *devname, int iscapture) +ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { esd_format_t format = (ESD_STREAM | ESD_PLAY); SDL_AudioFormat test_format = 0; diff --git a/src/audio/fusionsound/SDL_fsaudio.c b/src/audio/fusionsound/SDL_fsaudio.c index 643002dc6..dae4f4afa 100644 --- a/src/audio/fusionsound/SDL_fsaudio.c +++ b/src/audio/fusionsound/SDL_fsaudio.c @@ -143,7 +143,7 @@ SDL_FS_PlayDevice(_THIS) this->hidden->mixsamples); /* If we couldn't write, assume fatal error for now */ if (ret) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); @@ -186,7 +186,7 @@ SDL_FS_CloseDevice(_THIS) static int -SDL_FS_OpenDevice(_THIS, const char *devname, int iscapture) +SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { int bytes; SDL_AudioFormat test_format = 0, format = 0; diff --git a/src/audio/haiku/SDL_haikuaudio.cc b/src/audio/haiku/SDL_haikuaudio.cc index dddb77922..648987a14 100644 --- a/src/audio/haiku/SDL_haikuaudio.cc +++ b/src/audio/haiku/SDL_haikuaudio.cc @@ -111,7 +111,7 @@ UnmaskSignals(sigset_t * omask) static int -HAIKUAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) +HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { int valid_datatype = 0; media_raw_audio_format format; diff --git a/src/audio/nacl/SDL_naclaudio.c b/src/audio/nacl/SDL_naclaudio.c index 741cb1392..643666d6a 100644 --- a/src/audio/nacl/SDL_naclaudio.c +++ b/src/audio/nacl/SDL_naclaudio.c @@ -43,7 +43,7 @@ #define SAMPLE_FRAME_COUNT 4096 /* Audio driver functions */ -static int NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture); +static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture); static void NACLAUD_CloseDevice(_THIS); static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data); @@ -85,7 +85,7 @@ static void NACLAUD_CloseDevice(SDL_AudioDevice *device) { } static int -NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture) { +NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { PP_Instance instance = PSGetInstanceId(); const PPB_Audio *ppb_audio = PSInterfaceAudio(); const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig(); @@ -130,9 +130,7 @@ NACLAUD_Init(SDL_AudioDriverImpl * impl) /* Set the function pointers */ impl->OpenDevice = NACLAUD_OpenDevice; impl->CloseDevice = NACLAUD_CloseDevice; - impl->HasCaptureSupport = 0; impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultInputDevice = 1; impl->ProvidesOwnCallbackThread = 1; /* * impl->WaitDevice = NACLAUD_WaitDevice; diff --git a/src/audio/nas/SDL_nasaudio.c b/src/audio/nas/SDL_nasaudio.c index a41a480f2..fe5bd8eda 100644 --- a/src/audio/nas/SDL_nasaudio.c +++ b/src/audio/nas/SDL_nasaudio.c @@ -276,7 +276,7 @@ find_device(_THIS, int nch) } static int -NAS_OpenDevice(_THIS, const char *devname, int iscapture) +NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { AuElement elms[3]; int buffer_size; diff --git a/src/audio/paudio/SDL_paudio.c b/src/audio/paudio/SDL_paudio.c index d3c2d82b1..5f7d26c92 100644 --- a/src/audio/paudio/SDL_paudio.c +++ b/src/audio/paudio/SDL_paudio.c @@ -176,7 +176,7 @@ PAUDIO_WaitDevice(_THIS) * the user know what happened. */ fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); /* Don't try to close - may hang */ this->hidden->audio_fd = -1; #ifdef DEBUG_AUDIO @@ -212,7 +212,7 @@ PAUDIO_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if (written < 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); @@ -241,7 +241,7 @@ PAUDIO_CloseDevice(_THIS) } static int -PAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) +PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const char *workaround = SDL_getenv("SDL_DSP_NOSELECT"); char audiodev[1024]; diff --git a/src/audio/psp/SDL_pspaudio.c b/src/audio/psp/SDL_pspaudio.c index 360391164..59cbeb41c 100644 --- a/src/audio/psp/SDL_pspaudio.c +++ b/src/audio/psp/SDL_pspaudio.c @@ -43,7 +43,7 @@ #define PSPAUD_DRIVER_NAME "psp" static int -PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture) +PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { int format, mixlen, i; this->hidden = (struct SDL_PrivateAudioData *) diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index e108280b9..b5ac00eb1 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -302,7 +302,7 @@ PULSEAUDIO_WaitDevice(_THIS) if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); return; } if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) { @@ -318,7 +318,7 @@ PULSEAUDIO_PlayDevice(_THIS) struct SDL_PrivateAudioData *h = this->hidden; if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } } @@ -378,7 +378,7 @@ PULSEAUDIO_CloseDevice(_THIS) } static int -PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) +PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { struct SDL_PrivateAudioData *h = NULL; Uint16 test_format = 0; diff --git a/src/audio/qsa/SDL_qsa_audio.c b/src/audio/qsa/SDL_qsa_audio.c index 4121204ab..dcb7d38da 100644 --- a/src/audio/qsa/SDL_qsa_audio.c +++ b/src/audio/qsa/SDL_qsa_audio.c @@ -19,6 +19,15 @@ 3. This notice may not be removed or altered from any source distribution. */ +/* + * !!! FIXME: streamline this a little by removing all the + * !!! FIXME: if (capture) {} else {} sections that are identical + * !!! FIXME: except for one flag. + */ + +/* !!! FIXME: can this target support hotplugging? */ +/* !!! FIXME: ...does SDL2 even support QNX? */ + #include "../../SDL_internal.h" #if SDL_AUDIO_DRIVER_QSA @@ -300,7 +309,7 @@ QSA_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if (towrite != 0) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } } @@ -337,8 +346,9 @@ QSA_CloseDevice(_THIS) } static int -QSA_OpenDevice(_THIS, const char *devname, int iscapture) +QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { + const QSA_Device *device = (const QSA_Device *) handle; int status = 0; int format = 0; SDL_AudioFormat test_format = 0; @@ -363,80 +373,19 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture) /* Initialize channel direction: capture or playback */ this->hidden->iscapture = iscapture; - /* Find deviceid and cardid by device name for playback */ - if ((!this->hidden->iscapture) && (devname != NULL)) { - uint32_t device; - int32_t status; - - /* Search in the playback devices */ - device = 0; - do { - status = SDL_strcmp(qsa_playback_device[device].name, devname); - if (status == 0) { - /* Found requested device */ - this->hidden->deviceno = qsa_playback_device[device].deviceno; - this->hidden->cardno = qsa_playback_device[device].cardno; - break; - } - device++; - if (device >= qsa_playback_devices) { - QSA_CloseDevice(this); - return SDL_SetError("No such playback device"); - } - } while (1); - } - - /* Find deviceid and cardid by device name for capture */ - if ((this->hidden->iscapture) && (devname != NULL)) { - /* Search in the capture devices */ - uint32_t device; - int32_t status; - - /* Searching in the playback devices */ - device = 0; - do { - status = SDL_strcmp(qsa_capture_device[device].name, devname); - if (status == 0) { - /* Found requested device */ - this->hidden->deviceno = qsa_capture_device[device].deviceno; - this->hidden->cardno = qsa_capture_device[device].cardno; - break; - } - device++; - if (device >= qsa_capture_devices) { - QSA_CloseDevice(this); - return SDL_SetError("No such capture device"); - } - } while (1); - } - - /* Check if SDL requested default audio device */ - if (devname == NULL) { - /* Open system default audio device */ - if (!this->hidden->iscapture) { - status = snd_pcm_open_preferred(&this->hidden->audio_handle, - &this->hidden->cardno, - &this->hidden->deviceno, - SND_PCM_OPEN_PLAYBACK); - } else { - status = snd_pcm_open_preferred(&this->hidden->audio_handle, - &this->hidden->cardno, - &this->hidden->deviceno, - SND_PCM_OPEN_CAPTURE); - } - } else { + if (device != NULL) { /* Open requested audio device */ - if (!this->hidden->iscapture) { - status = - snd_pcm_open(&this->hidden->audio_handle, - this->hidden->cardno, this->hidden->deviceno, - SND_PCM_OPEN_PLAYBACK); - } else { - status = - snd_pcm_open(&this->hidden->audio_handle, - this->hidden->cardno, this->hidden->deviceno, - SND_PCM_OPEN_CAPTURE); - } + this->hidden->deviceno = device->deviceno; + this->hidden->cardno = device->cardno; + status = snd_pcm_open(&this->hidden->audio_handle, + device->cardno, device->deviceno, + iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE); + } else { + /* Open system default audio device */ + status = snd_pcm_open_preferred(&this->hidden->audio_handle, + &this->hidden->cardno, + &this->hidden->deviceno, + iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE); } /* Check if requested device is opened */ @@ -638,7 +587,7 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture) } static void -QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +QSA_DetectDevices(void) { uint32_t it; uint32_t cards; @@ -656,8 +605,9 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) return; } + /* !!! FIXME: code duplication */ /* Find requested devices by type */ - if (!iscapture) { + { /* output devices */ /* Playback devices enumeration requested */ for (it = 0; it < cards; it++) { devices = 0; @@ -688,7 +638,7 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) devices; status = snd_pcm_close(handle); if (status == EOK) { - addfn(qsa_playback_device[qsa_playback_devices].name); + SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]); qsa_playback_devices++; } } else { @@ -713,7 +663,9 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) break; } } - } else { + } + + { /* capture devices */ /* Capture devices enumeration requested */ for (it = 0; it < cards; it++) { devices = 0; @@ -744,7 +696,7 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) devices; status = snd_pcm_close(handle); if (status == EOK) { - addfn(qsa_capture_device[qsa_capture_devices].name); + SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]); qsa_capture_devices++; } } else { diff --git a/src/audio/sndio/SDL_sndioaudio.c b/src/audio/sndio/SDL_sndioaudio.c index e4a85a73b..f8757d127 100644 --- a/src/audio/sndio/SDL_sndioaudio.c +++ b/src/audio/sndio/SDL_sndioaudio.c @@ -158,7 +158,7 @@ SNDIO_PlayDevice(_THIS) /* If we couldn't write, assume fatal error for now */ if ( written == 0 ) { - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); @@ -193,7 +193,7 @@ SNDIO_CloseDevice(_THIS) } static int -SNDIO_OpenDevice(_THIS, const char *devname, int iscapture) +SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); struct sio_par par; diff --git a/src/audio/sun/SDL_sunaudio.c b/src/audio/sun/SDL_sunaudio.c index 569f9ba1d..ff35b6b1c 100644 --- a/src/audio/sun/SDL_sunaudio.c +++ b/src/audio/sun/SDL_sunaudio.c @@ -56,9 +56,9 @@ static Uint8 snd2au(int sample); /* Audio driver bootstrap functions */ static void -SUNAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +SUNAUDIO_DetectDevices(void) { - SDL_EnumUnixAudioDevices(iscapture, 1, (int (*)(int fd)) NULL, addfn); + SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL); } #ifdef DEBUG_AUDIO @@ -158,7 +158,7 @@ SUNAUDIO_PlayDevice(_THIS) if (write(this->hidden->audio_fd, this->hidden->ulaw_buf, this->hidden->fragsize) < 0) { /* Assume fatal error, for now */ - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } this->hidden->written += this->hidden->fragsize; } else { @@ -168,7 +168,7 @@ SUNAUDIO_PlayDevice(_THIS) if (write(this->hidden->audio_fd, this->hidden->mixbuf, this->spec.size) < 0) { /* Assume fatal error, for now */ - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } this->hidden->written += this->hidden->fragsize; } @@ -198,7 +198,7 @@ SUNAUDIO_CloseDevice(_THIS) } static int -SUNAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) +SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); SDL_AudioFormat format = 0; @@ -414,6 +414,8 @@ SUNAUDIO_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf; impl->CloseDevice = SUNAUDIO_CloseDevice; + impl->AllowsArbitraryDeviceNames = 1; + return 1; /* this audio target is available. */ } diff --git a/src/audio/winmm/SDL_winmm.c b/src/audio/winmm/SDL_winmm.c index 88a8154ec..bd795cf34 100644 --- a/src/audio/winmm/SDL_winmm.c +++ b/src/audio/winmm/SDL_winmm.c @@ -36,8 +36,10 @@ #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #endif -#define DETECT_DEV_IMPL(typ, capstyp) \ -static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \ +#define DETECT_DEV_IMPL(iscap, typ, capstyp) \ +static void DetectWave##typ##Devs(void) { \ + const UINT iscapture = iscap ? 1 : 0; \ + UINT devcount = wave##typ##GetNumDevs(); \ const UINT devcount = wave##typ##GetNumDevs(); \ capstyp caps; \ UINT i; \ @@ -45,24 +47,21 @@ static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \ if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ char *name = WIN_StringToUTF8(caps.szPname); \ if (name != NULL) { \ - addfn(name); \ + SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i|(iscap<<31))); \ SDL_free(name); \ } \ } \ } \ } -DETECT_DEV_IMPL(Out, WAVEOUTCAPS) -DETECT_DEV_IMPL(In, WAVEINCAPS) +DETECT_DEV_IMPL(SDL_FALSE, Out, WAVEOUTCAPS) +DETECT_DEV_IMPL(SDL_TRUE, In, WAVEINCAPS) static void -WINMM_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +WINMM_DetectDevices() { - if (iscapture) { - DetectWaveInDevs(addfn); - } else { - DetectWaveOutDevs(addfn); - } + DetectWaveInDevs(); + DetectWaveOutDevs(); } static void CALLBACK @@ -220,7 +219,7 @@ PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture) } static int -WINMM_OpenDevice(_THIS, const char *devname, int iscapture) +WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); int valid_datatype = 0; @@ -230,37 +229,13 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture) char *utf8 = NULL; UINT i; - if (devname != NULL) { /* specific device requested? */ + if (handle != NULL) { /* specific device requested? */ + const size_t val = (size_t) handle; + devId = (UINT) val; if (iscapture) { - const UINT devcount = 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 = i; - SDL_free(utf8); - } - } else { - const UINT devcount = 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 = i; - SDL_free(utf8); - } - } - - if (devId == WAVE_MAPPER) { - return SDL_SetError("Requested device not found"); + /* we use the top bit to make value unique vs output indices. */ + SDL_assert((devId & (1<<31)) != 0); + devId &= ~(1<<31); } } diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index 37fdf593b..8aebabf6e 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -126,16 +126,13 @@ struct SDL_PrivateAudioData static void -XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) +XAUDIO2_DetectDevices(void) { IXAudio2 *ixa2 = NULL; UINT32 devcount = 0; UINT32 i = 0; - if (iscapture) { - SDL_SetError("XAudio2: capture devices unsupported."); - return; - } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { + if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { SDL_SetError("XAudio2: XAudio2Create() failed at detection."); return; } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) { @@ -149,8 +146,8 @@ XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) { char *str = WIN_StringToUTF8(details.DisplayName); if (str != NULL) { - addfn(str); - SDL_free(str); /* addfn() made a copy of the string. */ + SDL_AddAudioDevice(SDL_FALSE, str, (void *) ((size_t) i)); + SDL_free(str); /* SDL_AddAudioDevice made a copy of the string. */ } } } @@ -169,8 +166,8 @@ VoiceCBOnBufferEnd(THIS_ void *data) static void STDMETHODCALLTYPE VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error) { - /* !!! FIXME: attempt to recover, or mark device disconnected. */ - SDL_assert(0 && "write me!"); + SDL_AudioDevice *this = (SDL_AudioDevice *) data; + SDL_OpenedAudioDeviceDisconnected(this); } /* no-op callbacks... */ @@ -221,7 +218,7 @@ XAUDIO2_PlayDevice(_THIS) if (result != S_OK) { /* uhoh, panic! */ IXAudio2SourceVoice_FlushSourceBuffers(source); - SDL_AudioDeviceDisconnected(SDL_FALSE, this); + SDL_OpenedAudioDeviceDisconnected(this); } } @@ -289,7 +286,7 @@ XAUDIO2_CloseDevice(_THIS) } static int -XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) +XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { HRESULT result = S_OK; WAVEFORMATEX waveformat; @@ -300,7 +297,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) #if defined(SDL_XAUDIO2_WIN8) LPCWSTR devId = NULL; #else - UINT32 devId = 0; /* 0 == system default device. */ + UINT32 devId = (UINT32) ((size_t) handle); /* 0 == system default device. */ #endif static IXAudio2VoiceCallbackVtbl callbacks_vtable = { @@ -315,9 +312,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) static IXAudio2VoiceCallback callbacks = { &callbacks_vtable }; - if (iscapture) { - return SDL_SetError("XAudio2: capture devices unsupported."); - } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { + if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { return SDL_SetError("XAudio2: XAudio2Create() failed at open."); } @@ -332,37 +327,6 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) ixa2->SetDebugConfiguration(&debugConfig); */ -#if ! defined(__WINRT__) - if (devname != NULL) { - UINT32 devcount = 0; - UINT32 i = 0; - - if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) { - IXAudio2_Release(ixa2); - return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed."); - } - for (i = 0; i < devcount; i++) { - XAUDIO2_DEVICE_DETAILS details; - if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) { - char *str = WIN_StringToUTF8(details.DisplayName); - if (str != NULL) { - const int match = (SDL_strcmp(str, devname) == 0); - SDL_free(str); - if (match) { - devId = i; - break; - } - } - } - } - - if (i == devcount) { - IXAudio2_Release(ixa2); - return SDL_SetError("XAudio2: Requested device not found."); - } - } -#endif - /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); @@ -529,6 +493,16 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl) impl->CloseDevice = XAUDIO2_CloseDevice; impl->Deinitialize = XAUDIO2_Deinitialize; + /* !!! FIXME: We can apparently use a C++ interface on Windows 8 + * !!! FIXME: (Windows::Devices::Enumeration::DeviceInformation) for device + * !!! FIXME: detection, but it's not implemented here yet. + * !!! FIXME: see http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx + * !!! FIXME: for now, force the default device. + */ +#if defined(SDL_XAUDIO2_WIN8) || defined(__WINRT__) + impl->OnlyHasDefaultOutputDevice = 1; +#endif + return 1; /* this audio target is available. */ #endif }