Skip to content

Commit

Permalink
audio: All device names reported by SDL must be unique.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
icculus committed Oct 10, 2018
1 parent 0378529 commit 04cbf13
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
60 changes: 53 additions & 7 deletions src/audio/SDL_audio.c
Expand Up @@ -378,21 +378,57 @@ static int
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
{
int retval = -1;
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_AudioDeviceItem *item;
const SDL_AudioDeviceItem *i;
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_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));

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;
}

SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
item->dupenum = dupenum;
item->name = replacement;
}

item->next = *devices;
*devices = item;
retval = (*devCount)++;
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */

SDL_UnlockMutex(current_audio.detectionLock);

return retval;
Expand Down Expand Up @@ -420,6 +456,11 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
if (item->handle != NULL) {
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);
}
*devices = NULL;
Expand Down Expand Up @@ -977,6 +1018,11 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re
} else {
*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);
}
item = next;
Expand Down
4 changes: 3 additions & 1 deletion src/audio/SDL_sysaudio.h
Expand Up @@ -98,8 +98,10 @@ typedef struct SDL_AudioDriverImpl
typedef struct SDL_AudioDeviceItem
{
void *handle;
char *name;
char *original_name;
int dupenum;
struct SDL_AudioDeviceItem *next;
char name[SDL_VARIABLE_LENGTH_ARRAY];
} SDL_AudioDeviceItem;


Expand Down

0 comments on commit 04cbf13

Please sign in to comment.