From 8572c0c427dec358e6070659032230966d0dd0ca Mon Sep 17 00:00:00 2001 From: Dragos Tarcatu Date: Thu, 24 Sep 2020 06:01:09 +0000 Subject: [PATCH] alsaloop: Fix the silence generation in xrun_sync The silence frames generation in xrun_sync() seems to be currently a bit off as snd_pcm_format_set_silence() uses a wrong buffer address and size for zero-ing out the data. Consequently instead of clearing out the last frame(s), snd_pcm_format_set_silence() ends up silencing samples somewhere else in the buffer. This is partilarly more obvious for higher frame sizes (e.g. more than 2 channels). This patch fixes this issue by correcting the parameters passed to snd_pcm_format_set_silence(). BugLink: https://github.com/alsa-project/alsa-utils/pull/58 Signed-off-by: Dragos Tarcatu Signed-off-by: Jaroslav Kysela --- alsaloop/pcmjob.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c index 1b7925a..6a9aff4 100644 --- a/alsaloop/pcmjob.c +++ b/alsaloop/pcmjob.c @@ -969,13 +969,14 @@ static int xrun_sync(struct loopback *loop) "sync: playback silence added %li samples\n", (long)diff); play->buf_pos -= diff; play->buf_pos %= play->buf_size; - if ((err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->channels, diff)) < 0) + err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->frame_size, + diff * play->channels); + if (err < 0) return err; play->buf_count += diff; } if ((err = snd_pcm_prepare(play->handle)) < 0) { logit(LOG_CRIT, "%s prepare failed: %s\n", play->id, snd_strerror(err)); - return err; } delay1 = writeit(play); @@ -1001,7 +1002,9 @@ static int xrun_sync(struct loopback *loop) "sync: playback short, silence filling %li / buf_count=%li\n", (long)delay1, play->buf_count); if (delay1 > diff) delay1 = diff; - if ((err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->channels, delay1)) < 0) + err = snd_pcm_format_set_silence(play->format, play->buf + play->buf_pos * play->frame_size, + delay1 * play->channels); + if (err < 0) return err; play->buf_pos += delay1; play->buf_pos %= play->buf_size;