提交 4a3b8b34 编写于 作者: K Kővágó, Zoltán 提交者: Gerd Hoffmann

dsoundaudio: port to -audiodev config

Signed-off-by: NKővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Message-id: f25562cb88246b41c3e6380685a108fd341d5b50.1552083282.git.DirtY.iCE.hu@gmail.com
Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
上级 17c56dc1
...@@ -120,6 +120,30 @@ static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 ( ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册