mirror of https://github.com/xemu-project/xemu.git
dsoundaudio: port to -audiodev config
Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com> Message-id: f25562cb88246b41c3e6380685a108fd341d5b50.1552083282.git.DirtY.iCE.hu@gmail.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
17c56dc1d1
commit
4a3b8b3444
|
@ -120,6 +120,30 @@ static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t samples_to_usecs(uint32_t samples,
|
||||||
|
AudiodevPerDirectionOptions *pdo)
|
||||||
|
{
|
||||||
|
uint32_t channels = pdo->has_channels ? pdo->channels : 2;
|
||||||
|
return frames_to_usecs(samples / channels, pdo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t bytes_to_usecs(uint32_t bytes, AudiodevPerDirectionOptions *pdo)
|
||||||
|
{
|
||||||
|
AudioFormat fmt = pdo->has_format ? pdo->format : AUDIO_FORMAT_S16;
|
||||||
|
uint32_t bytes_per_sample = audioformat_bytes_per_sample(fmt);
|
||||||
|
return samples_to_usecs(bytes / bytes_per_sample, pdo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_bytes_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||||
|
AudiodevPerDirectionOptions *pdo)
|
||||||
|
{
|
||||||
|
const char *val = getenv(env);
|
||||||
|
if (val) {
|
||||||
|
*dst = bytes_to_usecs(toui32(val), pdo);
|
||||||
|
*has_dst = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* backend specific functions */
|
/* backend specific functions */
|
||||||
/* ALSA */
|
/* ALSA */
|
||||||
static void handle_alsa_per_direction(
|
static void handle_alsa_per_direction(
|
||||||
|
@ -180,6 +204,21 @@ static void handle_coreaudio(Audiodev *dev)
|
||||||
&dev->u.coreaudio.out->has_buffer_count);
|
&dev->u.coreaudio.out->has_buffer_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dsound */
|
||||||
|
static void handle_dsound(Audiodev *dev)
|
||||||
|
{
|
||||||
|
get_millis_to_usecs("QEMU_DSOUND_LATENCY_MILLIS",
|
||||||
|
&dev->u.dsound.latency, &dev->u.dsound.has_latency);
|
||||||
|
get_bytes_to_usecs("QEMU_DSOUND_BUFSIZE_OUT",
|
||||||
|
&dev->u.dsound.out->buffer_length,
|
||||||
|
&dev->u.dsound.out->has_buffer_length,
|
||||||
|
dev->u.dsound.out);
|
||||||
|
get_bytes_to_usecs("QEMU_DSOUND_BUFSIZE_IN",
|
||||||
|
&dev->u.dsound.in->buffer_length,
|
||||||
|
&dev->u.dsound.in->has_buffer_length,
|
||||||
|
dev->u.dsound.in);
|
||||||
|
}
|
||||||
|
|
||||||
/* general */
|
/* general */
|
||||||
static void handle_per_direction(
|
static void handle_per_direction(
|
||||||
AudiodevPerDirectionOptions *pdo, const char *prefix)
|
AudiodevPerDirectionOptions *pdo, const char *prefix)
|
||||||
|
@ -229,6 +268,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname)
|
||||||
handle_coreaudio(e->dev);
|
handle_coreaudio(e->dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AUDIODEV_DRIVER_DSOUND:
|
||||||
|
handle_dsound(e->dev);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,17 +167,18 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||||
dsound *s = drv_opaque;
|
dsound *s = drv_opaque;
|
||||||
WAVEFORMATEX wfx;
|
WAVEFORMATEX wfx;
|
||||||
struct audsettings obt_as;
|
struct audsettings obt_as;
|
||||||
DSoundConf *conf = &s->conf;
|
|
||||||
#ifdef DSBTYPE_IN
|
#ifdef DSBTYPE_IN
|
||||||
const char *typ = "ADC";
|
const char *typ = "ADC";
|
||||||
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
|
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
|
||||||
DSCBUFFERDESC bd;
|
DSCBUFFERDESC bd;
|
||||||
DSCBCAPS bc;
|
DSCBCAPS bc;
|
||||||
|
AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
|
||||||
#else
|
#else
|
||||||
const char *typ = "DAC";
|
const char *typ = "DAC";
|
||||||
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
|
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
|
||||||
DSBUFFERDESC bd;
|
DSBUFFERDESC bd;
|
||||||
DSBCAPS bc;
|
DSBCAPS bc;
|
||||||
|
AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!s->FIELD2) {
|
if (!s->FIELD2) {
|
||||||
|
@ -193,8 +194,8 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||||
memset (&bd, 0, sizeof (bd));
|
memset (&bd, 0, sizeof (bd));
|
||||||
bd.dwSize = sizeof (bd);
|
bd.dwSize = sizeof (bd);
|
||||||
bd.lpwfxFormat = &wfx;
|
bd.lpwfxFormat = &wfx;
|
||||||
|
bd.dwBufferBytes = audio_buffer_bytes(pdo, as, 92880);
|
||||||
#ifdef DSBTYPE_IN
|
#ifdef DSBTYPE_IN
|
||||||
bd.dwBufferBytes = conf->bufsize_in;
|
|
||||||
hr = IDirectSoundCapture_CreateCaptureBuffer (
|
hr = IDirectSoundCapture_CreateCaptureBuffer (
|
||||||
s->dsound_capture,
|
s->dsound_capture,
|
||||||
&bd,
|
&bd,
|
||||||
|
@ -203,7 +204,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
|
bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
|
||||||
bd.dwBufferBytes = conf->bufsize_out;
|
|
||||||
hr = IDirectSound_CreateSoundBuffer (
|
hr = IDirectSound_CreateSoundBuffer (
|
||||||
s->dsound,
|
s->dsound,
|
||||||
&bd,
|
&bd,
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#define AUDIO_CAP "dsound"
|
#define AUDIO_CAP "dsound"
|
||||||
#include "audio_int.h"
|
#include "audio_int.h"
|
||||||
|
#include "qemu/host-utils.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
@ -42,17 +43,11 @@
|
||||||
|
|
||||||
/* #define DEBUG_DSOUND */
|
/* #define DEBUG_DSOUND */
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int bufsize_in;
|
|
||||||
int bufsize_out;
|
|
||||||
int latency_millis;
|
|
||||||
} DSoundConf;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
LPDIRECTSOUND dsound;
|
LPDIRECTSOUND dsound;
|
||||||
LPDIRECTSOUNDCAPTURE dsound_capture;
|
LPDIRECTSOUNDCAPTURE dsound_capture;
|
||||||
struct audsettings settings;
|
struct audsettings settings;
|
||||||
DSoundConf conf;
|
Audiodev *dev;
|
||||||
} dsound;
|
} dsound;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -248,9 +243,9 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
|
||||||
dsound_log_hresult (hr);
|
dsound_log_hresult (hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD millis_to_bytes (struct audio_pcm_info *info, DWORD millis)
|
static uint64_t usecs_to_bytes(struct audio_pcm_info *info, uint32_t usecs)
|
||||||
{
|
{
|
||||||
return (millis * info->bytes_per_second) / 1000;
|
return muldiv64(usecs, info->bytes_per_second, 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DSOUND
|
#ifdef DEBUG_DSOUND
|
||||||
|
@ -478,7 +473,7 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
|
||||||
LPVOID p1, p2;
|
LPVOID p1, p2;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
dsound *s = ds->s;
|
dsound *s = ds->s;
|
||||||
DSoundConf *conf = &s->conf;
|
AudiodevDsoundOptions *dso = &s->dev->u.dsound;
|
||||||
|
|
||||||
if (!dsb) {
|
if (!dsb) {
|
||||||
dolog ("Attempt to run empty with playback buffer\n");
|
dolog ("Attempt to run empty with playback buffer\n");
|
||||||
|
@ -501,14 +496,14 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
|
||||||
len = live << hwshift;
|
len = live << hwshift;
|
||||||
|
|
||||||
if (ds->first_time) {
|
if (ds->first_time) {
|
||||||
if (conf->latency_millis) {
|
if (dso->latency) {
|
||||||
DWORD cur_blat;
|
DWORD cur_blat;
|
||||||
|
|
||||||
cur_blat = audio_ring_dist (wpos, ppos, bufsize);
|
cur_blat = audio_ring_dist (wpos, ppos, bufsize);
|
||||||
ds->first_time = 0;
|
ds->first_time = 0;
|
||||||
old_pos = wpos;
|
old_pos = wpos;
|
||||||
old_pos +=
|
old_pos +=
|
||||||
millis_to_bytes (&hw->info, conf->latency_millis) - cur_blat;
|
usecs_to_bytes(&hw->info, dso->latency) - cur_blat;
|
||||||
old_pos %= bufsize;
|
old_pos %= bufsize;
|
||||||
old_pos &= ~hw->info.align;
|
old_pos &= ~hw->info.align;
|
||||||
}
|
}
|
||||||
|
@ -747,12 +742,6 @@ static int dsound_run_in (HWVoiceIn *hw)
|
||||||
return decr;
|
return decr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DSoundConf glob_conf = {
|
|
||||||
.bufsize_in = 16384,
|
|
||||||
.bufsize_out = 16384,
|
|
||||||
.latency_millis = 10
|
|
||||||
};
|
|
||||||
|
|
||||||
static void dsound_audio_fini (void *opaque)
|
static void dsound_audio_fini (void *opaque)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -788,8 +777,17 @@ static void *dsound_audio_init(Audiodev *dev)
|
||||||
int err;
|
int err;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
dsound *s = g_malloc0(sizeof(dsound));
|
dsound *s = g_malloc0(sizeof(dsound));
|
||||||
|
AudiodevDsoundOptions *dso;
|
||||||
|
|
||||||
|
assert(dev->driver == AUDIODEV_DRIVER_DSOUND);
|
||||||
|
s->dev = dev;
|
||||||
|
dso = &dev->u.dsound;
|
||||||
|
|
||||||
|
if (!dso->has_latency) {
|
||||||
|
dso->has_latency = true;
|
||||||
|
dso->latency = 10000; /* 10 ms */
|
||||||
|
}
|
||||||
|
|
||||||
s->conf = glob_conf;
|
|
||||||
hr = CoInitialize (NULL);
|
hr = CoInitialize (NULL);
|
||||||
if (FAILED (hr)) {
|
if (FAILED (hr)) {
|
||||||
dsound_logerr (hr, "Could not initialize COM\n");
|
dsound_logerr (hr, "Could not initialize COM\n");
|
||||||
|
@ -854,28 +852,6 @@ static void *dsound_audio_init(Audiodev *dev)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct audio_option dsound_options[] = {
|
|
||||||
{
|
|
||||||
.name = "LATENCY_MILLIS",
|
|
||||||
.tag = AUD_OPT_INT,
|
|
||||||
.valp = &glob_conf.latency_millis,
|
|
||||||
.descr = "(undocumented)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "BUFSIZE_OUT",
|
|
||||||
.tag = AUD_OPT_INT,
|
|
||||||
.valp = &glob_conf.bufsize_out,
|
|
||||||
.descr = "(undocumented)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "BUFSIZE_IN",
|
|
||||||
.tag = AUD_OPT_INT,
|
|
||||||
.valp = &glob_conf.bufsize_in,
|
|
||||||
.descr = "(undocumented)"
|
|
||||||
},
|
|
||||||
{ /* End of list */ }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct audio_pcm_ops dsound_pcm_ops = {
|
static struct audio_pcm_ops dsound_pcm_ops = {
|
||||||
.init_out = dsound_init_out,
|
.init_out = dsound_init_out,
|
||||||
.fini_out = dsound_fini_out,
|
.fini_out = dsound_fini_out,
|
||||||
|
@ -893,7 +869,6 @@ static struct audio_pcm_ops dsound_pcm_ops = {
|
||||||
static struct audio_driver dsound_audio_driver = {
|
static struct audio_driver dsound_audio_driver = {
|
||||||
.name = "dsound",
|
.name = "dsound",
|
||||||
.descr = "DirectSound http://wikipedia.org/wiki/DirectSound",
|
.descr = "DirectSound http://wikipedia.org/wiki/DirectSound",
|
||||||
.options = dsound_options,
|
|
||||||
.init = dsound_audio_init,
|
.init = dsound_audio_init,
|
||||||
.fini = dsound_audio_fini,
|
.fini = dsound_audio_fini,
|
||||||
.pcm_ops = &dsound_pcm_ops,
|
.pcm_ops = &dsound_pcm_ops,
|
||||||
|
|
Loading…
Reference in New Issue