Hi all, I wrote a patch to drop the silence data in such situation. There're two cases need consider: 1) when read_index/write_index both negative and the gap is quite huge, this take some time to consume the silence before real audio data comes. the patch reduces the silence length to make it near the 0. this is my current case. while droping the silence, keep write_index updated, otherwise there's underrun. 2) if write_index is positive and read-index is negative, only update the read_index is enough. i am afraid this case may also be reproduced. After the first rewinding of latency change, the read_index is a huge negative value while the write_index is 0, in such situation, the new request data will cause long time silence. I'm not quite familiar with pulseaudio and please help share your better ideas. Any comments are appreciated! :-) thanks --xingchao diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index e0a195e..53bd615 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -1506,6 +1506,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int /* Called from thread context */ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) { playback_stream *s; + size_t r_offset, w_offset; pa_sink_input_assert_ref(i); s = PLAYBACK_STREAM(i->userdata); @@ -1514,9 +1515,24 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk /* pa_log("%s, pop(): %lu", pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME), (unsigned long) pa_memblockq_get_length(s->memblockq)); */ - if (pa_memblockq_is_readable(s->memblockq)) + if (pa_memblockq_is_readable(s->memblockq)) { s->is_underrun = FALSE; - else { + + /* If read_index is huge negative, there's piece of silence as bad feeling. + * Check if read_index/write_index is negative, first drop the data to make sure + read_index move forward, also seek ahead to keep the memblockq's length.*/ + if (s->memblockq->read_index < 0) { + if (s->memblockq->write_index < 0) { + r_offset = w_offset = -(s->memblockq->write_index) + } else { + r_offset = -(s->memblockq->read_index); + w_offset = 0; + } + pa_memblockq_drop(s->memblockq, r_offset); + if (!w_offset) + pa_memblockq_seek(s->memblockq, w_offset, PA_SEEK_RELATIVE, TRUE); + } + } else { if (!s->is_underrun) pa_log_debug("Underrun on '%s', %lu bytes in queue.", pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)), (unsigned long) pa_memblockq_get_length(s->memblockq)); 2011/6/9 xing wang <wangxingchao2011 at gmail.com>: > hi all, > > i've a finding about silence delay, the background is looking like > this post : "[pulseaudio-discuss] [PATCH] core: Drop empty gaps in the > memblockq when playing data from it." > (http://www.mail-archive.com/pulseaudio-discuss at mail.0pointer.de/msg09579.html) > > with tsched=1 and using default 2s buffer size,,while alsa-driver > provides a even bigger buffer(5s),after the first rewind of "latency > change" before starting playback, the buffer had been shrinked to a > smaller value according to app's request, this trigger sink-input's > rewinding , read-index become a negative value,,nearly -buffer_size. > > in pa_sink_input_cb() , pa_memblockq_peek() will return silence before > the readindex reach 0 from the negative value. that caused obvious > delay. > > i had one idea to disable alsa-sink's first rewind request of "latency > change" , to avoid ?sink-input's read-index moved back, but seems > still delay...so a bit confused. > > Thanks > --xingchao >