From d194604402648fbab61bde3d1106fecb1b82dc83 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 22 Aug 2006 16:15:47 +0000 Subject: Remove silence generation in waveout module. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1325 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-waveout.c | 83 ++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/src/modules/module-waveout.c b/src/modules/module-waveout.c index f1861466e..4043c1364 100644 --- a/src/modules/module-waveout.c +++ b/src/modules/module-waveout.c @@ -75,11 +75,10 @@ struct userdata { uint32_t free_ofrags, free_ifrags; DWORD written_bytes; + int sink_underflow; int cur_ohdr, cur_ihdr; - unsigned int oremain; WAVEHDR *ohdrs, *ihdrs; - pa_memchunk silence; HWAVEOUT hwo; HWAVEIN hwi; @@ -110,8 +109,8 @@ static void update_usage(struct userdata *u) { static void do_write(struct userdata *u) { - uint32_t free_frags, remain; - pa_memchunk memchunk, *cur_chunk; + uint32_t free_frags; + pa_memchunk memchunk; WAVEHDR *hdr; MMRESULT res; @@ -119,13 +118,10 @@ static void do_write(struct userdata *u) return; EnterCriticalSection(&u->crit); - free_frags = u->free_ofrags; - u->free_ofrags = 0; - LeaveCriticalSection(&u->crit); - if (free_frags == u->fragments) + if (!u->sink_underflow && (free_frags == u->fragments)) pa_log_debug("WaveOut underflow!"); while (free_frags) { @@ -133,45 +129,39 @@ static void do_write(struct userdata *u) if (hdr->dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(u->hwo, hdr, sizeof(WAVEHDR)); - remain = u->oremain; - while (remain) { - cur_chunk = &memchunk; + hdr->dwBufferLength = 0; + while (hdr->dwBufferLength < u->fragment_size) { + size_t len; - if (pa_sink_render(u->sink, remain, cur_chunk) < 0) { - /* - * Don't fill with silence unless we're getting close to - * underflowing. - */ - if (free_frags > u->fragments/2) - cur_chunk = &u->silence; - else { - EnterCriticalSection(&u->crit); + len = u->fragment_size - hdr->dwBufferLength; - u->free_ofrags += free_frags; + if (pa_sink_render(u->sink, len, &memchunk) < 0) + break; - LeaveCriticalSection(&u->crit); + assert(memchunk.memblock); + assert(memchunk.memblock->data); + assert(memchunk.length); - u->oremain = remain; - return; - } - } + if (memchunk.length < len) + len = memchunk.length; - assert(cur_chunk->memblock); - assert(cur_chunk->memblock->data); - assert(cur_chunk->length); + memcpy(hdr->lpData + hdr->dwBufferLength, + (char*)memchunk.memblock->data + memchunk.index, len); - memcpy(hdr->lpData + u->fragment_size - remain, - (char*)cur_chunk->memblock->data + cur_chunk->index, - (cur_chunk->length < remain)?cur_chunk->length:remain); + hdr->dwBufferLength += len; - remain -= (cur_chunk->length < remain)?cur_chunk->length:remain; + pa_memblock_unref(memchunk.memblock); + memchunk.memblock = NULL; + } - if (cur_chunk != &u->silence) { - pa_memblock_unref(cur_chunk->memblock); - cur_chunk->memblock = NULL; - } + /* Insufficient data in sink buffer? */ + if (hdr->dwBufferLength == 0) { + u->sink_underflow = 1; + break; } + u->sink_underflow = 0; + res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR)); if (res != MMSYSERR_NOERROR) { pa_log_error(__FILE__ ": ERROR: Unable to prepare waveOut block: %d", @@ -183,12 +173,15 @@ static void do_write(struct userdata *u) res); } - u->written_bytes += u->fragment_size; + u->written_bytes += hdr->dwBufferLength; + + EnterCriticalSection(&u->crit); + u->free_ofrags--; + LeaveCriticalSection(&u->crit); free_frags--; u->cur_ohdr++; u->cur_ohdr %= u->fragments; - u->oremain = u->fragment_size; } } @@ -540,8 +533,7 @@ int pa__init(pa_core *c, pa_module*m) { u->fragment_size = frag_size - (frag_size % pa_frame_size(&ss)); u->written_bytes = 0; - - u->oremain = u->fragment_size; + u->sink_underflow = 1; u->poll_timeout = pa_bytes_to_usec(u->fragments * u->fragment_size / 10, &ss); @@ -570,12 +562,6 @@ int pa__init(pa_core *c, pa_module*m) { assert(u->ohdrs); } - u->silence.length = u->fragment_size; - u->silence.memblock = pa_memblock_new(u->core->mempool, u->silence.length); - assert(u->silence.memblock); - pa_silence_memblock(u->silence.memblock, &ss); - u->silence.index = 0; - u->module = m; m->userdata = u; @@ -611,9 +597,6 @@ void pa__done(pa_core *c, pa_module*m) { if (!(u = m->userdata)) return; - - if (u->silence.memblock) - pa_memblock_unref(u->silence.memblock); if (u->event) c->mainloop->time_free(u->event); -- cgit v1.2.1