NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/52781: audioctl can't set output gain



Hi,

I've come up with an alternative.  See attached.

In this patch audioctl devices default to the mix ring allowig hw gain to be 
adjusted (recording/ play back/ balance).  If one were to issue audioctl 
without specifing -p vchan it would set the hw paramaters one could still issue 
audioctl -p 0 to achieve the same thing.

It would mean existing sun audio apps that set the master volume via 
play/record->gain would not have to be changed and nor would scripts that want 
to set the hw gain via audioctl(1) and don't specify the -p swich have to be 
changed.


Best regards,

Nat
Index: audio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/audio.c,v
retrieving revision 1.456
diff -u -p -r1.456 audio.c
--- audio.c	17 May 2018 11:35:31 -0000	1.456
+++ audio.c	20 May 2018 10:07:09 -0000
@@ -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;
 


Home | Main Index | Thread Index | Old Index