Module Name:    src
Committed By:   isaki
Date:           Sat Feb 22 05:51:39 UTC 2020

Modified Files:
        src/sys/dev/audio: audio.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 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/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.42 src/sys/dev/audio/audio.c:1.43
--- src/sys/dev/audio/audio.c:1.42	Sat Feb 15 02:47:00 2020
+++ src/sys/dev/audio/audio.c	Sat Feb 22 05:51:39 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.42 2020/02/15 02:47:00 isaki Exp $	*/
+/*	$NetBSD: audio.c,v 1.43 2020/02/22 05:51:39 isaki Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -142,7 +142,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.42 2020/02/15 02:47:00 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.43 2020/02/22 05:51:39 isaki Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -541,7 +541,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 *,
@@ -6634,7 +6634,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];
@@ -6648,7 +6649,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];
@@ -6760,7 +6762,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;
 
@@ -6784,6 +6787,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