Revert "sdlaudio: make it suck less"

This reverts commit 4839abe78f.

The commit was badly broken, Gentoo has sdl as the default driver,
consequently 5 gentoo users have hit the breakage and were kind enough
to report, so thank you:

Claes Gyllenswrd
vekin
Chris

But above all thanks to Toralf Foerster who actually provied enough
information to pinpoint the breakage to sdlaudio.

http://bugs.gentoo.org/show_bug.cgi?id=294269
master
malc 2010-01-17 00:25:29 +03:00
parent 787cfbc432
commit ff54149906
1 changed files with 52 additions and 32 deletions

View File

@ -41,8 +41,8 @@
typedef struct SDLVoiceOut { typedef struct SDLVoiceOut {
HWVoiceOut hw; HWVoiceOut hw;
int live; int live;
int rpos;
int decr; int decr;
int pending;
} SDLVoiceOut; } SDLVoiceOut;
static struct { static struct {
@ -225,10 +225,6 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
HWVoiceOut *hw = &sdl->hw; HWVoiceOut *hw = &sdl->hw;
int samples = len >> hw->info.shift; int samples = len >> hw->info.shift;
if (sdl_lock (s, "sdl_callback")) {
return;
}
if (s->exit) { if (s->exit) {
return; return;
} }
@ -236,11 +232,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
while (samples) { while (samples) {
int to_mix, decr; int to_mix, decr;
while (!sdl->pending) { /* dolog ("in callback samples=%d\n", samples); */
if (sdl_unlock (s, "sdl_callback")) {
return;
}
sdl_wait (s, "sdl_callback"); sdl_wait (s, "sdl_callback");
if (s->exit) { if (s->exit) {
return; return;
@ -249,21 +241,40 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
if (sdl_lock (s, "sdl_callback")) { if (sdl_lock (s, "sdl_callback")) {
return; return;
} }
sdl->pending += sdl->live;
sdl->live = 0; if (audio_bug (AUDIO_FUNC, sdl->live < 0 || sdl->live > hw->samples)) {
dolog ("sdl->live=%d hw->samples=%d\n",
sdl->live, hw->samples);
return;
} }
to_mix = audio_MIN (samples, sdl->pending); if (!sdl->live) {
decr = audio_pcm_hw_clip_out (hw, buf, to_mix, 0); goto again;
buf += decr << hw->info.shift; }
/* dolog ("in callback live=%d\n", live); */
to_mix = audio_MIN (samples, sdl->live);
decr = to_mix;
while (to_mix) {
int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
struct st_sample *src = hw->mix_buf + hw->rpos;
/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
hw->clip (buf, src, chunk);
sdl->rpos = (sdl->rpos + chunk) % hw->samples;
to_mix -= chunk;
buf += chunk << hw->info.shift;
}
samples -= decr; samples -= decr;
sdl->live -= decr;
sdl->decr += decr; sdl->decr += decr;
sdl->pending -= decr;
}
again:
if (sdl_unlock (s, "sdl_callback")) { if (sdl_unlock (s, "sdl_callback")) {
return; return;
} }
}
/* dolog ("done len=%d\n", len); */
} }
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len) static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
@ -281,9 +292,18 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
return 0; return 0;
} }
sdl->live = live; if (sdl->decr > live) {
decr = sdl->decr; ldebug ("sdl->decr %d live %d sdl->live %d\n",
sdl->decr = 0; sdl->decr,
live,
sdl->live);
}
decr = audio_MIN (sdl->decr, live);
sdl->decr -= decr;
sdl->live = live - decr;
hw->rpos = sdl->rpos;
if (sdl->live > 0) { if (sdl->live > 0) {
sdl_unlock_and_post (s, "sdl_run_out"); sdl_unlock_and_post (s, "sdl_run_out");