diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index 8e7e5cb70b..aa39c3379c 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -41,8 +41,8 @@ typedef struct SDLVoiceOut { HWVoiceOut hw; int live; - int rpos; int decr; + int pending; } SDLVoiceOut; static struct { @@ -225,6 +225,10 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) HWVoiceOut *hw = &sdl->hw; int samples = len >> hw->info.shift; + if (sdl_lock (s, "sdl_callback")) { + return; + } + if (s->exit) { return; } @@ -232,49 +236,34 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) while (samples) { int to_mix, decr; - /* dolog ("in callback samples=%d\n", samples); */ - sdl_wait (s, "sdl_callback"); - if (s->exit) { - return; + while (!sdl->pending) { + if (sdl_unlock (s, "sdl_callback")) { + 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")) { - return; - } - - 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; - } + to_mix = audio_MIN (samples, sdl->pending); + decr = audio_pcm_hw_clip_out (hw, buf, to_mix, 0); + buf += decr << hw->info.shift; samples -= decr; - sdl->live -= decr; sdl->decr += decr; - - again: - if (sdl_unlock (s, "sdl_callback")) { - return; - } + sdl->pending -= decr; + } + + if (sdl_unlock (s, "sdl_callback")) { + return; } - /* dolog ("done len=%d\n", 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; } - if (sdl->decr > live) { - ldebug ("sdl->decr %d live %d sdl->live %d\n", - sdl->decr, - live, - sdl->live); - } - - decr = audio_MIN (sdl->decr, live); - sdl->decr -= decr; - - sdl->live = live - decr; - hw->rpos = sdl->rpos; + sdl->live = live; + decr = sdl->decr; + sdl->decr = 0; if (sdl->live > 0) { sdl_unlock_and_post (s, "sdl_run_out");