mirror of
https://github.com/Ryujinx/SDL.git
synced 2024-12-23 18:25:36 +00:00
audio: All device names reported by SDL must be unique.
This means that if you have two devices named "Soundblaster Pro" in your machine, one will be reported as "Soundblaster Pro" and the other as "Soundblaster Pro (2)". This makes it so you can't into a position where one of your devices can't be opened because another is sitting on the same name.
This commit is contained in:
parent
0378529e1e
commit
04cbf13261
|
@ -378,21 +378,57 @@ static int
|
||||||
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
|
SDL_AudioDeviceItem *item;
|
||||||
SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
|
const SDL_AudioDeviceItem *i;
|
||||||
if (item == NULL) {
|
int dupenum = 0;
|
||||||
|
|
||||||
|
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
|
||||||
|
SDL_assert(name != NULL);
|
||||||
|
|
||||||
|
item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem));
|
||||||
|
if (!item) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
item->original_name = SDL_strdup(name);
|
||||||
|
if (!item->original_name) {
|
||||||
|
SDL_free(item);
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
item->dupenum = 0;
|
||||||
|
item->name = item->original_name;
|
||||||
|
item->handle = handle;
|
||||||
|
|
||||||
|
SDL_LockMutex(current_audio.detectionLock);
|
||||||
|
|
||||||
|
for (i = *devices; i != NULL; i = i->next) {
|
||||||
|
if (SDL_strcmp(name, i->original_name) == 0) {
|
||||||
|
dupenum = i->dupenum + 1;
|
||||||
|
break; /* stop at the highest-numbered dupe. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dupenum) {
|
||||||
|
const size_t len = SDL_strlen(name) + 16;
|
||||||
|
char *replacement = (char *) SDL_malloc(len);
|
||||||
|
if (!replacement) {
|
||||||
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
|
SDL_free(item->original_name);
|
||||||
|
SDL_free(item);
|
||||||
|
SDL_OutOfMemory();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
|
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
|
||||||
|
item->dupenum = dupenum;
|
||||||
|
item->name = replacement;
|
||||||
|
}
|
||||||
|
|
||||||
item->handle = handle;
|
|
||||||
SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
|
|
||||||
|
|
||||||
SDL_LockMutex(current_audio.detectionLock);
|
|
||||||
item->next = *devices;
|
item->next = *devices;
|
||||||
*devices = item;
|
*devices = item;
|
||||||
retval = (*devCount)++;
|
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
|
||||||
|
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -420,6 +456,11 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
||||||
if (item->handle != NULL) {
|
if (item->handle != NULL) {
|
||||||
current_audio.impl.FreeDeviceHandle(item->handle);
|
current_audio.impl.FreeDeviceHandle(item->handle);
|
||||||
}
|
}
|
||||||
|
/* these two pointers are the same if not a duplicate devname */
|
||||||
|
if (item->name != item->original_name) {
|
||||||
|
SDL_free(item->name);
|
||||||
|
}
|
||||||
|
SDL_free(item->original_name);
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
}
|
}
|
||||||
*devices = NULL;
|
*devices = NULL;
|
||||||
|
@ -977,6 +1018,11 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re
|
||||||
} else {
|
} else {
|
||||||
*devices = next;
|
*devices = next;
|
||||||
}
|
}
|
||||||
|
/* these two pointers are the same if not a duplicate devname */
|
||||||
|
if (item->name != item->original_name) {
|
||||||
|
SDL_free(item->name);
|
||||||
|
}
|
||||||
|
SDL_free(item->original_name);
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
}
|
}
|
||||||
item = next;
|
item = next;
|
||||||
|
|
|
@ -98,8 +98,10 @@ typedef struct SDL_AudioDriverImpl
|
||||||
typedef struct SDL_AudioDeviceItem
|
typedef struct SDL_AudioDeviceItem
|
||||||
{
|
{
|
||||||
void *handle;
|
void *handle;
|
||||||
|
char *name;
|
||||||
|
char *original_name;
|
||||||
|
int dupenum;
|
||||||
struct SDL_AudioDeviceItem *next;
|
struct SDL_AudioDeviceItem *next;
|
||||||
char name[SDL_VARIABLE_LENGTH_ARRAY];
|
|
||||||
} SDL_AudioDeviceItem;
|
} SDL_AudioDeviceItem;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue