From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, peter.crosthwaite@xilinx.com,
mark.burton@greensocs.com, real@ispras.ru, batuzovk@ispras.ru,
pavel.dovgaluk@ispras.ru, pbonzini@redhat.com,
fred.konrad@greensocs.com
Subject: [Qemu-devel] [RFC PATCH v2 43/49] replay: audio data record/replay
Date: Thu, 17 Jul 2014 15:06:00 +0400 [thread overview]
Message-ID: <20140717110559.8352.32919.stgit@PASHA-ISP> (raw)
In-Reply-To: <20140717110153.8352.80175.stgit@PASHA-ISP>
This patch adds deterministic replay for audio adapter. Replay module saves
data from the microphone and "end-of-playback" events.
Support of audio record and replay is implemented only for Win32 hosts.
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
audio/audio.c | 14 ++-
audio/audio_win_int.h | 3 +
audio/winwaveaudio.c | 167 ++++++++++++++++++++++++++--------
replay/Makefile.objs | 1
replay/replay-audio.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++
replay/replay-internal.c | 4 +
replay/replay-internal.h | 14 +++
replay/replay.h | 20 ++++
8 files changed, 408 insertions(+), 43 deletions(-)
create mode 100755 replay/replay-audio.c
diff --git a/audio/audio.c b/audio/audio.c
index 9d018e9..7b272b7 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -26,6 +26,7 @@
#include "monitor/monitor.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
+#include "replay/replay.h"
#define AUDIO_CAP "audio"
#include "audio_int.h"
@@ -1201,7 +1202,9 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)
if (!hw->enabled) {
hw->enabled = 1;
if (s->vm_running) {
- hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
+ hw->pcm_ops->ctl_out(hw, VOICE_ENABLE,
+ replay_mode == REPLAY_NONE
+ ? conf.try_poll_out : 0);
audio_reset_timer (s);
}
}
@@ -1763,11 +1766,13 @@ static void audio_vm_change_state_handler (void *opaque, int running,
s->vm_running = running;
while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
- hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out);
+ hwo->pcm_ops->ctl_out(hwo, op, replay_mode == REPLAY_NONE
+ ? conf.try_poll_out : 0);
}
while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
- hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
+ hwi->pcm_ops->ctl_in(hwi, op, replay_mode == REPLAY_NONE
+ ? conf.try_poll_in : 0);
}
audio_reset_timer (s);
}
@@ -1810,9 +1815,10 @@ static void audio_atexit (void)
static const VMStateDescription vmstate_audio = {
.name = "audio",
- .version_id = 1,
+ .version_id = 2,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
+ VMSTATE_TIMER_V(ts, AudioState, 2),
VMSTATE_END_OF_LIST()
}
};
diff --git a/audio/audio_win_int.h b/audio/audio_win_int.h
index fa5b3cb..0525ae6 100644
--- a/audio/audio_win_int.h
+++ b/audio/audio_win_int.h
@@ -7,4 +7,7 @@ int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as);
+void winwave_callback_out_impl(void *dwInstance, WAVEHDR *h);
+void winwave_callback_in_impl(void *dwInstance, WAVEHDR *h);
+
#endif /* AUDIO_WIN_INT_H */
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
index 8dbd145..f7325a8 100644
--- a/audio/winwaveaudio.c
+++ b/audio/winwaveaudio.c
@@ -2,7 +2,9 @@
#include "qemu-common.h"
#include "sysemu/sysemu.h"
+#include "migration/vmstate.h"
#include "audio.h"
+#include "replay/replay.h"
#define AUDIO_CAP "winwave"
#include "audio_int.h"
@@ -47,6 +49,7 @@ typedef struct {
int paused;
int rpos;
int avail;
+ int non_added;
CRITICAL_SECTION crit_sect;
} WaveVoiceIn;
@@ -124,6 +127,24 @@ static void winwave_anal_close_out (WaveVoiceOut *wave)
wave->hwo = NULL;
}
+void winwave_callback_out_impl(void *dwInstance, WAVEHDR *h)
+{
+ WaveVoiceOut *wave = (WaveVoiceOut *)dwInstance;
+ if (!h->dwUser) {
+ h->dwUser = 1;
+ EnterCriticalSection(&wave->crit_sect);
+ {
+ wave->avail += conf.dac_samples;
+ }
+ LeaveCriticalSection(&wave->crit_sect);
+ if (wave->hw.poll_mode) {
+ if (!SetEvent(wave->event)) {
+ dolog("DAC SetEvent failed %lx\n", GetLastError());
+ }
+ }
+ }
+}
+
static void CALLBACK winwave_callback_out (
HWAVEOUT hwo,
UINT msg,
@@ -132,24 +153,16 @@ static void CALLBACK winwave_callback_out (
DWORD_PTR dwParam2
)
{
- WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
-
switch (msg) {
case WOM_DONE:
{
- WAVEHDR *h = (WAVEHDR *) dwParam1;
- if (!h->dwUser) {
- h->dwUser = 1;
- EnterCriticalSection (&wave->crit_sect);
- {
- wave->avail += conf.dac_samples;
- }
- LeaveCriticalSection (&wave->crit_sect);
- if (wave->hw.poll_mode) {
- if (!SetEvent (wave->event)) {
- dolog ("DAC SetEvent failed %lx\n", GetLastError ());
- }
- }
+ if (replay_mode == REPLAY_SAVE) {
+ replay_sound_out_event((WAVEHDR *)dwParam1);
+ } else if (replay_mode == REPLAY_PLAY) {
+ /* Do nothing */
+ } else {
+ winwave_callback_out_impl((void*)dwInstance,
+ (WAVEHDR *)dwParam1);
}
}
break;
@@ -163,6 +176,21 @@ static void CALLBACK winwave_callback_out (
}
}
+static const VMStateDescription vmstate_audio_out = {
+ .name = "audio_out",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32(enabled, HWVoiceOut),
+ VMSTATE_INT32(poll_mode, HWVoiceOut),
+ VMSTATE_INT32(pending_disable, HWVoiceOut),
+ VMSTATE_INT32(rpos, HWVoiceOut),
+ VMSTATE_UINT64(ts_helper, HWVoiceOut),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
{
int i;
@@ -173,6 +201,8 @@ static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
wave = (WaveVoiceOut *) hw;
+ vmstate_register(NULL, 0, &vmstate_audio_out, hw);
+
InitializeCriticalSection (&wave->crit_sect);
err = waveformat_from_audio_settings (&wfx, as);
@@ -219,6 +249,10 @@ static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
}
}
+ if (replay_mode != REPLAY_NONE) {
+ replay_init_sound_out(wave, wave->hdrs, conf.dac_headers);
+ }
+
return 0;
err4:
@@ -262,10 +296,20 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
WAVEHDR *h = &wave->hdrs[wave->curhdr];
h->dwUser = 0;
- mr = waveOutWrite (wave->hwo, h, sizeof (*h));
- if (mr != MMSYSERR_NOERROR) {
- winwave_logerr (mr, "waveOutWrite(%d)", wave->curhdr);
- break;
+ /* Only events will be simulated in REPLAY_PLAY mode,
+ no sounds will be emitted */
+ if (replay_mode != REPLAY_PLAY) {
+ mr = waveOutWrite (wave->hwo, h, sizeof (*h));
+ if (mr != MMSYSERR_NOERROR) {
+ winwave_logerr (mr, "waveOutWrite(%d)", wave->curhdr);
+ break;
+ }
+ } else {
+ /* This header will be passed to callback function,
+ when event will be read in the log */
+ if (replay_sound_out_event(h)) {
+ break;
+ }
}
wave->pending -= conf.dac_samples;
@@ -382,6 +426,26 @@ static void winwave_anal_close_in (WaveVoiceIn *wave)
wave->hwi = NULL;
}
+void winwave_callback_in_impl(void *dwInstance, WAVEHDR *h)
+{
+ WaveVoiceIn *wave = (WaveVoiceIn *)dwInstance;
+
+ if (!h->dwUser) {
+ h->dwUser = 1;
+ EnterCriticalSection(&wave->crit_sect);
+ {
+ wave->avail += conf.adc_samples;
+ }
+ LeaveCriticalSection(&wave->crit_sect);
+
+ if (wave->hw.poll_mode) {
+ if (!SetEvent(wave->event)) {
+ dolog("ADC SetEvent failed %lx\n", GetLastError());
+ }
+ }
+ }
+}
+
static void CALLBACK winwave_callback_in (
HWAVEIN *hwi,
UINT msg,
@@ -390,24 +454,16 @@ static void CALLBACK winwave_callback_in (
DWORD_PTR dwParam2
)
{
- WaveVoiceIn *wave = (WaveVoiceIn *) dwInstance;
-
switch (msg) {
case WIM_DATA:
{
- WAVEHDR *h = (WAVEHDR *) dwParam1;
- if (!h->dwUser) {
- h->dwUser = 1;
- EnterCriticalSection (&wave->crit_sect);
- {
- wave->avail += conf.adc_samples;
- }
- LeaveCriticalSection (&wave->crit_sect);
- if (wave->hw.poll_mode) {
- if (!SetEvent (wave->event)) {
- dolog ("ADC SetEvent failed %lx\n", GetLastError ());
- }
- }
+ if (replay_mode == REPLAY_SAVE) {
+ replay_sound_in_event((WAVEHDR *)dwParam1);
+ } else if (replay_mode == REPLAY_PLAY) {
+ /* Do nothing */
+ } else {
+ winwave_callback_in_impl((void*)dwInstance,
+ (WAVEHDR *)dwParam1);
}
}
break;
@@ -421,9 +477,10 @@ static void CALLBACK winwave_callback_in (
}
}
-static void winwave_add_buffers (WaveVoiceIn *wave, int samples)
+static int winwave_add_buffers (WaveVoiceIn *wave, int samples)
{
int doreset;
+ int added = 0;
doreset = wave->hw.poll_mode && (samples >= conf.adc_samples);
if (doreset && !ResetEvent (wave->event)) {
@@ -435,15 +492,39 @@ static void winwave_add_buffers (WaveVoiceIn *wave, int samples)
WAVEHDR *h = &wave->hdrs[wave->curhdr];
h->dwUser = 0;
- mr = waveInAddBuffer (wave->hwi, h, sizeof (*h));
- if (mr != MMSYSERR_NOERROR) {
- winwave_logerr (mr, "waveInAddBuffer(%d)", wave->curhdr);
+ /* Add buffer to replay queue in replay mode - it will be
+ loaded from log file. */
+ if (replay_mode != REPLAY_PLAY) {
+ mr = waveInAddBuffer(wave->hwi, h, sizeof (*h));
+ if (mr != MMSYSERR_NOERROR) {
+ winwave_logerr(mr, "waveInAddBuffer(%d)", wave->curhdr);
+ }
+ } else {
+ replay_sound_in_event(h);
}
wave->curhdr = (wave->curhdr + 1) % conf.adc_headers;
samples -= conf.adc_samples;
+ added += conf.adc_samples;
}
+
+ return added;
}
+static const VMStateDescription vmstate_audio_in = {
+ .name = "audio_in",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32(enabled, HWVoiceIn),
+ VMSTATE_INT32(poll_mode, HWVoiceIn),
+ VMSTATE_INT32(wpos, HWVoiceIn),
+ VMSTATE_INT32(total_samples_captured, HWVoiceIn),
+ VMSTATE_UINT64(ts_helper, HWVoiceIn),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as)
{
int i;
@@ -454,6 +535,8 @@ static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as)
wave = (WaveVoiceIn *) hw;
+ vmstate_register(NULL, 0, &vmstate_audio_in, hw);
+
InitializeCriticalSection (&wave->crit_sect);
err = waveformat_from_audio_settings (&wfx, as);
@@ -478,6 +561,7 @@ static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as)
audio_pcm_init_info (&hw->info, as);
hw->samples = conf.adc_samples * conf.adc_headers;
wave->avail = 0;
+ wave->non_added = 0;
wave->pcm_buf = audio_calloc (AUDIO_FUNC, conf.adc_samples,
conf.adc_headers << hw->info.shift);
@@ -500,6 +584,10 @@ static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as)
}
}
+ if (replay_mode != REPLAY_NONE) {
+ replay_init_sound_in(wave, wave->hdrs, conf.adc_headers);
+ }
+
wave->paused = 1;
winwave_add_buffers (wave, hw->samples);
return 0;
@@ -570,6 +658,7 @@ static int winwave_run_in (HWVoiceIn *hw)
LeaveCriticalSection (&wave->crit_sect);
ret = decr;
+ wave->non_added += ret;
while (decr) {
int left = hw->samples - hw->wpos;
int conv = audio_MIN (left, decr);
@@ -582,7 +671,7 @@ static int winwave_run_in (HWVoiceIn *hw)
decr -= conv;
}
- winwave_add_buffers (wave, ret);
+ wave->non_added -= winwave_add_buffers(wave, wave->non_added);
return ret;
}
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 43bafbb..1d57e71 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -4,3 +4,4 @@ obj-y += replay-events.o
obj-y += replay-time.o
obj-y += replay-input.o
obj-y += replay-net.o
+obj-y += replay-audio.o
diff --git a/replay/replay-audio.c b/replay/replay-audio.c
new file mode 100755
index 0000000..41e28c1
--- /dev/null
+++ b/replay/replay-audio.c
@@ -0,0 +1,228 @@
+/*
+ * replay-audio.c
+ *
+ * Copyright (c) 2010-2014 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "exec/cpu-common.h"
+#include "replay.h"
+#include "replay-internal.h"
+#ifdef _WIN32
+struct audsettings;
+#include "audio/audio_win_int.h"
+#endif
+
+/* Sound card state */
+typedef struct {
+ void *instance;
+ const int event_id;
+#ifdef _WIN32
+ WAVEHDR *queue;
+#endif
+ /*! Maximum size of the queue */
+ int size;
+ /*! Current size of the queue */
+ sig_atomic_t cur_size;
+ unsigned int head, tail;
+} SoundQueue;
+
+
+static SoundQueue sound_in = {
+ .event_id = EVENT_SOUND_IN
+ },
+ sound_out = {
+ .event_id = EVENT_SOUND_OUT,
+ };
+
+#ifdef _WIN32
+/*! Spinlock for sound events processing. */
+static spinlock_t sound_lock = SPIN_LOCK_UNLOCKED;
+#endif
+
+/*****************************************************************************
+ * Sound queue functions *
+ *****************************************************************************/
+
+/* callback functions */
+#ifdef _WIN32
+
+void replay_init_sound_in(void *instance, WAVEHDR *hdrs, int sz)
+{
+ sound_in.instance = instance;
+ sound_in.queue = hdrs;
+ sound_in.size = sz;
+ sound_in.head = 0;
+ sound_in.tail = 0;
+ sound_in.cur_size = 0;
+}
+
+void replay_init_sound_out(void *instance, WAVEHDR *hdrs, int sz)
+{
+ sound_out.instance = instance;
+ sound_out.queue = hdrs;
+ sound_out.size = sz;
+ sound_out.head = 0;
+ sound_out.tail = 0;
+ sound_out.cur_size = 0;
+}
+
+static int sound_queue_add(SoundQueue *q, WAVEHDR *hdr)
+{
+ if (q->queue + q->tail != hdr) {
+ /* state was loaded and we need to reset the queue */
+ if (q->cur_size == 0) {
+ q->head = q->tail = hdr - q->queue;
+ } else {
+ fprintf(stderr, "Replay: Sound queue error\n");
+ exit(1);
+ }
+ }
+
+ if (q->cur_size == q->size) {
+ if (replay_mode == REPLAY_PLAY) {
+ return 1;
+ }
+
+ fprintf(stderr, "Replay: Sound queue overflow\n");
+ exit(1);
+ }
+
+ q->tail = (q->tail + 1) % q->size;
+ ++q->cur_size;
+
+ return 0;
+}
+
+void replay_save_sound_out(void)
+{
+ spin_lock(&sound_lock);
+ while (sound_out.cur_size != 0) {
+ /* put the message ID */
+ replay_put_event(sound_out.event_id);
+ /* save the buffer size */
+ replay_put_dword(sound_out.queue[sound_out.head].dwBytesRecorded);
+ /* perform winwave-specific actions */
+ winwave_callback_out_impl(sound_out.instance,
+ &sound_out.queue[sound_out.head]);
+ /* goto the next buffer */
+ sound_out.head = (sound_out.head + 1) % sound_out.size;
+ --sound_out.cur_size;
+ }
+ spin_unlock(&sound_lock);
+}
+
+void replay_save_sound_in(void)
+{
+ spin_lock(&sound_lock);
+ while (sound_in.cur_size != 0) {
+ /* put the message ID */
+ replay_put_event(sound_in.event_id);
+ /* save the buffer */
+ replay_put_array((const uint8_t *)sound_in.queue[sound_in.head].lpData,
+ sound_in.queue[sound_in.head].dwBytesRecorded);
+ /* perform winwave-specific actions */
+ winwave_callback_in_impl(sound_in.instance,
+ &sound_in.queue[sound_in.head]);
+ /* goto the next buffer */
+ sound_in.head = (sound_in.head + 1) % sound_in.size;
+ --sound_in.cur_size;
+ }
+ spin_unlock(&sound_lock);
+}
+
+void replay_read_sound_out(void)
+{
+ if (sound_out.cur_size == 0) {
+ fprintf(stderr, "Replay: Sound queue underflow\n");
+ exit(1);
+ }
+
+ /* get the buffer size */
+ sound_out.queue[sound_out.head].dwBytesRecorded = replay_get_dword();
+
+ replay_check_error();
+ replay_has_unread_data = 0;
+
+ /* perform winwave-specific actions */
+ winwave_callback_out_impl(sound_out.instance, &sound_out.queue[sound_out.head]);
+ sound_out.head = (sound_out.head + 1) % sound_out.size;
+ --sound_out.cur_size;
+}
+
+void replay_read_sound_in(void)
+{
+ if (sound_in.cur_size == 0) {
+ fprintf(stderr, "Replay: Sound queue underflow\n");
+ exit(1);
+ }
+
+ /* get the buffer size */
+ size_t size;
+ replay_get_array((uint8_t *)sound_in.queue[sound_in.head].lpData, &size);
+ sound_in.queue[sound_in.head].dwBytesRecorded = (unsigned int)size;
+
+ replay_check_error();
+ replay_has_unread_data = 0;
+
+ /* perform winwave-specific actions */
+ winwave_callback_in_impl(sound_in.instance, &sound_in.queue[sound_in.head]);
+ sound_in.head = (sound_in.head + 1) % sound_in.size;
+ --sound_in.cur_size;
+}
+
+void replay_sound_in_event(WAVEHDR *hdr)
+{
+ spin_lock(&sound_lock);
+ if (sound_queue_add(&sound_in, hdr)) {
+ fprintf(stderr, "Replay: Input sound buffer overflow\n");
+ exit(1);
+ }
+ spin_unlock(&sound_lock);
+}
+
+int replay_sound_out_event(WAVEHDR *hdr)
+{
+ spin_lock(&sound_lock);
+ int result = sound_queue_add(&sound_out, hdr);
+ spin_unlock(&sound_lock);
+
+ return result;
+}
+#endif
+
+bool replay_has_sound_events(void)
+{
+ return sound_in.cur_size || sound_out.cur_size;
+}
+
+void replay_sound_flush_queue(void)
+{
+#ifdef _WIN32
+ spin_lock(&sound_lock);
+ while (sound_out.cur_size != 0) {
+ /* perform winwave-specific actions */
+ winwave_callback_out_impl(sound_out.instance,
+ &sound_out.queue[sound_out.head]);
+ /* goto the next buffer */
+ sound_out.head = (sound_out.head + 1) % sound_out.size;
+ --sound_out.cur_size;
+ }
+ while (sound_in.cur_size != 0)
+ {
+ /* perform winwave-specific actions */
+ winwave_callback_in_impl(sound_in.instance,
+ &sound_in.queue[sound_in.head]);
+ /* goto the next buffer */
+ sound_in.head = (sound_in.head + 1) % sound_in.size;
+ --sound_in.cur_size;
+ }
+ spin_unlock(&sound_lock);
+#endif
+}
+
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index f416317..fab9c0c 100755
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -151,5 +151,9 @@ void replay_save_instructions(void)
replay_state.current_step += first_cpu->instructions_count;
first_cpu->instructions_count = 0;
}
+#ifdef _WIN32
+ replay_save_sound_in();
+ replay_save_sound_out();
+#endif
}
}
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 254a386..0f001f4 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -21,6 +21,10 @@
#define EVENT_TIME_T 1
/* for tm event */
#define EVENT_TM 2
+/* for outgoing sound event */
+#define EVENT_SOUND_OUT 7
+/* for incoming sound event */
+#define EVENT_SOUND_IN 8
/* for software interrupt */
#define EVENT_INTERRUPT 15
/* for shutdown request */
@@ -169,4 +173,14 @@ void *replay_net_read_packet(void);
to the net queue. */
void replay_net_send_packet(void *opaque);
+/* Sound events */
+
+/*! Returns true, when there are any pending sound events. */
+bool replay_has_sound_events(void);
+void replay_save_sound_out(void);
+void replay_save_sound_in(void);
+void replay_read_sound_out(void);
+void replay_read_sound_in(void);
+void replay_sound_flush_queue(void);
+
#endif
diff --git a/replay/replay.h b/replay/replay.h
index f654673..700b19a 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -15,6 +15,10 @@
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
+#ifdef _WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#endif
struct QemuOpts;
struct InputEvent;
@@ -128,5 +132,21 @@ void replay_add_network_client(struct NetClientState *nc);
void replay_save_net_packet(struct NetClientState *nc, const uint8_t *buf,
size_t size);
+/* Audio */
+
+#ifdef _WIN32
+/*! Microphone event. */
+void replay_sound_in_event(WAVEHDR *hdr);
+/*! Adds header to the queue.
+ In record mode this header is queued for saving into log.
+ In replay mode this header is queued for reading from log.
+ Returns 1 in replay mode when queue is full.
+ Otherwise returns 0. */
+int replay_sound_out_event(WAVEHDR *hdr);
+/*! Initializes queue for sound input. */
+void replay_init_sound_in(void *instance, WAVEHDR *hdrs, int sz);
+/*! Initializes queue for sound output. */
+void replay_init_sound_out(void *instance, WAVEHDR *hdrs, int sz);
+#endif
#endif
next prev parent reply other threads:[~2014-07-17 11:06 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-17 11:01 [Qemu-devel] [RFC PATCH v2 00/49] Series short description Pavel Dovgalyuk
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 01/49] acpi: accurate overflow check Pavel Dovgalyuk
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 02/49] integratorcp: adding vmstate for save/restore Pavel Dovgalyuk
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 03/49] pcspk: " Pavel Dovgalyuk
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 04/49] fdc: " Pavel Dovgalyuk
2014-07-28 9:47 ` Paolo Bonzini
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 05/49] parallel: " Pavel Dovgalyuk
2014-07-28 10:02 ` Paolo Bonzini
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 06/49] serial: fixing " Pavel Dovgalyuk
2014-07-28 9:58 ` Paolo Bonzini
2014-07-30 7:01 ` Pavel Dovgaluk
[not found] ` <19697.8771281012$1406703748@news.gmane.org>
2014-07-30 9:19 ` Paolo Bonzini
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 07/49] kvmapic: fixing loading vmstate Pavel Dovgalyuk
2014-07-28 8:49 ` Paolo Bonzini
2014-07-29 12:03 ` Pavel Dovgaluk
2014-07-29 12:16 ` Paolo Bonzini
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 08/49] hpet: fixing saving and loading process Pavel Dovgalyuk
2014-07-28 8:33 ` Paolo Bonzini
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 09/49] pckbd: adding new fields to vmstate Pavel Dovgalyuk
2014-07-28 9:36 ` Paolo Bonzini
2014-07-17 11:02 ` [Qemu-devel] [RFC PATCH v2 10/49] rtl8139: " Pavel Dovgalyuk
2014-07-28 9:41 ` Paolo Bonzini
2014-07-28 9:54 ` Pavel Dovgaluk
[not found] ` <37740.9009532586$1406541296@news.gmane.org>
2014-07-28 10:12 ` Paolo Bonzini
2014-07-30 8:24 ` Pavel Dovgaluk
2014-07-30 9:26 ` Paolo Bonzini
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 11/49] piix: do not raise irq while loading vmstate Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 12/49] mc146818rtc: add missed field to vmstate Pavel Dovgalyuk
2014-07-28 9:42 ` Paolo Bonzini
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 13/49] pl031: " Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 14/49] ide pci: reset status field before loading the vmstate Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 15/49] softmmu: fixing usage of cpu_st/ld* from helpers Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 16/49] target: save cpu state fields Pavel Dovgalyuk
2014-07-31 6:48 ` Andreas Färber
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 17/49] target-i386: update fp status fix Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 18/49] migration: add vmstate for int8 and char arrays Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 19/49] replay: global variables and function stubs Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 20/49] block: add suffix parameter to bdrv_open functions Pavel Dovgalyuk
2014-07-17 11:03 ` [Qemu-devel] [RFC PATCH v2 21/49] sysemu: system functions for replay Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 22/49] replay: internal functions for replay log Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 23/49] cpu: invent instruction count for accurate replay Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 24/49] target-arm: instructions counting code for replay Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 25/49] target-i386: " Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 26/49] replay: interrupts and exceptions Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 27/49] vga: do not use virtual clock for blinking cursor Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 28/49] replay: asynchronous events infrastructure Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 29/49] replay: recording and replaying clock ticks Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 30/49] replay: recording and replaying different timers Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 31/49] replay: shutdown event Pavel Dovgalyuk
2014-07-17 11:04 ` [Qemu-devel] [RFC PATCH v2 32/49] replay: checkpoints Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 33/49] replay: bottom halves Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 34/49] replay: replay aio requests Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 35/49] replay: thread pool Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 36/49] pl031: vmstate in replay mode Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 37/49] replay: initialization and deinitialization Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 38/49] replay: command line options Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 39/49] replay: snapshotting the virtual machine Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 40/49] replay: recording of the user input Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 41/49] tap-win32: destroy the thread at exit Pavel Dovgalyuk
2014-07-17 11:05 ` [Qemu-devel] [RFC PATCH v2 42/49] replay: network packets record/replay Pavel Dovgalyuk
2014-07-17 11:06 ` Pavel Dovgalyuk [this message]
2014-07-17 11:06 ` [Qemu-devel] [RFC PATCH v2 44/49] replay: serial port Pavel Dovgalyuk
2014-07-17 11:06 ` [Qemu-devel] [RFC PATCH v2 45/49] replay: USB passthrough Pavel Dovgalyuk
2014-07-17 11:06 ` [Qemu-devel] [RFC PATCH v2 46/49] replay: replay_info command Pavel Dovgalyuk
2014-07-18 15:55 ` Eric Blake
2014-07-18 15:56 ` Eric Blake
2014-07-17 11:06 ` [Qemu-devel] [RFC PATCH v2 47/49] replay: replay_break command Pavel Dovgalyuk
2014-07-18 15:58 ` Eric Blake
2014-07-17 11:06 ` [Qemu-devel] [RFC PATCH v2 48/49] replay: replay_seek_step command Pavel Dovgalyuk
2014-07-18 15:59 ` Eric Blake
2014-07-17 11:06 ` [Qemu-devel] [RFC PATCH v2 49/49] gdbstub: reverse debugging Pavel Dovgalyuk
2014-07-18 8:10 ` [Qemu-devel] [RFC PATCH v2 00/49] Series short description Frederic Konrad
2014-07-24 17:48 ` Paolo Bonzini
2014-07-28 7:50 ` Pavel Dovgaluk
[not found] ` <2596.37912172384$1406533875@news.gmane.org>
2014-07-28 10:12 ` Paolo Bonzini
2014-07-30 7:44 ` Pavel Dovgaluk
2014-07-30 9:25 ` Paolo Bonzini
2014-07-30 13:19 ` Frederic Konrad
2014-07-30 13:35 ` Paolo Bonzini
2014-07-30 14:51 ` Frederic Konrad
2014-07-31 13:05 ` Frederic Konrad
2014-07-31 14:18 ` Paolo Bonzini
2014-07-31 5:44 ` Pavel Dovgaluk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140717110559.8352.32919.stgit@PASHA-ISP \
--to=pavel.dovgaluk@ispras.ru \
--cc=batuzovk@ispras.ru \
--cc=fred.konrad@greensocs.com \
--cc=mark.burton@greensocs.com \
--cc=pbonzini@redhat.com \
--cc=peter.crosthwaite@xilinx.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=real@ispras.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.