mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
Remove silence generation in waveout module.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1325 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
095f35725d
commit
d194604402
1 changed files with 34 additions and 51 deletions
|
|
@ -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;
|
||||
|
||||
if (cur_chunk != &u->silence) {
|
||||
pa_memblock_unref(cur_chunk->memblock);
|
||||
cur_chunk->memblock = NULL;
|
||||
}
|
||||
pa_memblock_unref(memchunk.memblock);
|
||||
memchunk.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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue