@@ -78,26 +78,24 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
if (frames > runtime->silence_size)
frames = runtime->silence_size;
} else {
- if (new_hw_ptr == ULONG_MAX) { /* initialization */
+ if (new_hw_ptr == ULONG_MAX) {
+ /* initialization, fill silence to whole unused buffer */
snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
if (avail > runtime->buffer_size)
avail = runtime->buffer_size;
runtime->silence_filled = avail > 0 ? avail : 0;
- runtime->silence_start = (runtime->status->hw_ptr +
- runtime->silence_filled) %
- runtime->boundary;
+ runtime->silence_start = runtime->status->hw_ptr;
} else {
- ofs = runtime->status->hw_ptr;
- frames = new_hw_ptr - ofs;
+ /* top-up mode (appl_ptr is not required) */
+ /* silence the played area immediately */
+ frames = new_hw_ptr - runtime->status->hw_ptr;
if ((snd_pcm_sframes_t)frames < 0)
frames += runtime->boundary;
- runtime->silence_filled -= frames;
- if ((snd_pcm_sframes_t)runtime->silence_filled < 0) {
+ if ((snd_pcm_uframes_t)frames < runtime->silence_filled)
+ runtime->silence_filled -= frames;
+ else
runtime->silence_filled = 0;
- runtime->silence_start = new_hw_ptr;
- } else {
- runtime->silence_start = ofs;
- }
+ runtime->silence_start = new_hw_ptr;
}
frames = runtime->buffer_size - runtime->silence_filled;
}
@@ -105,7 +103,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
return;
if (frames == 0)
return;
- ofs = runtime->silence_start % runtime->buffer_size;
+ ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
while (frames > 0) {
transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
err = fill_silence_frames(substream, ofs, transfer);
The incremental silencing was broken with the threshold mode. The silenced area was smaller than expected in some cases. The updated area starts at runtime->silence_start + runtime->silence_filled position not only at runtime->silence_start in this mode. Unify the runtime->silence_start use for all cases (threshold and top-up). Suggested-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz> --- sound/core/pcm_lib.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)