mirror of
https://github.com/libretro/RetroArch
synced 2025-02-11 06:40:48 +00:00
(DirectSound) Add audio device selection - can set audio_device
either by name or by index
This commit is contained in:
parent
afc2888116
commit
ce37405d29
@ -35,7 +35,9 @@
|
|||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
#include <rthreads/rthreads.h>
|
#include <rthreads/rthreads.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <lists/string_list.h>
|
||||||
#include <queues/fifo_queue.h>
|
#include <queues/fifo_queue.h>
|
||||||
|
#include <string/stdstring.h>
|
||||||
|
|
||||||
#include "../../retroarch.h"
|
#include "../../retroarch.h"
|
||||||
#include "../../verbosity.h"
|
#include "../../verbosity.h"
|
||||||
@ -73,6 +75,9 @@ typedef struct dsound
|
|||||||
volatile bool thread_alive;
|
volatile bool thread_alive;
|
||||||
} dsound_t;
|
} dsound_t;
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
static void *dsound_list_new(void *u);
|
||||||
|
|
||||||
static INLINE unsigned write_avail(unsigned read_ptr,
|
static INLINE unsigned write_avail(unsigned read_ptr,
|
||||||
unsigned write_ptr, unsigned buffer_size)
|
unsigned write_ptr, unsigned buffer_size)
|
||||||
{
|
{
|
||||||
@ -298,52 +303,86 @@ static void dsound_free(void *data)
|
|||||||
free(ds);
|
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)
|
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;
|
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 block_frames,
|
||||||
unsigned *new_rate)
|
unsigned *new_rate)
|
||||||
{
|
{
|
||||||
WAVEFORMATEX wfx = {0};
|
LPGUID selected_device = NULL;
|
||||||
DSBUFFERDESC bufdesc = {0};
|
WAVEFORMATEX wfx = {0};
|
||||||
struct dsound_dev dev = {0};
|
DSBUFFERDESC bufdesc = {0};
|
||||||
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
|
int32_t idx_found = -1;
|
||||||
|
struct string_list *list = dsound_list_new(NULL);
|
||||||
|
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
|
||||||
|
|
||||||
if (!ds)
|
if (!ds)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
InitializeCriticalSection(&ds->crit);
|
InitializeCriticalSection(&ds->crit);
|
||||||
|
|
||||||
if (device)
|
if (dev)
|
||||||
dev.device = strtoul(device, NULL, 0);
|
{
|
||||||
|
/* 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");
|
if (idx_found == -1 && isdigit(dev[0]))
|
||||||
#ifndef _XBOX
|
{
|
||||||
#ifdef UNICODE
|
idx_found = strtoul(dev, NULL, 0);
|
||||||
DirectSoundEnumerate((LPDSENUMCALLBACKW)enumerate_cb, &dev);
|
RARCH_LOG("[DirectSound]: Fallback, device index is a single number index instead: %d.\n", idx_found);
|
||||||
#else
|
|
||||||
DirectSoundEnumerate((LPDSENUMCALLBACKA)enumerate_cb, &dev);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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;
|
goto error;
|
||||||
|
|
||||||
#ifndef _XBOX
|
#ifndef _XBOX
|
||||||
@ -397,10 +436,13 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency,
|
|||||||
if (!dsound_start_thread(ds))
|
if (!dsound_start_thread(ds))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
string_list_free(list);
|
||||||
return ds;
|
return ds;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
RARCH_ERR("[DirectSound] Error occurred in init.\n");
|
RARCH_ERR("[DirectSound] Error occurred in init.\n");
|
||||||
|
if (list)
|
||||||
|
string_list_free(list);
|
||||||
dsound_free(ds);
|
dsound_free(ds);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -502,6 +544,32 @@ static bool dsound_use_float(void *data)
|
|||||||
return false;
|
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 = {
|
audio_driver_t audio_dsound = {
|
||||||
dsound_init,
|
dsound_init,
|
||||||
dsound_write,
|
dsound_write,
|
||||||
@ -512,8 +580,8 @@ audio_driver_t audio_dsound = {
|
|||||||
dsound_free,
|
dsound_free,
|
||||||
dsound_use_float,
|
dsound_use_float,
|
||||||
"dsound",
|
"dsound",
|
||||||
NULL,
|
dsound_list_new,
|
||||||
NULL,
|
dsound_device_list_free,
|
||||||
dsound_write_avail,
|
dsound_write_avail,
|
||||||
dsound_buffer_size,
|
dsound_buffer_size,
|
||||||
};
|
};
|
||||||
|
@ -95,10 +95,13 @@ static IMMDevice *wasapi_init_device(const char *id)
|
|||||||
idx_found = strtoul(id, NULL, 0);
|
idx_found = strtoul(id, NULL, 0);
|
||||||
RARCH_LOG("[WASAPI]: Fallback, device index is a single number index instead: %d.\n", idx_found);
|
RARCH_LOG("[WASAPI]: Fallback, device index is a single number index instead: %d.\n", idx_found);
|
||||||
|
|
||||||
if (idx_found < list->size)
|
if (idx_found != -1)
|
||||||
{
|
{
|
||||||
RARCH_LOG("[WASAPI]: Corresponding name: %s\n", list->elems[idx_found].data);
|
if (idx_found < (int32_t)list->size)
|
||||||
}
|
{
|
||||||
|
RARCH_LOG("[WASAPI]: Corresponding name: %s\n", list->elems[idx_found].data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string_list_free(list);
|
string_list_free(list);
|
||||||
|
@ -41,6 +41,7 @@ union string_list_elem_attr
|
|||||||
struct string_list_elem
|
struct string_list_elem
|
||||||
{
|
{
|
||||||
char *data;
|
char *data;
|
||||||
|
void *userdata;
|
||||||
union string_list_elem_attr attr;
|
union string_list_elem_attr attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,7 +47,10 @@ void string_list_free(struct string_list *list)
|
|||||||
{
|
{
|
||||||
if (list->elems[i].data)
|
if (list->elems[i].data)
|
||||||
free(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);
|
free(list->elems);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user