Module Name: src Committed By: nat Date: Tue May 15 00:28:00 UTC 2018
Modified Files: src/sys/dev: audio.c Log Message: Expose the audio_info structure of vchan zero(0) the mix ring to allow setting the hardware gain and balance via audioctl(1) using the -p 0 switch. It is not possible to influence the hardware gain/blance from the audio_info structure of vchans 1 onwards. It is now possible to return the audio mixers audio format from the audio_info structure of vchan 0 to ease applications configuring for mmapped play back. This is conformant to the audio specification posted on tech-kern see: "NetBSD Audio Specification 2018" or audio.7 manual page to be added in a follow up commit. To generate a diff of this commit: cvs rdiff -u -r1.453 -r1.454 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/sys/dev/audio.c diff -u src/sys/dev/audio.c:1.453 src/sys/dev/audio.c:1.454 --- src/sys/dev/audio.c:1.453 Tue May 15 00:19:08 2018 +++ src/sys/dev/audio.c Tue May 15 00:28:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.453 2018/05/15 00:19:08 nat Exp $ */ +/* $NetBSD: audio.c,v 1.454 2018/05/15 00:28:00 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.453 2018/05/15 00:19:08 nat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.454 2018/05/15 00:28:00 nat Exp $"); #ifdef _KERNEL_OPT #include "audio.h" @@ -3076,7 +3076,7 @@ audio_ioctl(dev_t dev, struct audio_soft KASSERT(mutex_owned(sc->sc_lock)); - if (sc->sc_usemixer) { + if (sc->sc_usemixer && chan->deschan != 0) { SIMPLEQ_FOREACH(pchan, &sc->sc_audiochan, entries) { if (pchan->chan == chan->deschan) break; @@ -3086,7 +3086,10 @@ audio_ioctl(dev_t dev, struct audio_soft } else pchan = chan; - vc = pchan->vc; + if (chan->deschan != 0) + vc = pchan->vc; + else + vc = &sc->sc_mixring; DPRINTF(("audio_ioctl(%lu,'%c',%lu)\n", IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff)); @@ -3100,7 +3103,7 @@ audio_ioctl(dev_t dev, struct audio_soft *(int*)addr = chan->chan; break; case AUDIO_SETCHAN: - if ((int *)addr != NULL && *(int*)addr > 0) + if ((int *)addr != NULL && *(int*)addr >= 0) chan->deschan = *(int*)addr; break; case FIONBIO: @@ -4195,6 +4198,12 @@ audio_set_vchan_defaults(struct audio_so if (error == 0) error = audiosetinfo(sc, &ai, true, vc); + if (error == 0) { + vc = &sc->sc_mixring; + + vc->sc_rparams = sc->sc_vchan_params; + vc->sc_pparams = sc->sc_vchan_params; + } return error; } @@ -4559,6 +4568,9 @@ audiosetinfo(struct audio_softc *sc, str rp = vc->sc_rparams; /* case setting the modes fails. */ nr = np = 0; + if (vc == &sc->sc_mixring) + goto done; + if (SPECIFIED(p->sample_rate)) { pp.sample_rate = p->sample_rate; np++; @@ -4644,9 +4656,10 @@ audiosetinfo(struct audio_softc *sc, str vc->sc_mode &= ~AUMODE_RECORD; } +done: oldpus = vc->sc_pustream; oldrus = vc->sc_rustream; - if (modechange || reset) { + if (vc != &sc->sc_mixring && (modechange || reset)) { int indep; indep = audio_get_props(sc) & AUDIO_PROP_INDEPENDENT; @@ -4741,23 +4754,41 @@ audiosetinfo(struct audio_softc *sc, str if (error) goto cleanup; } - if (SPECIFIED(p->gain)) - vc->sc_swvol = p->gain; + if (SPECIFIED(p->gain)) { + if (!sc->sc_usemixer || vc == &sc->sc_mixring) { + au_get_gain(sc, &sc->sc_outports, &gain, &balance); + error = au_set_gain(sc, &sc->sc_outports, p->gain, balance); + if (error) + goto cleanup; + } else + vc->sc_swvol = p->gain; + } - if (SPECIFIED(r->gain)) - vc->sc_recswvol = r->gain; + if (SPECIFIED(r->gain)) { + if (!sc->sc_usemixer || vc == &sc->sc_mixring) { + au_get_gain(sc, &sc->sc_outports, &gain, &balance); + error = au_set_gain(sc, &sc->sc_outports, r->gain, balance); + if (error) + goto cleanup; + } else + vc->sc_recswvol = r->gain; + } if (SPECIFIED_CH(p->balance)) { - au_get_gain(sc, &sc->sc_outports, &gain, &balance); - error = au_set_gain(sc, &sc->sc_outports, gain, p->balance); - if (error) - goto cleanup; + if (!sc->sc_usemixer || vc == &sc->sc_mixring) { + au_get_gain(sc, &sc->sc_outports, &gain, &balance); + error = au_set_gain(sc, &sc->sc_outports, gain, p->balance); + if (error) + goto cleanup; + } } if (SPECIFIED_CH(r->balance)) { - au_get_gain(sc, &sc->sc_inports, &gain, &balance); - error = au_set_gain(sc, &sc->sc_inports, gain, r->balance); - if (error) - goto cleanup; + if (!sc->sc_usemixer || vc == &sc->sc_mixring) { + au_get_gain(sc, &sc->sc_inports, &gain, &balance); + error = au_set_gain(sc, &sc->sc_inports, gain, r->balance); + if (error) + goto cleanup; + } } if (SPECIFIED(ai->monitor_gain) && sc->sc_monitor_port != -1) { @@ -4901,8 +4932,13 @@ audiogetinfo(struct audio_softc *sc, str r->avail_ports = sc->sc_inports.allports; p->avail_ports = sc->sc_outports.allports; - au_get_gain(sc, &sc->sc_inports, &r->gain, &r->balance); - au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance); + if (!sc->sc_usemixer || vc == &sc->sc_mixring) { + au_get_gain(sc, &sc->sc_inports, &r->gain, &r->balance); + au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance); + } else { + p->gain = vc->sc_swvol; + r->gain = vc->sc_recswvol; + } } if (sc->sc_monitor_port != -1 && buf_only_mode == 0) {