aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-02-04 15:41:33 +0100
committerMax Kellermann <max@duempel.org>2013-02-04 15:51:32 +0100
commitaf9917658145e0595d16c6e508b95d0eef2986d0 (patch)
tree7d8e10626142841c63f19e3e2d1bdbde4a1b37fd
parent57e825dfe729c80081371d22207b8eb43c49b051 (diff)
downloadmpd-af9917658145e0595d16c6e508b95d0eef2986d0.tar.gz
mpd-af9917658145e0595d16c6e508b95d0eef2986d0.tar.xz
mpd-af9917658145e0595d16c6e508b95d0eef2986d0.zip
output/alsa: workaround for noise after manual song change
Workaround for driver bug observed on the Raspberry Pi, see code comment for details.
-rw-r--r--NEWS1
-rw-r--r--src/output/AlsaOutputPlugin.cxx20
2 files changed, 21 insertions, 0 deletions
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;