sdlaudio: make it suck less

Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
malc 2009-09-30 16:25:55 +04:00
parent d68592022b
commit 4839abe78f

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,6 +225,10 @@ 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;
} }
@ -232,49 +236,34 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
while (samples) { while (samples) {
int to_mix, decr; int to_mix, decr;
/* dolog ("in callback samples=%d\n", samples); */ while (!sdl->pending) {
sdl_wait (s, "sdl_callback"); if (sdl_unlock (s, "sdl_callback")) {
if (s->exit) { return;
return; }
sdl_wait (s, "sdl_callback");
if (s->exit) {
return;
}
if (sdl_lock (s, "sdl_callback")) {
return;
}
sdl->pending += sdl->live;
sdl->live = 0;
} }
if (sdl_lock (s, "sdl_callback")) { to_mix = audio_MIN (samples, sdl->pending);
return; decr = audio_pcm_hw_clip_out (hw, buf, to_mix, 0);
} buf += decr << hw->info.shift;
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;
}
if (!sdl->live) {
goto again;
}
/* 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")) {
return; if (sdl_unlock (s, "sdl_callback")) {
} 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)
@ -292,18 +281,9 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
return 0; return 0;
} }
if (sdl->decr > live) { sdl->live = live;
ldebug ("sdl->decr %d live %d sdl->live %d\n", decr = sdl->decr;
sdl->decr, sdl->decr = 0;
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");