Module Name:    src
Committed By:   nat
Date:           Tue May 22 01:35:49 UTC 2018

Modified Files:
        src/share/man/man7: audio.7
        src/sys/dev: audio.c

Log Message:
Using audioctl without the -p switch defaults to the mix ring.  This allows
setting the hardware gain etc.

Update the audio spec in audio.7 to reflect these changes.

Addresses PR kern/52781.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/share/man/man7/audio.7
cvs rdiff -u -r1.456 -r1.457 src/sys/dev/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/man7/audio.7
diff -u src/share/man/man7/audio.7:1.2 src/share/man/man7/audio.7:1.3
--- src/share/man/man7/audio.7:1.2	Tue May 15 09:30:01 2018
+++ src/share/man/man7/audio.7	Tue May 22 01:35:49 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: audio.7,v 1.2 2018/05/15 09:30:01 wiz Exp $
+.\"	$NetBSD: audio.7,v 1.3 2018/05/22 01:35:49 nat Exp $
 .\"
 .\" Copyright (c) 2016 - 2018  Nathanial Sloss <nathanialsl...@yahoo.com.au>
 .\" All rights reserved.
@@ -144,7 +144,7 @@ device so to check on buffer usage and s
 .Pp
 As opening an
 .Xr audioctl 4
-device would result in a new vchan being created, these
+device would represent vchan 0 (the mix ring), these
 ioctls allow setting the target vchan and
 .Vt audio_info
 structure to that of an existing vchan.
@@ -188,22 +188,21 @@ are numbered starting at zero (0).
 .Pp
 Not specifying
 .Fl p
-will result in working with a new vchan and this is only
-desired when the next subsequent audio open is to be
-.Pa /dev/sound ,
-i.e.:
+is the same as specifying
+.Fl p
+0 and will result in working with vchan 0 (the mix ring).
+This will display the audio parameters of the mix ring and allow
+setting the hardware gain and balance.
 .Pp
-.Dl audioctl -w play.gain=120
-.Dl open /dev/sound this will have an initial software volume level of 120.
+This is for compatibility with existing applications and shell scrpits
+that are unaware of the
+.Fl p
+switch.
 .Pp
 The parameters for playback and recording only effect the particular vchan
 being operated on (gain, sample rate, channels, encoding etc), except
 .Fl p Ar 0
 (the mix ring).
-Specifying
-.Fl p Ar 0
-will display the audio parameters of the mix ring and allow
-setting the hardware gain and balance.
 .Sh ADDED SYSCTLS
 With the introduction of the audio mixer the following
 .Xr sysctl 7 Ns s

Index: src/sys/dev/audio.c
diff -u src/sys/dev/audio.c:1.456 src/sys/dev/audio.c:1.457
--- src/sys/dev/audio.c:1.456	Thu May 17 11:35:31 2018
+++ src/sys/dev/audio.c	Tue May 22 01:35:49 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.456 2018/05/17 11:35:31 nat Exp $	*/
+/*	$NetBSD: audio.c,v 1.457 2018/05/22 01:35:49 nat Exp $	*/
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsl...@yahoo.com.au>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.456 2018/05/17 11:35:31 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.457 2018/05/22 01:35:49 nat Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -234,6 +234,8 @@ int	audiosetinfo(struct audio_softc *, s
 int	audiogetinfo(struct audio_softc *, struct audio_info *, int,
 		     struct virtual_channel *);
 
+int	audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *,
+		   struct file **);
 int	audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
 		   struct file **);
 int	audio_close(struct audio_softc *, int, struct audio_chan *);
@@ -1678,9 +1680,11 @@ audioopen(dev_t dev, int flags, int ifmt
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
-	case AUDIOCTL_DEVICE:
 		error = audio_open(dev, sc, flags, ifmt, l, &fp);
 		break;
+	case AUDIOCTL_DEVICE:
+		error = audioctl_open(dev, sc, flags, ifmt, l, &fp);
+		break;
 	case MIXER_DEVICE:
 		error = mixer_open(dev, sc, flags, ifmt, l, &fp);
 		break;
@@ -1714,9 +1718,11 @@ audioclose(struct file *fp)
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
-	case AUDIOCTL_DEVICE:
 		error = audio_close(sc, fp->f_flag, chan);
 		break;
+	case AUDIOCTL_DEVICE:
+		error = 0;
+		break;
 	case MIXER_DEVICE:
 		error = mixer_close(sc, fp->f_flag, chan);
 		break;
@@ -2144,6 +2150,50 @@ audio_calcwater(struct audio_softc *sc, 
 }
 
 int
+audioctl_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
+    struct lwp *l, struct file **nfp)
+{
+	struct file *fp;
+	int error, fd;
+	const struct audio_hw_if *hw;
+	struct virtual_channel *vc;
+	struct audio_chan *chan;
+
+	KASSERT(mutex_owned(sc->sc_lock));
+
+	if (sc->sc_usemixer && !sc->sc_ready)
+		return ENXIO;
+
+	hw = sc->hw_if;
+	if (hw == NULL)
+		return ENXIO;
+
+	chan = kmem_zalloc(sizeof(struct audio_chan), KM_SLEEP);
+	if (sc->sc_usemixer)
+		vc = &sc->sc_mixring;
+	else
+		vc = sc->sc_hwvc;
+	chan->vc = vc;
+
+	error = fd_allocfile(&fp, &fd);
+	if (error)
+		goto bad;
+
+	chan->dev = dev;
+	chan->chan = 0;
+	chan->deschan = 0;
+
+	error = fd_clone(fp, fd, flags, &audio_fileops, chan);
+	KASSERT(error == EMOVEFD);
+
+	*nfp = fp;
+	return error;
+bad:
+	kmem_free(chan, sizeof(struct audio_chan));
+	return error;
+}
+
+int
 audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
     struct lwp *l, struct file **nfp)
 {
@@ -2175,9 +2225,6 @@ audio_open(dev_t dev, struct audio_softc
 		vc = sc->sc_hwvc;
 	chan->vc = vc;
 
-	if (!sc->sc_usemixer && AUDIODEV(dev) == AUDIOCTL_DEVICE)
-		goto audioctl_dev;
-
 	if (sc->sc_usemixer) {
 		vc->sc_open = 0;
 		vc->sc_mode = 0;
@@ -2295,12 +2342,9 @@ audio_open(dev_t dev, struct audio_softc
 	/* audio_close() decreases sc_mpr[n].usedlow, recalculate here */
 	audio_calcwater(sc, vc);
 
-audioctl_dev:
 	error = fd_allocfile(&fp, &fd);
 	if (error)
 		goto bad;
-	if (!sc->sc_usemixer && AUDIODEV(dev) == AUDIOCTL_DEVICE)
-		goto setup_chan;
 
 	DPRINTF(("audio_open: done sc_mode = 0x%x\n", vc->sc_mode));
 
@@ -2311,7 +2355,6 @@ audioctl_dev:
 	if (flags & FWRITE)
 		sc->sc_opens++;
 
-setup_chan:
 	chan->dev = dev;
 	chan->chan = n;
 	chan->deschan = n;
@@ -2488,9 +2531,6 @@ audio_close(struct audio_softc *sc, int 
 
 	KASSERT(mutex_owned(sc->sc_lock));
 	
-	if (!sc->sc_usemixer && AUDIODEV(chan->dev) == AUDIOCTL_DEVICE)
-		return 0;
-
 	if (sc->sc_opens == 0 && sc->sc_recopens == 0)
 		return ENXIO;
 
@@ -3086,7 +3126,7 @@ audio_ioctl(dev_t dev, struct audio_soft
 	} else
 		pchan = chan;
 
-	if (chan->deschan != 0)
+	if (!sc->sc_usemixer || chan->deschan != 0)
 		vc = pchan->vc;
 	else
 		vc = &sc->sc_mixring;

Reply via email to