#define AUDIO_CAP "dsound"
#include "audio_int.h"
+#include "qemu/host-utils.h"
#include <windows.h>
#include <mmsystem.h>
/* #define DEBUG_DSOUND */
-typedef struct {
- int bufsize_in;
- int bufsize_out;
- int latency_millis;
-} DSoundConf;
-
typedef struct {
LPDIRECTSOUND dsound;
LPDIRECTSOUNDCAPTURE dsound_capture;
struct audsettings settings;
- DSoundConf conf;
+ Audiodev *dev;
} dsound;
typedef struct {
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
LPVOID p1, p2;
int bufsize;
dsound *s = ds->s;
- DSoundConf *conf = &s->conf;
+ AudiodevDsoundOptions *dso = &s->dev->u.dsound;
if (!dsb) {
dolog ("Attempt to run empty with playback buffer\n");
len = live << hwshift;
if (ds->first_time) {
- if (conf->latency_millis) {
+ if (dso->latency) {
DWORD cur_blat;
cur_blat = audio_ring_dist (wpos, ppos, bufsize);
ds->first_time = 0;
old_pos = wpos;
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 &= ~hw->info.align;
}
}
}
- if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
+ if (audio_bug(__func__, len < 0 || len > bufsize)) {
dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
len, bufsize, old_pos, ppos);
return 0;
return decr;
}
-static DSoundConf glob_conf = {
- .bufsize_in = 16384,
- .bufsize_out = 16384,
- .latency_millis = 10
-};
-
static void dsound_audio_fini (void *opaque)
{
HRESULT hr;
g_free(s);
}
-static void *dsound_audio_init (void)
+static void *dsound_audio_init(Audiodev *dev)
{
int err;
HRESULT hr;
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);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not initialize COM\n");
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 = {
.init_out = dsound_init_out,
.fini_out = dsound_fini_out,
.ctl_in = dsound_ctl_in
};
-struct audio_driver dsound_audio_driver = {
+static struct audio_driver dsound_audio_driver = {
.name = "dsound",
.descr = "DirectSound http://wikipedia.org/wiki/DirectSound",
- .options = dsound_options,
.init = dsound_audio_init,
.fini = dsound_audio_fini,
.pcm_ops = &dsound_pcm_ops,
.voice_size_out = sizeof (DSoundVoiceOut),
.voice_size_in = sizeof (DSoundVoiceIn)
};
+
+static void register_audio_dsound(void)
+{
+ audio_driver_register(&dsound_audio_driver);
+}
+type_init(register_audio_dsound);