From f3fd01ebcdfb4df7d9612387a8845deb5dc50799 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 2 Jul 2016 08:04:43 +0200 Subject: [PATCH] ALSA code: Fixed corrupted sample at the end of a read The last sample may get corrupted. It seems that this depends on the card that is used. To fix this, the snd_pcm_avail is checked and one sample less than available is read using snd_pcm_readi. This sample remains in RX buffer until next read. Then it is not corrupted. --- src/common/sound_alsa.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/common/sound_alsa.c b/src/common/sound_alsa.c index 9a35e3e..f34405c 100644 --- a/src/common/sound_alsa.c +++ b/src/common/sound_alsa.c @@ -154,6 +154,10 @@ void *sound_open(const char *device, int samplerate) goto error; } + /* trigger capturing */ + int16_t buff[2]; + snd_pcm_readi(sound->chandle, buff, 1); + return sound; error: @@ -207,13 +211,24 @@ int sound_read(void *inst, int16_t *samples_left, int16_t *samples_right, int nu { sound_t *sound = (sound_t *)inst; int16_t buff[num << 1]; - int rc; + int in, rc; int i, ii; + /* get samples in rx buffer */ + in = snd_pcm_avail(sound->chandle); + /* if less than 2 frames available, try next time */ + if (in < 2) + return 0; + /* read one frame less than in buffer, because snd_pcm_readi() seems + * to corrupt last frame */ + in--; + if (in > num) + in = num; + if (sound->cchannels == 2) - rc = snd_pcm_readi(sound->chandle, buff, num); + rc = snd_pcm_readi(sound->chandle, buff, in); else - rc = snd_pcm_readi(sound->chandle, samples_left, num); + rc = snd_pcm_readi(sound->chandle, samples_left, in); if (rc < 0) { if (errno == EAGAIN)