Skip to content

Commit

Permalink
wasapi/win32: Sort initial device lists by device GUID.
Browse files Browse the repository at this point in the history
This makes an unchanged set of hardware always report devices in the same
order on each run.
  • Loading branch information
icculus committed Oct 22, 2018
1 parent 1ec56f7 commit 4a50a04
Showing 1 changed file with 54 additions and 8 deletions.
62 changes: 54 additions & 8 deletions src/audio/wasapi/SDL_wasapi_win32.c
Expand Up @@ -351,10 +351,42 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
}


typedef struct
{
LPWSTR devid;
char *devname;
} EndpointItem;

static int sort_endpoints(const void *_a, const void *_b)
{
LPWSTR a = ((const EndpointItem *) _a)->devid;
LPWSTR b = ((const EndpointItem *) _b)->devid;
if (!a && b) {
return -1;
} else if (a && !b) {
return 1;
}

while (SDL_TRUE) {
if (*a < *b) {
return -1;
} else if (*a > *b) {
return 1;
} else if (*a == 0) {
break;
}
a++;
b++;
}

return 0;
}

static void
WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
{
IMMDeviceCollection *collection = NULL;
EndpointItem *items;
UINT i, total;

/* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
Expand All @@ -369,22 +401,36 @@ WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
return;
}

items = (EndpointItem *) SDL_calloc(total, sizeof (EndpointItem));
if (!items) {
return; /* oh well. */
}

for (i = 0; i < total; i++) {
EndpointItem *item = items + i;
IMMDevice *device = NULL;
if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
LPWSTR devid = NULL;
if (SUCCEEDED(IMMDevice_GetId(device, &devid))) {
char *devname = GetWasapiDeviceName(device);
if (devname) {
WASAPI_AddDevice(iscapture, devname, devid);
SDL_free(devname);
}
CoTaskMemFree(devid);
if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) {
item->devname = GetWasapiDeviceName(device);
}
IMMDevice_Release(device);
}
}

/* sort the list of devices by their guid so list is consistent between runs */
SDL_qsort(items, total, sizeof (*items), sort_endpoints);

/* Send the sorted list on to the SDL's higher level. */
for (i = 0; i < total; i++) {
EndpointItem *item = items + i;
if ((item->devid) && (item->devname)) {
WASAPI_AddDevice(iscapture, item->devname, item->devid);
}
SDL_free(item->devname);
CoTaskMemFree(item->devid);
}

SDL_free(items);
IMMDeviceCollection_Release(collection);
}

Expand Down

0 comments on commit 4a50a04

Please sign in to comment.