Module Name: src
Committed By: martin
Date: Tue May 15 13:42:50 UTC 2018
Modified Files:
src/distrib/sets/lists/man [netbsd-8]: mi
src/share/man/man4 [netbsd-8]: audio.4
src/share/man/man7 [netbsd-8]: Makefile intro.7
src/share/man/man9 [netbsd-8]: audio.9
src/sys/dev [netbsd-8]: audio.c
Added Files:
src/share/man/man7 [netbsd-8]: audio.7
Log Message:
Pull up following revision(s) (requested by nat in ticket #825):
share/man/man7/Makefile: revision 1.32
share/man/man9/audio.9: revision 1.46
sys/dev/audio.c: revision 1.453
sys/dev/audio.c: revision 1.454
sys/dev/audio.c: revision 1.455
share/man/man7/audio.7: revision 1.1
share/man/man7/audio.7: revision 1.2
share/man/man7/intro.7: revision 1.24
share/man/man4/audio.4: revision 1.85
distrib/sets/lists/man/mi: revision 1.1586
Fix numbering of vchan mixer controls to correspond to the vchan number in
use.
This makes the numbering of vchans consistient for audioctl and mixerctl.
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.
Add the audio mixer specification to section 7 of the manual.
See posting on tech-kern - "NetBSD Audio Specification 2018."
Update the introduction page to section 7 of the manual noting the audio
spec.
Various improvements, more markup, typo fixes.
Fix over cautious compiler error - setmode may not be initialized.
To generate a diff of this commit:
cvs rdiff -u -r1.1557.2.3 -r1.1557.2.4 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.79.2.1 -r1.79.2.2 src/share/man/man4/audio.4
cvs rdiff -u -r1.31 -r1.31.8.1 src/share/man/man7/Makefile
cvs rdiff -u -r0 -r1.2.2.2 src/share/man/man7/audio.7
cvs rdiff -u -r1.23 -r1.23.24.1 src/share/man/man7/intro.7
cvs rdiff -u -r1.44 -r1.44.16.1 src/share/man/man9/audio.9
cvs rdiff -u -r1.357.2.11 -r1.357.2.12 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/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1557.2.3 src/distrib/sets/lists/man/mi:1.1557.2.4
--- src/distrib/sets/lists/man/mi:1.1557.2.3 Sat May 12 10:35:45 2018
+++ src/distrib/sets/lists/man/mi Tue May 15 13:42:50 2018
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1557.2.3 2018/05/12 10:35:45 martin Exp $
+# $NetBSD: mi,v 1.1557.2.4 2018/05/15 13:42:50 martin Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -2251,6 +2251,7 @@
./usr/share/man/cat5/wtmpx.0 man-sys-catman .cat
./usr/share/man/cat5/ypserv.acl.0 man-obsolete obsolete
./usr/share/man/cat7/ascii.0 man-reference-catman .cat
+./usr/share/man/cat7/audio.0 man-reference-catman .cat
./usr/share/man/cat7/atf.0 man-atf-catman .cat,atf
./usr/share/man/cat7/c.0 man-reference-catman .cat
./usr/share/man/cat7/c78.0 man-reference-catman .cat
@@ -5271,6 +5272,7 @@
./usr/share/man/html5/wtmp.html man-sys-htmlman html
./usr/share/man/html5/wtmpx.html man-sys-htmlman html
./usr/share/man/html7/ascii.html man-reference-htmlman html
+./usr/share/man/html7/audio.html man-reference-htmlman html
./usr/share/man/html7/atf.html man-atf-htmlman html,atf
./usr/share/man/html7/c.html man-reference-htmlman html
./usr/share/man/html7/c78.html man-reference-htmlman html
@@ -8261,6 +8263,7 @@
./usr/share/man/man5/wtmpx.5 man-sys-man .man
./usr/share/man/man5/ypserv.acl.5 man-obsolete obsolete
./usr/share/man/man7/ascii.7 man-reference-man .man
+./usr/share/man/man7/audio.7 man-reference-man .man
./usr/share/man/man7/atf.7 man-atf-man .man,atf
./usr/share/man/man7/c.7 man-reference-man .man
./usr/share/man/man7/c78.7 man-reference-man .man
Index: src/share/man/man4/audio.4
diff -u src/share/man/man4/audio.4:1.79.2.1 src/share/man/man4/audio.4:1.79.2.2
--- src/share/man/man4/audio.4:1.79.2.1 Mon Jan 15 00:08:55 2018
+++ src/share/man/man4/audio.4 Tue May 15 13:42:50 2018
@@ -1,4 +1,4 @@
-.\" $NetBSD: audio.4,v 1.79.2.1 2018/01/15 00:08:55 snj Exp $
+.\" $NetBSD: audio.4,v 1.79.2.2 2018/05/15 13:42:50 martin Exp $
.\"
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 27, 2017
+.Dd May 15, 2018
.Dt AUDIO 4
.Os
.Sh NAME
@@ -789,6 +789,8 @@ string values.
.Xr bba 4
.Ss USB
.Xr uaudio 4
+.Ss The NetBSD audio specification
+.Xr audio 7
.Sh HISTORY
Support for virtual channels and mixing first appeared in
.Nx 8.0 .
Index: src/share/man/man7/Makefile
diff -u src/share/man/man7/Makefile:1.31 src/share/man/man7/Makefile:1.31.8.1
--- src/share/man/man7/Makefile:1.31 Tue Dec 2 03:51:48 2014
+++ src/share/man/man7/Makefile Tue May 15 13:42:49 2018
@@ -1,14 +1,14 @@
-# $NetBSD: Makefile,v 1.31 2014/12/02 03:51:48 msaitoh Exp $
+# $NetBSD: Makefile,v 1.31.8.1 2018/05/15 13:42:49 martin Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93
.include <bsd.init.mk>
# missing: eqnchar.7 man.7 ms.7 term.7
-MAN= ascii.7 c.7 environ.7 glob.7 hier.7 hostname.7 intro.7 mailaddr.7 \
- module.7 nls.7 operator.7 orders.7 pkgsrc.7 release.7 rfc6056.7 \
- security.7 script.7 setuid.7 signal.7 src.7 sticky.7 symlink.7 \
- sysctl.7 tests.7
+MAN= ascii.7 audio.7 c.7 environ.7 glob.7 hier.7 hostname.7 intro.7 \
+ mailaddr.7 module.7 nls.7 operator.7 orders.7 pkgsrc.7 release.7 \
+ rfc6056.7 security.7 script.7 setuid.7 signal.7 src.7 sticky.7 \
+ symlink.7 sysctl.7 tests.7
CLEANFILES= tests.7
.if ${MKKYUA} != "no"
Index: src/share/man/man7/intro.7
diff -u src/share/man/man7/intro.7:1.23 src/share/man/man7/intro.7:1.23.24.1
--- src/share/man/man7/intro.7:1.23 Sun Jul 1 16:18:00 2012
+++ src/share/man/man7/intro.7 Tue May 15 13:42:49 2018
@@ -1,4 +1,4 @@
-.\" $NetBSD: intro.7,v 1.23 2012/07/01 16:18:00 christos Exp $
+.\" $NetBSD: intro.7,v 1.23.24.1 2018/05/15 13:42:49 martin Exp $
.\"
.\" Copyright (c) 1983, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" @(#)intro.7 8.1 (Berkeley) 6/5/93
.\"
-.Dd July 1, 2012
+.Dd May 15, 2018
.Dt INTRO 7
.Os
.Sh NAME
@@ -42,6 +42,9 @@ This section contains miscellaneous docu
map of
.Tn ASCII
character set
+.It Xr audio 7
+the
+.Nx audio specification
.It Xr c 7
the C programming language
.It Xr environ 7
Index: src/share/man/man9/audio.9
diff -u src/share/man/man9/audio.9:1.44 src/share/man/man9/audio.9:1.44.16.1
--- src/share/man/man9/audio.9:1.44 Sun Jul 13 11:08:46 2014
+++ src/share/man/man9/audio.9 Tue May 15 13:42:50 2018
@@ -1,4 +1,4 @@
-.\" $NetBSD: audio.9,v 1.44 2014/07/13 11:08:46 mbalmer Exp $
+.\" $NetBSD: audio.9,v 1.44.16.1 2018/05/15 13:42:50 martin Exp $
.\"
.\" Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 13, 2014
+.Dd May 15, 2018
.Dt AUDIO 9
.Os
.Sh NAME
@@ -591,7 +591,8 @@ and that is a control named
of class
.Dv AudioCmonitor .
.Sh SEE ALSO
-.Xr audio 4
+.Xr audio 4 ,
+.Xr audio 7
.Sh HISTORY
This
.Nm
Index: src/sys/dev/audio.c
diff -u src/sys/dev/audio.c:1.357.2.11 src/sys/dev/audio.c:1.357.2.12
--- src/sys/dev/audio.c:1.357.2.11 Mon Apr 16 14:11:44 2018
+++ src/sys/dev/audio.c Tue May 15 13:42:50 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.357.2.11 2018/04/16 14:11:44 martin Exp $ */
+/* $NetBSD: audio.c,v 1.357.2.12 2018/05/15 13:42:50 martin Exp $ */
/*-
* Copyright (c) 2016 Nathanial Sloss <[email protected]>
@@ -148,7 +148,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.357.2.11 2018/04/16 14:11:44 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.357.2.12 2018/05/15 13:42:50 martin Exp $");
#ifdef _KERNEL_OPT
#include "audio.h"
@@ -3075,7 +3075,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;
@@ -3085,7 +3085,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));
@@ -3099,7 +3102,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:
@@ -4186,6 +4189,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;
}
@@ -4549,6 +4558,10 @@ audiosetinfo(struct audio_softc *sc, str
pp = vc->sc_pparams; /* Temporary encoding storage in */
rp = vc->sc_rparams; /* case setting the modes fails. */
nr = np = 0;
+ setmode = 0;
+
+ if (vc == &sc->sc_mixring)
+ goto done;
if (SPECIFIED(p->sample_rate)) {
pp.sample_rate = p->sample_rate;
@@ -4603,7 +4616,6 @@ audiosetinfo(struct audio_softc *sc, str
if (np > 0 && (error = audio_check_params(&pp)))
return error;
- setmode = 0;
if (nr > 0) {
if (!cleared) {
audio_clear_intr_unlocked(sc, vc);
@@ -4635,9 +4647,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;
@@ -4732,23 +4745,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) {
@@ -4892,8 +4923,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) {
@@ -5775,6 +5811,9 @@ unitscopy(mixer_devinfo_t *di, const cha
static int
audio_query_devinfo(struct audio_softc *sc, mixer_devinfo_t *di)
{
+ struct audio_chan *chan;
+ unsigned int j;
+
KASSERT(mutex_owned(sc->sc_lock));
if (sc->sc_static_nmixer_states == 0 || sc->sc_nmixer_states == 0)
@@ -5790,18 +5829,40 @@ audio_query_devinfo(struct audio_softc *
di->type = AUDIO_MIXER_CLASS;
} else if ((di->index - sc->sc_static_nmixer_states) % 2 == 0) {
di->mixer_class = sc->sc_static_nmixer_states -1;
+ j = 0;
+ SIMPLEQ_FOREACH(chan, &sc->sc_audiochan, entries) {
+ if (j == (di->index -
+ sc->sc_static_nmixer_states) / 2)
+ break;
+ j++;
+ }
+ if (j != (di->index - sc->sc_static_nmixer_states) / 2)
+ return 0;
+
+ j = chan->deschan;
+
snprintf(di->label.name, sizeof(di->label.name),
- AudioNdac"%d",
- (di->index - sc->sc_static_nmixer_states) / 2);
+ AudioNdac"%d", j);
di->type = AUDIO_MIXER_VALUE;
di->next = di->prev = AUDIO_MIXER_LAST;
di->un.v.num_channels = 1;
unitscopy(di, AudioNvolume);
} else {
di->mixer_class = sc->sc_static_nmixer_states -1;
+ j = 0;
+ SIMPLEQ_FOREACH(chan, &sc->sc_audiochan, entries) {
+ if (j == (di->index -
+ sc->sc_static_nmixer_states) / 2)
+ break;
+ j++;
+ }
+ if (j != (di->index - sc->sc_static_nmixer_states) / 2)
+ return 0;
+
+ j = chan->deschan;
+
snprintf(di->label.name, sizeof(di->label.name),
- AudioNmicrophone "%d",
- (di->index - sc->sc_static_nmixer_states) / 2);
+ AudioNmicrophone "%d", j);
di->type = AUDIO_MIXER_VALUE;
di->next = di->prev = AUDIO_MIXER_LAST;
di->un.v.num_channels = 1;
Added files:
Index: src/share/man/man7/audio.7
diff -u /dev/null src/share/man/man7/audio.7:1.2.2.2
--- /dev/null Tue May 15 13:42:51 2018
+++ src/share/man/man7/audio.7 Tue May 15 13:42:49 2018
@@ -0,0 +1,308 @@
+.\" $NetBSD: audio.7,v 1.2.2.2 2018/05/15 13:42:49 martin Exp $
+.\"
+.\" Copyright (c) 2016 - 2018 Nathanial Sloss <[email protected]>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 4, 2018
+.Dt AUDIO 7
+.Os
+.Sh NAME
+.Nm audio
+.Nd the
+.Nx
+in-kernel audio mixer specification
+.Sh INTRODUCTION
+This document aims to describe all aspects of the in-kernel audio mixer
+included with
+.Nx 8
+and onwards, describing its current behavior as of 2018.
+.Sh VIRTUAL CHANNEL (VCHAN)
+This is the most fundamental element to the mixer.
+The vchan has all of the properties of the traditional single open
+.Nx
+audio channel.
+It consists of playback and record rings along with
+.Vt audio_info
+structures.
+.Pp
+Upon opening of
+.Pa /dev/audio
+or
+.Pa /dev/sound ,
+a new vchan and mixerctl structure is created.
+In the case of
+.Pa /dev/sound ,
+.Vt audio_info
+structures are inherited from the last open of
+.Pa /dev/audio
+or
+.Pa /dev/sound .
+.Pp
+All vchans are up or down sampled into the mix ring (intermediate) format
+before being sent to hardware.
+.Pp
+It is described in the following diagram:
+.Bd -literal
+ VCHAN1---------\\
+ \\ VCHAN0
+ VCHAN2-------------MIX RING ---- HARDWARE
+ ... /
+ VCHANn---------/
+.Ed
+.Pp
+In the case of
+.Xr sysctl 8
+.Dv usemixer=0
+(see below), there is only one vchan whose play
+and record rings are the hardware play/record rings.
+.Pp
+User accessible vchans are numbered starting at one (1).
+Vchan 0 is used internally by the mixer for the mix ring and its ring buffers
+are not user accessible.
+.Pp
+The only limit to the number of open vchans is the speed of the computer and the
+number of free file descriptors.
+.Sh BLOCK - SIZE / LATENCY
+A block of audio data is the basic unit for audio data.
+Audio applications will not commence playback until three (3) blocks have been
+written - this is the source of latency in the mixer along with the size of the
+audio data block.
+.Pp
+For normal uses of audio read/write there will be three blocks of audio data before
+playback commences one in the vchan, one in the mix ring and one in the
+hardware ring.
+.Pp
+The size of the audio data block is dependent on the audio format configured
+by the application the latency
+.Xr sysctl 8
+and the underlying audio hardware.
+.Pp
+Some audio hardware devices only support a static block size, as such the
+overall latency of the mixer for these devices cannot be changed.
+Other devices such as those supported by
+.Xr hdaudio 4
+allow the hardware block size
+to be changed, allowing the latency of the mixer to change from 4
+milliseconds (ms) to 128 ms with the mixer intermediate format being 16 bit,
+stereo, 48 kHz.
+.Pp
+With regard to mmapped audio, blocks are played back immediately so the latency
+presented to applications is one third of the latency
+.Xr sysctl 8
+value.
+.Pp
+Latency can be calculated by the following formula:
+.Bd -literal
+ Latency (ms) = blocksize(bytes) * num blocks * 1000
+ --------------------------------------
+ freq(Hz) * bytes per sample * channels
+.Ed
+.Pp
+Latency in the mixer and latency presented to audio applications is consistent,
+it will be the same regardless of the audio format requested by the audio
+application.
+.Pp
+The default latency configured at boot time is 150ms and is subject to the above
+constraints.
+.Sh ADDED IOCTLS
+Two new ioctls have been added to accommodate mixing of multiple vchans:
+.Bl -tag -width indent
+.It Dv AUDIO_SETCHAN :
+Allows setting the target vchan to operate on for subsequent
+.Xr ioctl 2
+calls.
+.It Dv AUDIO_GETCHAN :
+Returns the current vchan number.
+.El
+.Pp
+These ioctls were necessary as some audio applications like to open an
+.Xr audio 4
+device and an
+.Xr audioctl 4
+device so to check on buffer usage and samples played etc.
+.Pp
+As opening an
+.Xr audioctl 4
+device would result in a new vchan being created, these
+ioctls allow setting the target vchan and
+.Vt audio_info
+structure to that of an existing vchan.
+.Sh MIXERCTL INTERFACE / SOFTWARE VOLUME
+Mixerctl structures are allocated when a new vchan is created.
+The mixer control structure allows for setting the software volume for playback -
+.Li vchan.dacN
+or recording -
+.Li vchan.adcN .
+These are 8 bit values and the this value is applied during mixing into the mix
+ring.
+.Pp
+The software volume is applied to all channels (1, 2, 4 etc.) in the vchan and at
+present (2018-05-04) there are no balance controls for user accessible vchans.
+.Pp
+The first vchan corresponds to the
+.Li vchan.dac1/adc1
+mixer controls.
+.Pp
+All vchan mixer controls only have effect upon its own volume and writing to
+.Li outputs.master
+(or equivalent) control is required to change the volume of the hardware.
+.Pp
+Mixer controls are only present whilst the chan is in use and numbering starts
+at one (1).
+Mixer control numbers i.e.
+.Li dac/adc1
+correspond to their vchan number.
+.Sh AUDIOCTL / AUDIO_INFO INTERFACE
+Audioctl allows access to the
+.Vt audio_info
+structure of a given device.
+Due to the audio mixer a
+.Fl p
+flag was added to allow access to a given vchan's
+.Vt audio_info
+structure.
+The values for
+.Fl p
+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.:
+.Pp
+.Dl audioctl -w play.gain=120
+.Dl open /dev/sound this will have an initial software volume level of 120.
+.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
+have been added:
+.Bl -tag -width indent
+.It Li hw.driverN.frequency :
+.It Li hw.driverN.precision :
+.It Li hw.driverN.channels :
+Intermediate mixing format.
+(see below)
+.It Li hw.driverN.latency :
+Expressed in milliseconds.
+(see above)
+.It Li hw.driverN.multiuser :
+Off/On (0/1), defaults to off.
+This
+.Xr sysctl 7
+determines if multiple users are allowed to access the sound hardware.
+The root user is always allowed access (i.e., for wsbell).
+The first user to open the audio device has full control of the audio device
+if this sysctl is set to off.
+There currently is an outstanding PR about affecting a privileged process -
+PR/52627.
+.Pp
+Ideally if root intervenes with the audio device, it should do so unaffected.
+.Pp
+If this control is set to on, then all users' audio data are mixed and all users
+have access to the audio hardware.
+.It Li hw.driverN.usemixer :
+Off/On (0/1), defaults to on.
+This
+.Xr sysctl 7
+enables or disables the audio mixer.
+When set to off, the audio device can support only one vchan.
+This vchan's play and record ring buffers are the hardware ring buffers.
+.Pp
+This option was added to aid older/slower systems where the extra overhead of
+the audio mixer might pose a problem.
+.El
+.Sh INTERMEDIATE / MIXING FORMAT
+The initial concept was to handle incoming audio data similarly to that of a
+superheterodyne radio receiver:
+.Pp
+.Dl RF -> IF -> AF
+.Pp
+So the corresponding mixing concept is:
+.Pp
+.Dl vchan -> mixing format -> hardware
+.Pp
+The
+.Xr sysctl 7 Ns s
+described above determine the format for mixing.
+All vchans are up or down sampled to this format before mixing takes place.
+.Pp
+On most systems this defaults to 16 bit stereo 48kHz.
+The
+.Xr sysctl 7 Ns s
+governing the mixing format may only be changed when there are no
+vchans in use.
+.Pp
+On faster systems the precision (8, 16, 32 bits) may be changed along with the
+sample rate and number of channels (mono, stereo, 4 etc.).
+.Pp
+On older/slower systems utilizing audio mixing, it may be required to lower the
+quality of this format to ease the amount of data processing whilst mixing.
+.Pp
+All possible audio formats (mulaw, alaw, slinear, ulinear, 8, 16, and 32 bit
+precision) are converted for use by the audio mixer.
+.Sh MEMORY MAPPED PLAYBACK
+It is possible to use mmap for audio playback, achieving reduced latency.
+However the audio applications selected format must match the
+mixing/intermediate format (see above).
+.Pp
+It is possible to obtain the
+.Vt audio_info
+for vchan0 which contains the
+intermediate/mixing format to ease applications configuring for mmapped audio.
+.Pp
+At present most applications don't use the mix ring's
+.Vt audio_info
+structure to obtain the requiredplay back parameters and some user
+intervention is required to set the audio format for the application.
+.Sh HARDWARE DRIVER REQUIREMENTS
+Audio mixing requires signed linear support in the host's endianness.
+Driver authors should support slinear_le and slinear_be formats.
+.Pp
+If the audio hardware is intended to be used with the mixer disabled, mulaw 1ch
+8000 hz needs to be supported also.
+.Pp
+This is easily achievable with the auconv framework/filters.
+All new drivers should consider the use of auconv where possible.
+.Sh SEE ALSO
+.Xr audioctl 1 ,
+.Xr mixerctl 1 ,
+.Xr audio 4 ,
+.Xr audio 9
+.Sh AUTHORS
+.An Nathanial Sloss
+.Sh SPECIAL THANKS
+Great appreciation goes to Onno van der Linden, isaki@, maya@, jmcneill@,
+pgoyette@, mrg@, riastradh@ and christos@ \(em without their input, this code would
+not be what it is currently.