perex a7e045
From 73d20069e072e2b62bbc3ea12e46ae19d8b6cac9 Mon Sep 17 00:00:00 2001
perex a7e045
From: Lennart Poettering <mznyfn@0pointer.de>
perex a7e045
Date: Sun, 31 Aug 2008 03:41:48 +0200
perex a7e045
Subject: [PATCH] alsa-lib: Make sure SND_PCM_NO_xxx flags don't get lost when nonblocking mode is enabled
perex a7e045
perex a7e045
The plug PCM copies the 'mode' field from the slave PCM. If blocking mode is
perex a7e045
enabled for the plug PCM the mode is subsequently overwritten with the original
perex a7e045
requested 'mode'. If non-blocking mode is requested this does not happen.
perex a7e045
perex a7e045
Because the hw PCM synthesizes the 'mode' from the actual file descriptor flags
perex a7e045
no SND_PCM_NO_xxx will ever be set for it. This has the effect that the 'mode'
perex a7e045
of the plug PCM will also not include those flags anymore -- unless they are
perex a7e045
overwritten as mentioned above. This basically means SND_PCM_NO_xxx is ignored
perex a7e045
for plug:hw:4711 style device strings opened in non-blocking mode.
perex a7e045
perex a7e045
You can easily test this with "aplay --channels 7 --disable-channels -f S16_LE
perex a7e045
-r 44100 -D plug:hw:0" on a device that cannot do 7 channels. Normally this
perex a7e045
call should fail, however if you add "-N" to the command line this call will
perex a7e045
succeed.
perex a7e045
perex a7e045
This patch simply copies the SND_PCM_NO_xxx flags back into the 'mode' field in
perex a7e045
case we don't overwrite it with the original anyway.
perex a7e045
perex a7e045
Probably closes bug 3571 for good.
perex a7e045
perex a7e045
From: Lennart Poettering <mznyfn@0pointer.de>
perex a7e045
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
perex a7e045
---
perex a7e045
 src/pcm/pcm_hw.c |    8 +++++++-
perex a7e045
 1 files changed, 7 insertions(+), 1 deletions(-)
perex a7e045
perex a7e045
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
perex a7e045
index 1e1889c..c8d9a62 100644
perex a7e045
--- a/src/pcm/pcm_hw.c
perex a7e045
+++ b/src/pcm/pcm_hw.c
perex a7e045
@@ -1507,7 +1507,13 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
perex a7e045
 		/* revert to blocking mode for read/write access */
perex a7e045
 		snd_pcm_hw_nonblock(*pcmp, 0);
perex a7e045
 		(*pcmp)->mode = mode;
perex a7e045
-	}
perex a7e045
+	} else
perex a7e045
+		/* make sure the SND_PCM_NO_xxx flags don't get lost on the
perex a7e045
+		 * way */
perex a7e045
+		(*pcmp)->mode |= mode & (SND_PCM_NO_AUTO_RESAMPLE|
perex a7e045
+					 SND_PCM_NO_AUTO_CHANNELS|
perex a7e045
+					 SND_PCM_NO_AUTO_FORMAT|
perex a7e045
+					 SND_PCM_NO_SOFTVOL);
perex a7e045
 
perex a7e045
 	hw = (*pcmp)->private_data;
perex a7e045
 	if (format != SND_PCM_FORMAT_UNKNOWN)
perex a7e045
-- 
perex a7e045
1.5.5.1
perex a7e045