sdlaudio: make it suck less
Signed-off-by: malc <av1474@comtv.ru>
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index 8e7e5cb..aa39c33 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 @@
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 @@
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;
}
- /* dolog ("done len=%d\n", len); */
+
+ if (sdl_unlock (s, "sdl_callback")) {
+ return;
+ }
}
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
@@ -292,18 +281,9 @@
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");