aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/audio.c11
-rw-r--r--audio/audio.h5
-rw-r--r--audio/mixeng.c32
-rw-r--r--audio/sdlaudio.c48
4 files changed, 93 insertions, 3 deletions
diff --git a/audio/audio.c b/audio/audio.c
index c845a44f0a..c8898d8422 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -28,6 +28,7 @@
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
+#include "sysemu/replay.h"
#define AUDIO_CAP "audio"
#include "audio_int.h"
@@ -1112,7 +1113,7 @@ static int audio_is_timer_needed (void)
static void audio_reset_timer (AudioState *s)
{
if (audio_is_timer_needed ()) {
- timer_mod (s->ts,
+ timer_mod_anticipate_ns(s->ts,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + conf.period.ticks);
}
else {
@@ -1387,6 +1388,7 @@ static void audio_run_out (AudioState *s)
prev_rpos = hw->rpos;
played = hw->pcm_ops->run_out (hw, live);
+ replay_audio_out(&played);
if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
hw->rpos, hw->samples, played);
@@ -1450,9 +1452,12 @@ static void audio_run_in (AudioState *s)
while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
SWVoiceIn *sw;
- int captured, min;
+ int captured = 0, min;
- captured = hw->pcm_ops->run_in (hw);
+ if (replay_mode != REPLAY_MODE_PLAY) {
+ captured = hw->pcm_ops->run_in(hw);
+ }
+ replay_audio_in(&captured, hw->conv_buf, &hw->wpos, hw->samples);
min = audio_pcm_hw_find_min_in (hw);
hw->total_samples_captured += captured - min;
diff --git a/audio/audio.h b/audio/audio.h
index c3c51988f5..f4339a185e 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -166,4 +166,9 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
bool audio_is_cleaning_up(void);
void audio_cleanup(void);
+void audio_sample_to_uint64(void *samples, int pos,
+ uint64_t *left, uint64_t *right);
+void audio_sample_from_uint64(void *samples, int pos,
+ uint64_t left, uint64_t right);
+
#endif /* QEMU_AUDIO_H */
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 66c0328d42..0bf9b5360f 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/bswap.h"
+#include "qemu/error-report.h"
#include "audio.h"
#define AUDIO_CAP "mixeng"
@@ -267,6 +268,37 @@ f_sample *mixeng_clip[2][2][2][3] = {
}
};
+
+void audio_sample_to_uint64(void *samples, int pos,
+ uint64_t *left, uint64_t *right)
+{
+ struct st_sample *sample = samples;
+ sample += pos;
+#ifdef FLOAT_MIXENG
+ error_report(
+ "Coreaudio and floating point samples are not supported by replay yet");
+ abort();
+#else
+ *left = sample->l;
+ *right = sample->r;
+#endif
+}
+
+void audio_sample_from_uint64(void *samples, int pos,
+ uint64_t left, uint64_t right)
+{
+ struct st_sample *sample = samples;
+ sample += pos;
+#ifdef FLOAT_MIXENG
+ error_report(
+ "Coreaudio and floating point samples are not supported by replay yet");
+ abort();
+#else
+ sample->l = left;
+ sample->r = right;
+#endif
+}
+
/*
* August 21, 1998
* Copyright 1998 Fabrice Bellard.
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index db69fe1416..e8d91d22af 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -38,10 +38,14 @@
#define AUDIO_CAP "sdl"
#include "audio_int.h"
+#define USE_SEMAPHORE (SDL_MAJOR_VERSION < 2)
+
typedef struct SDLVoiceOut {
HWVoiceOut hw;
int live;
+#if USE_SEMAPHORE
int rpos;
+#endif
int decr;
} SDLVoiceOut;
@@ -53,8 +57,10 @@ static struct {
static struct SDLAudioState {
int exit;
+#if USE_SEMAPHORE
SDL_mutex *mutex;
SDL_sem *sem;
+#endif
int initialized;
bool driver_created;
} glob_sdl;
@@ -73,31 +79,45 @@ static void GCC_FMT_ATTR (1, 2) sdl_logerr (const char *fmt, ...)
static int sdl_lock (SDLAudioState *s, const char *forfn)
{
+#if USE_SEMAPHORE
if (SDL_LockMutex (s->mutex)) {
sdl_logerr ("SDL_LockMutex for %s failed\n", forfn);
return -1;
}
+#else
+ SDL_LockAudio();
+#endif
+
return 0;
}
static int sdl_unlock (SDLAudioState *s, const char *forfn)
{
+#if USE_SEMAPHORE
if (SDL_UnlockMutex (s->mutex)) {
sdl_logerr ("SDL_UnlockMutex for %s failed\n", forfn);
return -1;
}
+#else
+ SDL_UnlockAudio();
+#endif
+
return 0;
}
static int sdl_post (SDLAudioState *s, const char *forfn)
{
+#if USE_SEMAPHORE
if (SDL_SemPost (s->sem)) {
sdl_logerr ("SDL_SemPost for %s failed\n", forfn);
return -1;
}
+#endif
+
return 0;
}
+#if USE_SEMAPHORE
static int sdl_wait (SDLAudioState *s, const char *forfn)
{
if (SDL_SemWait (s->sem)) {
@@ -106,6 +126,7 @@ static int sdl_wait (SDLAudioState *s, const char *forfn)
}
return 0;
}
+#endif
static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)
{
@@ -246,6 +267,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
int to_mix, decr;
/* dolog ("in callback samples=%d\n", samples); */
+#if USE_SEMAPHORE
sdl_wait (s, "sdl_callback");
if (s->exit) {
return;
@@ -264,6 +286,11 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
if (!sdl->live) {
goto again;
}
+#else
+ if (s->exit || !sdl->live) {
+ break;
+ }
+#endif
/* dolog ("in callback live=%d\n", live); */
to_mix = audio_MIN (samples, sdl->live);
@@ -274,7 +301,11 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
hw->clip (buf, src, chunk);
+#if USE_SEMAPHORE
sdl->rpos = (sdl->rpos + chunk) % hw->samples;
+#else
+ hw->rpos = (hw->rpos + chunk) % hw->samples;
+#endif
to_mix -= chunk;
buf += chunk << hw->info.shift;
}
@@ -282,12 +313,21 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
sdl->live -= decr;
sdl->decr += decr;
+#if USE_SEMAPHORE
again:
if (sdl_unlock (s, "sdl_callback")) {
return;
}
+#endif
}
/* dolog ("done len=%d\n", len); */
+
+#if (SDL_MAJOR_VERSION >= 2)
+ /* SDL2 does not clear the remaining buffer for us, so do it on our own */
+ if (samples) {
+ memset(buf, 0, samples << hw->info.shift);
+ }
+#endif
}
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
@@ -315,8 +355,12 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
decr = audio_MIN (sdl->decr, live);
sdl->decr -= decr;
+#if USE_SEMAPHORE
sdl->live = live - decr;
hw->rpos = sdl->rpos;
+#else
+ sdl->live = live;
+#endif
if (sdl->live > 0) {
sdl_unlock_and_post (s, "sdl_run_out");
@@ -405,6 +449,7 @@ static void *sdl_audio_init (void)
return NULL;
}
+#if USE_SEMAPHORE
s->mutex = SDL_CreateMutex ();
if (!s->mutex) {
sdl_logerr ("Failed to create SDL mutex\n");
@@ -419,6 +464,7 @@ static void *sdl_audio_init (void)
SDL_QuitSubSystem (SDL_INIT_AUDIO);
return NULL;
}
+#endif
s->driver_created = true;
return s;
@@ -428,8 +474,10 @@ static void sdl_audio_fini (void *opaque)
{
SDLAudioState *s = opaque;
sdl_close (s);
+#if USE_SEMAPHORE
SDL_DestroySemaphore (s->sem);
SDL_DestroyMutex (s->mutex);
+#endif
SDL_QuitSubSystem (SDL_INIT_AUDIO);
s->driver_created = false;
}