[Spice-commits] Branch 'audio.2' - 4 commits - hw/hda-audio.c hw/hw.h hw/intel-hda.c savevm.c
Gerd Hoffmann
kraxel at kemper.freedesktop.org
Mon Nov 1 04:05:13 PDT 2010
hw/hda-audio.c | 109 +++++++++++++++++++++++++++++++++++++++++++++------------
hw/hw.h | 14 +++++++
hw/intel-hda.c | 17 +++-----
savevm.c | 21 ++++++++++
4 files changed, 129 insertions(+), 32 deletions(-)
New commits:
commit 2b7b1acbca4fd8a5464b7e42f3deb9a26aa026df
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Mon Nov 1 12:00:54 2010 +0100
hda-audio: add savevm, handle partial audio reads/writes, misc tweaks.
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 6f47429..a21f9a1 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -443,8 +443,8 @@ typedef struct HDAAudioStream HDAAudioStream;
struct HDAAudioStream {
HDAAudioState *state;
- bool output, running, wbuf;
const desc_node *node;
+ bool output, running;
uint32_t stream;
uint32_t channel;
uint32_t format;
@@ -456,11 +456,12 @@ struct HDAAudioStream {
SWVoiceOut *out;
} voice;
uint8_t buf[HDA_BUFFER_SIZE];
+ uint32_t bpos;
};
struct HDAAudioState {
HDACodecDevice hda;
- char name[32];
+ const char *name;
QEMUSoundCard card;
const desc_codec *desc;
@@ -475,20 +476,25 @@ static void hda_audio_input_cb(void *opaque, int avail)
{
HDAAudioStream *st = opaque;
int recv = 0;
+ int len;
bool rc;
while (avail - recv >= sizeof(st->buf)) {
- if (!st->wbuf) {
- AUD_read(st->voice.in, st->buf, sizeof(st->buf));
- recv += sizeof(st->buf);
- st->wbuf = true;
+ if (st->bpos != sizeof(st->buf)) {
+ len = AUD_read(st->voice.in, st->buf + st->bpos,
+ sizeof(st->buf) - st->bpos);
+ st->bpos += len;
+ recv += len;
+ if (st->bpos != sizeof(st->buf)) {
+ break;
+ }
}
rc = hda_codec_xfer(&st->state->hda, st->stream, false,
st->buf, sizeof(st->buf));
if (!rc) {
break;
}
- st->wbuf = false;
+ st->bpos = 0;
}
}
@@ -496,16 +502,25 @@ static void hda_audio_output_cb(void *opaque, int avail)
{
HDAAudioStream *st = opaque;
int sent = 0;
+ int len;
bool rc;
while (avail - sent >= sizeof(st->buf)) {
- rc = hda_codec_xfer(&st->state->hda, st->stream, true,
- st->buf, sizeof(st->buf));
- if (!rc) {
+ if (st->bpos == sizeof(st->buf)) {
+ rc = hda_codec_xfer(&st->state->hda, st->stream, true,
+ st->buf, sizeof(st->buf));
+ if (!rc) {
+ break;
+ }
+ st->bpos = 0;
+ }
+ len = AUD_write(st->voice.out, st->buf + st->bpos,
+ sizeof(st->buf) - st->bpos);
+ st->bpos += len;
+ sent += len;
+ if (st->bpos != sizeof(st->buf)) {
break;
}
- AUD_write(st->voice.out, st->buf, sizeof(st->buf));
- sent += sizeof(st->buf);
}
}
@@ -757,8 +772,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
uint32_t i, type;
a->desc = desc;
- snprintf(a->name, sizeof(a->name), "%s/%s",
- a->hda.qdev.info->name, a->desc->name);
+ a->name = a->hda.qdev.info->name;
dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
AUD_register_card("hda", &a->card);
@@ -779,6 +793,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
/* unmute output by default */
st->gain_left = QEMU_HDA_AMP_STEPS;
st->gain_right = QEMU_HDA_AMP_STEPS;
+ st->bpos = sizeof(st->buf);
st->output = true;
} else {
st->output = false;
@@ -795,8 +810,20 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
static int hda_audio_post_load(void *opaque, int version)
{
-// HDAAudioState* a = opaque;
+ HDAAudioState *a = opaque;
+ HDAAudioStream *st;
+ int i;
+ dprint(a, 1, "%s\n", __FUNCTION__);
+ for (i = 0; i < ARRAY_SIZE(a->st); i++) {
+ st = a->st + i;
+ if (st->node == NULL)
+ continue;
+ hda_codec_parse_fmt(st->format, &st->as);
+ hda_audio_setup(st);
+ hda_audio_set_amp(st);
+ hda_audio_set_running(st, a->running[st->stream]);
+ }
return 0;
}
@@ -804,6 +831,15 @@ static const VMStateDescription vmstate_hda_audio_stream = {
.name = "hda-audio-stream",
.version_id = 1,
.fields = (VMStateField []) {
+ VMSTATE_UINT32(stream, HDAAudioStream),
+ VMSTATE_UINT32(channel, HDAAudioStream),
+ VMSTATE_UINT32(format, HDAAudioStream),
+ VMSTATE_UINT32(gain_left, HDAAudioStream),
+ VMSTATE_UINT32(gain_right, HDAAudioStream),
+ VMSTATE_BOOL(mute_left, HDAAudioStream),
+ VMSTATE_BOOL(mute_right, HDAAudioStream),
+ VMSTATE_UINT32(bpos, HDAAudioStream),
+ VMSTATE_BUFFER(buf, HDAAudioStream),
VMSTATE_END_OF_LIST()
}
};
@@ -816,10 +852,16 @@ static const VMStateDescription vmstate_hda_audio = {
VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
vmstate_hda_audio_stream,
HDAAudioStream),
+ VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16),
VMSTATE_END_OF_LIST()
}
};
+static Property hda_audio_properties[] = {
+ DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static int hda_audio_init_output(HDACodecDevice *hda)
{
return hda_audio_init(hda, &output);
@@ -834,26 +876,22 @@ static HDACodecDeviceInfo hda_audio_info_output = {
.qdev.name = "hda-output",
.qdev.desc = "HDA Audio Codec, output-only",
.qdev.size = sizeof(HDAAudioState),
+ .qdev.vmsd = &vmstate_hda_audio,
+ .qdev.props = hda_audio_properties,
.init = hda_audio_init_output,
.command = hda_audio_command,
.stream = hda_audio_stream,
- .qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
- DEFINE_PROP_END_OF_LIST(),
- }
};
static HDACodecDeviceInfo hda_audio_info_duplex = {
.qdev.name = "hda-duplex",
.qdev.desc = "HDA Audio Codec, duplex",
.qdev.size = sizeof(HDAAudioState),
+ .qdev.vmsd = &vmstate_hda_audio,
+ .qdev.props = hda_audio_properties,
.init = hda_audio_init_duplex,
.command = hda_audio_command,
.stream = hda_audio_stream,
- .qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
- DEFINE_PROP_END_OF_LIST(),
- }
};
static void hda_audio_register(void)
commit 54b93d05d41c5dc1826c99944dabb9dae007db4b
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Mon Nov 1 11:58:49 2010 +0100
add VMSTATE_BOOL
diff --git a/hw/hw.h b/hw/hw.h
index 4405092..9d2cfc2 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -333,6 +333,8 @@ struct VMStateDescription {
const VMStateSubsection *subsections;
};
+extern const VMStateInfo vmstate_info_bool;
+
extern const VMStateInfo vmstate_info_int8;
extern const VMStateInfo vmstate_info_int16;
extern const VMStateInfo vmstate_info_int32;
@@ -602,6 +604,9 @@ extern const VMStateDescription vmstate_i2c_slave;
#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \
VMSTATE_STRUCT_POINTER_TEST(_field, _state, NULL, _vmsd, _type)
+#define VMSTATE_BOOL_V(_f, _s, _v) \
+ VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool)
+
#define VMSTATE_INT8_V(_f, _s, _v) \
VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t)
#define VMSTATE_INT16_V(_f, _s, _v) \
@@ -620,6 +625,9 @@ extern const VMStateDescription vmstate_i2c_slave;
#define VMSTATE_UINT64_V(_f, _s, _v) \
VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t)
+#define VMSTATE_BOOL(_f, _s) \
+ VMSTATE_BOOL_V(_f, _s, 0)
+
#define VMSTATE_INT8(_f, _s) \
VMSTATE_INT8_V(_f, _s, 0)
#define VMSTATE_INT16(_f, _s) \
@@ -674,6 +682,12 @@ extern const VMStateDescription vmstate_i2c_slave;
#define VMSTATE_PTIMER(_f, _s) \
VMSTATE_PTIMER_V(_f, _s, 0)
+#define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
+
+#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
+ VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
+
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
diff --git a/savevm.c b/savevm.c
index 2d8cadc..4e49765 100644
--- a/savevm.c
+++ b/savevm.c
@@ -675,6 +675,27 @@ uint64_t qemu_get_be64(QEMUFile *f)
return v;
}
+/* bool */
+
+static int get_bool(QEMUFile *f, void *pv, size_t size)
+{
+ bool *v = pv;
+ *v = qemu_get_byte(f);
+ return 0;
+}
+
+static void put_bool(QEMUFile *f, void *pv, size_t size)
+{
+ bool *v = pv;
+ qemu_put_byte(f, *v);
+}
+
+const VMStateInfo vmstate_info_bool = {
+ .name = "bool",
+ .get = get_bool,
+ .put = put_bool,
+};
+
/* 8 bit int */
static int get_int8(QEMUFile *f, void *pv, size_t size)
commit f79dd26ee53b9995cac5edf1b60d47c33f5d0b0a
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Mon Nov 1 10:29:18 2010 +0100
intel-hda: fix wall clock to use qemu_get_clock()
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 72d91d5..ccb059d 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -19,6 +19,7 @@
#include "hw.h"
#include "pci.h"
+#include "qemu-timer.h"
#include "audiodev.h"
#include "intel-hda.h"
#include "intel-hda-defs.h"
@@ -165,7 +166,7 @@ struct IntelHDAState {
/* state */
int mmio_addr;
uint32_t rirb_count;
- uint64_t wall_base_usecs;
+ int64_t wall_base_ns;
/* debug logging */
const IntelHDAReg *last_reg;
@@ -508,12 +509,10 @@ static void intel_hda_set_int_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint
static void intel_hda_get_wall_clk(IntelHDAState *d, const IntelHDAReg *reg)
{
- qemu_timeval tv;
- uint64_t usecs;
+ int64_t ns;
- qemu_gettimeofday(&tv);
- usecs = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
- d->wall_clk = (uint32_t)((usecs - d->wall_base_usecs) * 24); /* 24 MHz */
+ ns = qemu_get_clock_ns(vm_clock) - d->wall_base_ns;
+ d->wall_clk = (uint32_t)(ns * 24 / 1000); /* 24 MHz */
}
static void intel_hda_set_corb_wp(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
@@ -1096,11 +1095,9 @@ static void intel_hda_reset(DeviceState *dev)
IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev);
DeviceState *qdev;
HDACodecDevice *cdev;
- qemu_timeval tv;
intel_hda_regs_reset(d);
- qemu_gettimeofday(&tv);
- d->wall_base_usecs = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+ d->wall_base_ns = qemu_get_clock(vm_clock);
/* reset codecs */
QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
@@ -1209,7 +1206,7 @@ static const VMStateDescription vmstate_intel_hda = {
/* additional state info */
VMSTATE_UINT32(rirb_count, IntelHDAState),
- VMSTATE_UINT64(wall_base_usecs, IntelHDAState),
+ VMSTATE_INT64(wall_base_ns, IntelHDAState),
VMSTATE_END_OF_LIST()
}
commit ce51f3f7b78910af082df6d5d4ec73c06633603c
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Mon Nov 1 10:08:22 2010 +0100
hda-audio: savevm support [incomplete]
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index d99bdd7..6f47429 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -793,6 +793,33 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
return 0;
}
+static int hda_audio_post_load(void *opaque, int version)
+{
+// HDAAudioState* a = opaque;
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_hda_audio_stream = {
+ .name = "hda-audio-stream",
+ .version_id = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_hda_audio = {
+ .name = "hda-audio",
+ .version_id = 1,
+ .post_load = hda_audio_post_load,
+ .fields = (VMStateField []) {
+ VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
+ vmstate_hda_audio_stream,
+ HDAAudioStream),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int hda_audio_init_output(HDACodecDevice *hda)
{
return hda_audio_init(hda, &output);
More information about the Spice-commits
mailing list