From af9917658145e0595d16c6e508b95d0eef2986d0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 4 Feb 2013 15:41:33 +0100 Subject: [PATCH] output/alsa: workaround for noise after manual song change Workaround for driver bug observed on the Raspberry Pi, see code comment for details. --- NEWS | 1 + src/output/AlsaOutputPlugin.cxx | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/NEWS b/NEWS index e1821a877..71e20eb6c 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ ver 0.18 (2012/??/??) - vorbis: accept floating point input samples * output: - new option "tags" may be used to disable sending tags to output + - alsa: workaround for noise after manual song change * improved decoder/output error reporting diff --git a/src/output/AlsaOutputPlugin.cxx b/src/output/AlsaOutputPlugin.cxx index 75089f9d6..1badeb63d 100644 --- a/src/output/AlsaOutputPlugin.cxx +++ b/src/output/AlsaOutputPlugin.cxx @@ -726,6 +726,26 @@ alsa_recover(AlsaOutput *ad, int err) case SND_PCM_STATE_XRUN: ad->period_position = 0; err = snd_pcm_prepare(ad->pcm); + + if (err == 0) { + /* this works around a driver bug observed on + the Raspberry Pi: after snd_pcm_drop(), the + whole ring buffer must be invalidated, but + the snd_pcm_prepare() call above makes the + driver play random data that just happens + to be still in the buffer; by adding and + cancelling some silence, this bug does not + occur */ + alsa_write_silence(ad, ad->period_frames); + + /* cancel the silence data right away to avoid + increasing latency; even though this + function call invalidates the portion of + silence, the driver seems to avoid the + bug */ + snd_pcm_reset(ad->pcm); + } + break; case SND_PCM_STATE_DISCONNECTED: break;