(DirectSound) Add audio device selection - can set audio_device

either by name or by index
This commit is contained in:
twinaphex 2019-07-26 02:36:18 +02:00
parent afc2888116
commit ce37405d29
4 changed files with 110 additions and 35 deletions

View File

@ -35,7 +35,9 @@
#ifdef HAVE_THREADS
#include <rthreads/rthreads.h>
#endif
#include <lists/string_list.h>
#include <queues/fifo_queue.h>
#include <string/stdstring.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
@ -73,6 +75,9 @@ typedef struct dsound
volatile bool thread_alive;
} dsound_t;
/* Forward declarations */
static void *dsound_list_new(void *u);
static INLINE unsigned write_avail(unsigned read_ptr,
unsigned write_ptr, unsigned buffer_size)
{
@ -298,52 +303,86 @@ static void dsound_free(void *data)
free(ds);
}
struct dsound_dev
{
unsigned device;
unsigned total_count;
LPGUID guid;
};
static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context)
{
struct dsound_dev *dev = (struct dsound_dev*)context;
union string_list_elem_attr attr;
struct string_list *list = (struct string_list*)context;
RARCH_LOG("\t%u: %s\n", dev->total_count, desc);
attr.i = 0;
string_list_append(list, desc, attr);
if (guid)
{
unsigned i;
LPGUID guid_copy = (LPGUID)malloc(sizeof(GUID) * 1);
guid_copy->Data1 = guid->Data1;
guid_copy->Data2 = guid->Data2;
guid_copy->Data3 = guid->Data3;
for (i = 0; i < 8; i++)
guid_copy->Data4[i] = guid->Data4[i];
list->elems[list->size-1].userdata = guid_copy;
}
if (dev->device == dev->total_count)
dev->guid = guid;
dev->total_count++;
return TRUE;
}
static void *dsound_init(const char *device, unsigned rate, unsigned latency,
static void *dsound_init(const char *dev, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
WAVEFORMATEX wfx = {0};
DSBUFFERDESC bufdesc = {0};
struct dsound_dev dev = {0};
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
LPGUID selected_device = NULL;
WAVEFORMATEX wfx = {0};
DSBUFFERDESC bufdesc = {0};
int32_t idx_found = -1;
struct string_list *list = dsound_list_new(NULL);
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
if (!ds)
goto error;
InitializeCriticalSection(&ds->crit);
if (device)
dev.device = strtoul(device, NULL, 0);
if (dev)
{
/* Search for device name first */
if (list && list->elems)
{
if (list->elems)
{
unsigned i;
for (i = 0; i < list->size; i++)
{
if (string_is_equal(dev, list->elems[i].data))
{
idx_found = i;
selected_device = list->elems[idx_found].userdata;
break;
}
}
/* Index was not found yet based on name string,
* just assume id is a one-character number index. */
RARCH_LOG("DirectSound devices:\n");
#ifndef _XBOX
#ifdef UNICODE
DirectSoundEnumerate((LPDSENUMCALLBACKW)enumerate_cb, &dev);
#else
DirectSoundEnumerate((LPDSENUMCALLBACKA)enumerate_cb, &dev);
#endif
#endif
if (idx_found == -1 && isdigit(dev[0]))
{
idx_found = strtoul(dev, NULL, 0);
RARCH_LOG("[DirectSound]: Fallback, device index is a single number index instead: %d.\n", idx_found);
if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK)
if (idx_found != -1)
{
if (idx_found < (int32_t)list->size)
{
RARCH_LOG("[DirectSound]: Corresponding name: %s\n", list->elems[idx_found].data);
selected_device = list->elems[idx_found].userdata;
}
}
}
}
}
}
if (DirectSoundCreate(selected_device, &ds->ds, NULL) != DS_OK)
goto error;
#ifndef _XBOX
@ -397,10 +436,13 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency,
if (!dsound_start_thread(ds))
goto error;
string_list_free(list);
return ds;
error:
RARCH_ERR("[DirectSound] Error occurred in init.\n");
if (list)
string_list_free(list);
dsound_free(ds);
return NULL;
}
@ -502,6 +544,32 @@ static bool dsound_use_float(void *data)
return false;
}
static void *dsound_list_new(void *u)
{
struct string_list *sl = string_list_new();
if (!sl)
return NULL;
#ifndef _XBOX
#ifdef UNICODE
DirectSoundEnumerate((LPDSENUMCALLBACKW)enumerate_cb, sl);
#else
DirectSoundEnumerate((LPDSENUMCALLBACKA)enumerate_cb, sl);
#endif
#endif
return sl;
}
static void dsound_device_list_free(void *u, void *slp)
{
struct string_list *sl = (struct string_list*)slp;
if (sl)
string_list_free(sl);
}
audio_driver_t audio_dsound = {
dsound_init,
dsound_write,
@ -512,8 +580,8 @@ audio_driver_t audio_dsound = {
dsound_free,
dsound_use_float,
"dsound",
NULL,
NULL,
dsound_list_new,
dsound_device_list_free,
dsound_write_avail,
dsound_buffer_size,
};

View File

@ -95,10 +95,13 @@ static IMMDevice *wasapi_init_device(const char *id)
idx_found = strtoul(id, NULL, 0);
RARCH_LOG("[WASAPI]: Fallback, device index is a single number index instead: %d.\n", idx_found);
if (idx_found < list->size)
{
RARCH_LOG("[WASAPI]: Corresponding name: %s\n", list->elems[idx_found].data);
}
if (idx_found != -1)
{
if (idx_found < (int32_t)list->size)
{
RARCH_LOG("[WASAPI]: Corresponding name: %s\n", list->elems[idx_found].data);
}
}
}
}
string_list_free(list);

View File

@ -41,6 +41,7 @@ union string_list_elem_attr
struct string_list_elem
{
char *data;
void *userdata;
union string_list_elem_attr attr;
};

View File

@ -47,7 +47,10 @@ void string_list_free(struct string_list *list)
{
if (list->elems[i].data)
free(list->elems[i].data);
list->elems[i].data = NULL;
if (list->elems[i].userdata)
free(list->elems[i].userdata);
list->elems[i].data = NULL;
list->elems[i].userdata = NULL;
}
free(list->elems);