Module Name:    src
Committed By:   martin
Date:           Thu Apr 30 15:40:50 UTC 2020

Modified Files:
        src/share/man/man4 [netbsd-9]: audio.4
        src/sys/dev/audio [netbsd-9]: audio.c

Log Message:
Pull up following revision(s) (requested by isaki in ticket #875):

        sys/dev/audio/audio.c: revision 1.59
        share/man/man4/audio.4: revision 1.102
        share/man/man4/audio.4: revision 1.103
        sys/dev/audio/audio.c: revision 1.43

Limit the number of channels that userland apps can set (by AUDIO_SETINFO)
to the number of channels supported by the hardware or less, if the hardware
supports multi channels.
- On monaural or stereo hardware, userland apps can always set 1ch or 2ch.
  The kernel (audio layer) can convert mono-stereo each other.
- On 3ch (2.1ch) hardware, for example, userland apps can set 1, 2, or 3ch,
  but not 4ch or more.

This allows userland apps to know actual number of channels supported by
the hardware in the same way as before.

PR kern/54973.

Reinitialize the sticky parameters whenever the hardware format is changed.

When the number of the hardware channels becomes less than the number of
channels that sticky parameters remember, subsequent open("/dev/sound") will
fail without this treatment.  This is for rev 1.43.

Add description about channel limitation introduced in audio.c 1.43.
PR kern/54973.

Remove trailing whitespace.


To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.90.2.1 src/share/man/man4/audio.4
cvs rdiff -u -r1.28.2.9 -r1.28.2.10 src/sys/dev/audio/audio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man4/audio.4
diff -u src/share/man/man4/audio.4:1.90 src/share/man/man4/audio.4:1.90.2.1
--- src/share/man/man4/audio.4:1.90	Thu May  9 09:35:29 2019
+++ src/share/man/man4/audio.4	Thu Apr 30 15:40:50 2020
@@ -1,4 +1,4 @@
-.\"	$NetBSD: audio.4,v 1.90 2019/05/09 09:35:29 wiz Exp $
+.\"	$NetBSD: audio.4,v 1.90.2.1 2020/04/30 15:40:50 martin Exp $
 .\"
 .\" Copyright (c) 1996 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -402,18 +402,25 @@ unsigned linear encoding with big endian
 Dolby Digital AC3
 .El
 .Pp
-Regardless of formats supported by underlying driver, the
+The
 .Nm
 driver accepts the following formats.
 .Va encoding
 and
 .Va precision
 are one of the values obtained by
-.Dv AUDIO_GETENC .
-.Va channels
-ranges from 1 to 12.
+.Dv AUDIO_GETENC ,
+regardless of formats supported by underlying driver.
 .Va frequency
-ranges from 1000Hz to 192000Hz.
+ranges from 1000Hz to 192000Hz,
+regardless of frequency (ranges) supported by underlying driver.
+.Va channels
+depends your underlying driver.
+If the underlying driver only supports monaural (1channel)
+or stereo (2channels), you can specify 1 or 2 regardless of
+number of channels supported by underlying driver.
+If the underlying driver supports three or more channels, you can specify
+the number of channels supported by the underlying driver or less.
 .Pp
 The
 .Va gain ,

Index: src/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.28.2.9 src/sys/dev/audio/audio.c:1.28.2.10
--- src/sys/dev/audio/audio.c:1.28.2.9	Sat Mar 21 15:47:00 2020
+++ src/sys/dev/audio/audio.c	Thu Apr 30 15:40:50 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.28.2.9 2020/03/21 15:47:00 martin Exp $	*/
+/*	$NetBSD: audio.c,v 1.28.2.10 2020/04/30 15:40:50 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -142,7 +142,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.9 2020/03/21 15:47:00 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.10 2020/04/30 15:40:50 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -543,7 +543,7 @@ static __inline int audio_track_readable
 static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
 	const struct audio_info *);
 static int audio_track_setinfo_check(audio_format2_t *,
-	const struct audio_prinfo *);
+	const struct audio_prinfo *, const audio_format2_t *);
 static void audio_track_setinfo_water(audio_track_t *,
 	const struct audio_info *);
 static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *,
@@ -6546,6 +6546,18 @@ audio_mixers_set_format(struct audio_sof
 	if (error)
 		return error;
 
+	/*
+	 * Reinitialize the sticky parameters for /dev/sound.
+	 * If the number of the hardware channels becomes less than the number
+	 * of channels that sticky parameters remember, subsequent /dev/sound
+	 * open will fail.  To prevent this, reinitialize the sticky
+	 * parameters whenever the hardware format is changed.
+	 */
+	sc->sc_sound_pparams = params_to_format2(&audio_default);
+	sc->sc_sound_rparams = params_to_format2(&audio_default);
+	sc->sc_sound_ppause = false;
+	sc->sc_sound_rpause = false;
+
 	return 0;
 }
 
@@ -6800,7 +6812,8 @@ audio_file_setinfo(struct audio_softc *s
 	}
 
 	if (ptrack) {
-		pchanges = audio_track_setinfo_check(&pfmt, pi);
+		pchanges = audio_track_setinfo_check(&pfmt, pi,
+		    &sc->sc_pmixer->hwbuf.fmt);
 		if (pchanges == -1) {
 #if defined(AUDIO_DEBUG)
 			char fmtbuf[64];
@@ -6814,7 +6827,8 @@ audio_file_setinfo(struct audio_softc *s
 			pchanges = 1;
 	}
 	if (rtrack) {
-		rchanges = audio_track_setinfo_check(&rfmt, ri);
+		rchanges = audio_track_setinfo_check(&rfmt, ri,
+		    &sc->sc_rmixer->hwbuf.fmt);
 		if (rchanges == -1) {
 #if defined(AUDIO_DEBUG)
 			char fmtbuf[64];
@@ -6926,7 +6940,8 @@ abort1:
  * Return value of -1 indicates that error EINVAL has occurred.
  */
 static int
-audio_track_setinfo_check(audio_format2_t *fmt, const struct audio_prinfo *info)
+audio_track_setinfo_check(audio_format2_t *fmt, const struct audio_prinfo *info,
+	const audio_format2_t *hwfmt)
 {
 	int changes;
 
@@ -6950,6 +6965,13 @@ audio_track_setinfo_check(audio_format2_
 		changes = 1;
 	}
 	if (SPECIFIED(info->channels)) {
+		/*
+		 * We can convert between monaural and stereo each other.
+		 * We can reduce than the number of channels that the hardware
+		 * supports.
+		 */
+		if (info->channels > 2 && info->channels > hwfmt->channels)
+			return -1;
 		fmt->channels = info->channels;
 		changes = 1;
 	}

Reply via email to