Revision ff541499 audio/sdlaudio.c
b/audio/sdlaudio.c | ||
---|---|---|
41 | 41 |
typedef struct SDLVoiceOut { |
42 | 42 |
HWVoiceOut hw; |
43 | 43 |
int live; |
44 |
int rpos; |
|
44 | 45 |
int decr; |
45 |
int pending; |
|
46 | 46 |
} SDLVoiceOut; |
47 | 47 |
|
48 | 48 |
static struct { |
... | ... | |
225 | 225 |
HWVoiceOut *hw = &sdl->hw; |
226 | 226 |
int samples = len >> hw->info.shift; |
227 | 227 |
|
228 |
if (sdl_lock (s, "sdl_callback")) { |
|
229 |
return; |
|
230 |
} |
|
231 |
|
|
232 | 228 |
if (s->exit) { |
233 | 229 |
return; |
234 | 230 |
} |
... | ... | |
236 | 232 |
while (samples) { |
237 | 233 |
int to_mix, decr; |
238 | 234 |
|
239 |
while (!sdl->pending) { |
|
240 |
if (sdl_unlock (s, "sdl_callback")) { |
|
241 |
return; |
|
242 |
} |
|
243 |
|
|
244 |
sdl_wait (s, "sdl_callback"); |
|
245 |
if (s->exit) { |
|
246 |
return; |
|
247 |
} |
|
248 |
|
|
249 |
if (sdl_lock (s, "sdl_callback")) { |
|
250 |
return; |
|
251 |
} |
|
252 |
sdl->pending += sdl->live; |
|
253 |
sdl->live = 0; |
|
235 |
/* dolog ("in callback samples=%d\n", samples); */ |
|
236 |
sdl_wait (s, "sdl_callback"); |
|
237 |
if (s->exit) { |
|
238 |
return; |
|
239 |
} |
|
240 |
|
|
241 |
if (sdl_lock (s, "sdl_callback")) { |
|
242 |
return; |
|
243 |
} |
|
244 |
|
|
245 |
if (audio_bug (AUDIO_FUNC, sdl->live < 0 || sdl->live > hw->samples)) { |
|
246 |
dolog ("sdl->live=%d hw->samples=%d\n", |
|
247 |
sdl->live, hw->samples); |
|
248 |
return; |
|
249 |
} |
|
250 |
|
|
251 |
if (!sdl->live) { |
|
252 |
goto again; |
|
254 | 253 |
} |
255 | 254 |
|
256 |
to_mix = audio_MIN (samples, sdl->pending); |
|
257 |
decr = audio_pcm_hw_clip_out (hw, buf, to_mix, 0); |
|
258 |
buf += decr << hw->info.shift; |
|
255 |
/* dolog ("in callback live=%d\n", live); */ |
|
256 |
to_mix = audio_MIN (samples, sdl->live); |
|
257 |
decr = to_mix; |
|
258 |
while (to_mix) { |
|
259 |
int chunk = audio_MIN (to_mix, hw->samples - hw->rpos); |
|
260 |
struct st_sample *src = hw->mix_buf + hw->rpos; |
|
261 |
|
|
262 |
/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ |
|
263 |
hw->clip (buf, src, chunk); |
|
264 |
sdl->rpos = (sdl->rpos + chunk) % hw->samples; |
|
265 |
to_mix -= chunk; |
|
266 |
buf += chunk << hw->info.shift; |
|
267 |
} |
|
259 | 268 |
samples -= decr; |
269 |
sdl->live -= decr; |
|
260 | 270 |
sdl->decr += decr; |
261 |
sdl->pending -= decr; |
|
262 |
} |
|
263 | 271 |
|
264 |
if (sdl_unlock (s, "sdl_callback")) { |
|
265 |
return; |
|
272 |
again: |
|
273 |
if (sdl_unlock (s, "sdl_callback")) { |
|
274 |
return; |
|
275 |
} |
|
266 | 276 |
} |
277 |
/* dolog ("done len=%d\n", len); */ |
|
267 | 278 |
} |
268 | 279 |
|
269 | 280 |
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len) |
... | ... | |
281 | 292 |
return 0; |
282 | 293 |
} |
283 | 294 |
|
284 |
sdl->live = live; |
|
285 |
decr = sdl->decr; |
|
286 |
sdl->decr = 0; |
|
295 |
if (sdl->decr > live) { |
|
296 |
ldebug ("sdl->decr %d live %d sdl->live %d\n", |
|
297 |
sdl->decr, |
|
298 |
live, |
|
299 |
sdl->live); |
|
300 |
} |
|
301 |
|
|
302 |
decr = audio_MIN (sdl->decr, live); |
|
303 |
sdl->decr -= decr; |
|
304 |
|
|
305 |
sdl->live = live - decr; |
|
306 |
hw->rpos = sdl->rpos; |
|
287 | 307 |
|
288 | 308 |
if (sdl->live > 0) { |
289 | 309 |
sdl_unlock_and_post (s, "sdl_run_out"); |
Also available in: Unified diff