Update manpages respond to isaki-audio2 branch.
This commit is contained in:
parent
9beb52efed
commit
b040836639
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.2272 2019/04/27 23:04:31 kamil Exp $
|
||||
# $NetBSD: mi,v 1.2273 2019/05/08 14:25:38 isaki Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
./etc/mtree/set.comp comp-sys-root
|
||||
|
@ -10654,7 +10654,7 @@
|
|||
./usr/share/man/cat9/arpresolve.0 comp-sys-catman .cat
|
||||
./usr/share/man/cat9/atop.0 comp-sys-catman .cat
|
||||
./usr/share/man/cat9/audio.0 comp-sys-catman .cat
|
||||
./usr/share/man/cat9/audio_system.0 comp-sys-catman .cat
|
||||
./usr/share/man/cat9/audio_system.0 comp-sys-catman obsolete
|
||||
./usr/share/man/cat9/autoconf.0 comp-sys-catman .cat
|
||||
./usr/share/man/cat9/bawrite.0 comp-sys-catman .cat
|
||||
./usr/share/man/cat9/bcdtobin.0 comp-sys-catman .cat
|
||||
|
@ -18591,7 +18591,7 @@
|
|||
./usr/share/man/html9/arpresolve.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/atop.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/audio.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/audio_system.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/audio_system.html comp-sys-htmlman obsolete
|
||||
./usr/share/man/html9/autoconf.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/bawrite.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/bcdtobin.html comp-sys-htmlman html
|
||||
|
@ -26631,7 +26631,7 @@
|
|||
./usr/share/man/man9/arpresolve.9 comp-sys-man .man
|
||||
./usr/share/man/man9/atop.9 comp-sys-man .man
|
||||
./usr/share/man/man9/audio.9 comp-sys-man .man
|
||||
./usr/share/man/man9/audio_system.9 comp-sys-man .man
|
||||
./usr/share/man/man9/audio_system.9 comp-sys-man obsolete
|
||||
./usr/share/man/man9/autoconf.9 comp-sys-man .man
|
||||
./usr/share/man/man9/bawrite.9 comp-sys-man .man
|
||||
./usr/share/man/man9/bcdtobin.9 comp-sys-man .man
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: audio.4,v 1.87 2019/02/16 06:50:14 isaki Exp $
|
||||
.\" $NetBSD: audio.4,v 1.88 2019/05/08 14:25:39 isaki Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -66,137 +66,40 @@ accepts the same
|
|||
operations as
|
||||
.Pa /dev/sound ,
|
||||
but no other operations.
|
||||
It can be opened at any time and can be used to manipulate the
|
||||
audio device while it is in use.
|
||||
.Pp
|
||||
.Pa /dev/sound
|
||||
and
|
||||
.Pa /dev/audio
|
||||
can be opened at
|
||||
.Em any
|
||||
time and audio sources of different precision and playback
|
||||
parameters i.e frequency will be mixed and played back simultaneously.
|
||||
.Pp
|
||||
.Pa /dev/audioctl
|
||||
can be used to manipulate the audio device
|
||||
while it is in use.
|
||||
.Sh SAMPLING DEVICES
|
||||
When
|
||||
.Pa /dev/audio
|
||||
is opened, it automatically directs the underlying driver to manipulate
|
||||
monaural 8-bit mu-law samples.
|
||||
In addition, if it is opened read-only
|
||||
(write-only) the device is set to half-duplex record (play) mode with
|
||||
recording (playing) unpaused and playing (recording) paused.
|
||||
is opened, it automatically sets the track to manipulate
|
||||
monaural 8-bit mu-law 8000Hz.
|
||||
When
|
||||
.Pa /dev/sound
|
||||
is opened, it maintains the previous audio sample mode and
|
||||
record/playback mode most recently set on
|
||||
.Pa /dev/sound
|
||||
by any open channel.
|
||||
is opened, it maintains the audio format and pause/unpause
|
||||
state of the most recently opened track.
|
||||
In all other respects
|
||||
.Pa /dev/audio
|
||||
and
|
||||
.Pa /dev/sound
|
||||
are identical.
|
||||
.Sh VIRTUAL CHANNELS
|
||||
Any process may open a sampling device at a given time.
|
||||
Any number of devices per process and file descriptors may be shared between
|
||||
processes.
|
||||
.Pp
|
||||
Virtual channels are converted to a common format, signed linear encoding,
|
||||
frequency channels and precision.
|
||||
These can be modified to taste by the following
|
||||
.Xr sysctl 8
|
||||
variables:
|
||||
.Bl -tag -width "hw.driverN.precision" -compact -offset indent
|
||||
.It Li hw. Ns Ar driverN Ns Li .precision
|
||||
.It Li hw. Ns Ar driverN Ns Li .frequency
|
||||
.It Li hw. Ns Ar driverN Ns Li .channels
|
||||
.It Li hw. Ns Ar driverN Ns Li .latency
|
||||
.It Li hw. Ns Ar driverN Ns Li .multiuser
|
||||
.El
|
||||
.Pp
|
||||
Where
|
||||
.Ar driverN
|
||||
corresponds to the underlying audio device driver and device number.
|
||||
E.g. in the case of an
|
||||
.\" XXX: there's no hdafg(4) to xref to
|
||||
.Xr hdaudio 4
|
||||
supported device the variables would be:
|
||||
.Li hw.hdafg0.channels ,
|
||||
.Li hw.hdafg0.precision ,
|
||||
.Li hw.hdafg0.frequency .
|
||||
.Pp
|
||||
For best results, values close to the underlying hardware should be chosen.
|
||||
These variables may only be changed when the sampling device is not in use.
|
||||
.Pp
|
||||
The
|
||||
.Li hw. Ns Ar driverN Ns Li .latency
|
||||
.Xr sysctl 8
|
||||
variable controls the latency of the in-kernel mixer by varying the hardware
|
||||
blocksize.
|
||||
It accepts a value in milliseconds(ms), fractional values are not allowed.
|
||||
A value of zero will default to 150ms.
|
||||
.Pp
|
||||
If a static blocksize is enforced by the underlying hardware driver this value
|
||||
cannot be changed.
|
||||
.Pp
|
||||
For audio applications that do not specify a preferred blocksize when configuring
|
||||
the audio device, this will be the latency these applications have.
|
||||
.Pp
|
||||
For audio applications that
|
||||
.Xr mmap 2
|
||||
the audio device for play back the resultant latency is a third (1/3) of the value
|
||||
of the
|
||||
.Li hw. Ns Ar driverN Ns Li .latency
|
||||
variable.
|
||||
.Pp
|
||||
The
|
||||
.Li hw. Ns Ar driverN Ns Li .multiuser
|
||||
.Xr sysctl 8
|
||||
variable determines if multiple users are allowed to access the sampling
|
||||
device.
|
||||
.Pp
|
||||
By default it is set to false.
|
||||
This means that the sampling device may be only used by
|
||||
.Em one
|
||||
user at a time.
|
||||
Other users (except root) attempting to open the sampling device will be
|
||||
denied.
|
||||
.Pp
|
||||
If set to true, all users may access the sampling device at any time.
|
||||
.Pp
|
||||
Each virtual channel has a corresponding mixer:
|
||||
.Bl -tag -width "vchan.dacN" -compact -offset indent
|
||||
.It Li vchan.dac Ns Ar N
|
||||
Output volume
|
||||
.It Li vchan.mic Ns Ar N
|
||||
Recording volume
|
||||
.El
|
||||
.Pp
|
||||
Where
|
||||
.Ar N
|
||||
is the virtual channel number.
|
||||
E.g.\&
|
||||
.Li vchan.dac0
|
||||
controlling playback volume and
|
||||
.Li vchan.mic0
|
||||
controlling recording volume for the first virtual channel.
|
||||
.Pp
|
||||
On a half-duplex device, writes while recording is in progress will be
|
||||
immediately discarded.
|
||||
Similarly, reads while playback is in progress
|
||||
will be filled with silence but delayed to return at the current
|
||||
sampling rate.
|
||||
If both playback and recording are requested on a half-duplex
|
||||
device, playback mode takes precedence and recordings will get silence.
|
||||
.Pp
|
||||
On a full-duplex device, reads and writes may operate
|
||||
concurrently without interference.
|
||||
On a full-duplex device, reads and writes may operate concurrently
|
||||
without interference.
|
||||
If a full-duplex capable audio device is opened for both reading and writing
|
||||
it will start in half-duplex play mode; full-duplex mode has to be set
|
||||
explicitly.
|
||||
it will start in play mode but not start in record mode.
|
||||
.Pp
|
||||
On either type of device, if the playback mode is paused then silence is
|
||||
On a half-duplex device, if there are any recording descriptors already,
|
||||
opening with write mode will fail.
|
||||
Similarly, if there are any playback descriptors already,
|
||||
opening with read mode will fail.
|
||||
If both playback and recording are requested on a half-duplex device,
|
||||
it will be treated as playback mode.
|
||||
.Pp
|
||||
On either type of device, opening with write mode will start in playback mode,
|
||||
opening with read mode will start in recording mode.
|
||||
.Pp
|
||||
If the playback mode is paused then silence is
|
||||
played instead of the provided samples, and if recording is paused then
|
||||
the process blocks in
|
||||
.Xr read 2
|
||||
|
@ -206,46 +109,55 @@ If a writing process does not call
|
|||
.Xr write 2
|
||||
frequently enough to provide samples at the pace the hardware
|
||||
consumes them silence is inserted.
|
||||
If the
|
||||
.Dv AUMODE_PLAY_ALL
|
||||
mode is not set the writing process must
|
||||
provide enough data via
|
||||
subsequent write calls to
|
||||
.Dq catch up
|
||||
in time to the current audio
|
||||
block before any more process-provided samples will be played.
|
||||
If a reading process does not call
|
||||
.Xr read 2
|
||||
frequently enough, it will simply miss samples.
|
||||
.Pp
|
||||
The audio driver supports track multiplexing.
|
||||
All sampling devices can be opened at any time without interference.
|
||||
For playback, all tracks opened simultaneously are mixed,
|
||||
even if thier specified format is different.
|
||||
For recording, recorded data is distributed to all opened tracks,
|
||||
even if thier specified format is different.
|
||||
To achieve this, the audio driver has an small efficient encoding converter,
|
||||
a channel mixer, and a frequency conveter.
|
||||
The frequency conversion adapts the simplest way
|
||||
(interpolation method for upward, and simple thinning method for downward)
|
||||
due to restriction in kernel resources and processing time.
|
||||
It will work well in most case but don't expect excessively for its quality.
|
||||
.Pp
|
||||
The audio device is normally accessed with
|
||||
.Xr read 2
|
||||
or
|
||||
.Xr write 2
|
||||
calls, but it can also be mapped into user memory with
|
||||
.Xr mmap 2
|
||||
.Xr mmap 2 .
|
||||
Once the device has been mapped it can no longer be accessed
|
||||
by read or write; all access is by reading and writing to
|
||||
the mapped memory.
|
||||
The device appears as a block of memory
|
||||
of size
|
||||
The mmap'ped buffer appears as a block of memory of size
|
||||
.Va buffersize
|
||||
(as available via
|
||||
.Dv AUDIO_GETINFO
|
||||
or
|
||||
.Dv AUDIO_GETBUFINFO ) .
|
||||
The device driver will continuously move data from this buffer
|
||||
from/to the audio hardware, wrapping around at the end of the buffer.
|
||||
The audio driver will continuously move data from this buffer
|
||||
from/to the mixing buffer, wrapping around at the end of the buffer.
|
||||
To find out where the hardware is currently accessing data in the buffer the
|
||||
.Dv AUDIO_GETIOFFS
|
||||
and
|
||||
.Dv AUDIO_GETOOFFS
|
||||
calls can be used.
|
||||
The playing and recording buffers are distinct and must be
|
||||
mapped separately if both are to be used.
|
||||
Only encodings that are not emulated (i.e. where
|
||||
Note that
|
||||
.Xr mmap 2
|
||||
no longer maps hardware buffer directly.
|
||||
Now it is achieved by emulation so don't expect any improvements excessively
|
||||
rather than normal
|
||||
.Xr write 2 .
|
||||
For historical reasons, only encodings that are not set
|
||||
.Dv AUDIO_ENCODINGFLAG_EMULATED
|
||||
is not set) work properly for a mapped device.
|
||||
is able to
|
||||
.Xr mmap 2 .
|
||||
.Pp
|
||||
The audio device, like most devices, can be used in
|
||||
.Xr select 2 ,
|
||||
|
@ -262,26 +174,23 @@ The following
|
|||
.Xr ioctl 2
|
||||
commands are supported on the sample devices:
|
||||
.Bl -tag -width indent
|
||||
.It Dv AUDIO_GETCHAN (int)
|
||||
This command will return the audio channel in use.
|
||||
.It Dv AUDIO_SETCHAN (int)
|
||||
This command will select the audio channel for subsequent ioctl calls.
|
||||
.It Dv AUDIO_FLUSH
|
||||
This command stops all playback and recording, clears all queued
|
||||
buffers, resets error counters, and restarts recording and playback as
|
||||
buffers, resets error counters on this track,
|
||||
and restarts recording and playback as
|
||||
appropriate for the current sampling mode.
|
||||
.It Dv AUDIO_PERROR (int)
|
||||
.It Dv AUDIO_RERROR (int)
|
||||
This command fetches the count of dropped output (input)
|
||||
samples into its integer argument.
|
||||
bytes into its integer argument.
|
||||
There is no information regarding when in the sample stream
|
||||
they were dropped.
|
||||
.It Dv AUDIO_WSEEK (u_long)
|
||||
This command fetches the count of samples that are queued ahead of the
|
||||
This command fetches the count of bytes that are queued ahead of the
|
||||
first sample in the most recent sample block written into its integer argument.
|
||||
.It Dv AUDIO_DRAIN
|
||||
This command suspends the calling process until all queued playback
|
||||
samples have been played by the hardware.
|
||||
samples have been played.
|
||||
.It Dv AUDIO_GETDEV (audio_device_t)
|
||||
This command fetches the current hardware device information into the
|
||||
.Vt audio_device_t
|
||||
|
@ -296,6 +205,8 @@ typedef struct audio_device {
|
|||
.It Dv AUDIO_GETENC (audio_encoding_t)
|
||||
This command is used iteratively to fetch sample encoding names and
|
||||
format ids into the input/output audio_encoding_t argument.
|
||||
The encoding returned by the command is user accessible encoding and
|
||||
is not hardware supported encoding.
|
||||
.Bd -literal
|
||||
typedef struct audio_encoding {
|
||||
int index; /* input: nth encoding */
|
||||
|
@ -312,13 +223,9 @@ all the supported encodings, start with an index field of 0 and
|
|||
continue with successive encodings (1, 2, ...) until the command returns
|
||||
an error.
|
||||
.It Dv AUDIO_GETFD (int)
|
||||
The command returns the current setting of the full duplex mode.
|
||||
This command is obsoleted.
|
||||
.It Dv AUDIO_SETFD (int)
|
||||
This command sets the device into full-duplex operation if its integer
|
||||
argument has a non-zero value, or into half-duplex operation if it
|
||||
contains a zero value.
|
||||
If the device does not support full-duplex
|
||||
operation, attempting to set full-duplex mode returns an error.
|
||||
This command is obsoleted.
|
||||
.It Dv AUDIO_GETPROPS (int)
|
||||
This command gets a bit set of hardware properties.
|
||||
If the hardware
|
||||
|
@ -342,7 +249,7 @@ the device is capable of audio capture.
|
|||
.It Dv AUDIO_GETIOFFS (audio_offset_t)
|
||||
.It Dv AUDIO_GETOOFFS (audio_offset_t)
|
||||
This command fetches the current offset in the input(output) buffer where
|
||||
the audio hardware's DMA engine will be putting(getting) data.
|
||||
the track mixer will be putting(getting) data.
|
||||
It mostly useful when the device
|
||||
buffer is available in user space via the
|
||||
.Xr mmap 2
|
||||
|
@ -361,20 +268,22 @@ typedef struct audio_offset {
|
|||
.It Dv AUDIO_GETBUFINFO (audio_info_t)
|
||||
.It Dv AUDIO_SETINFO (audio_info_t)
|
||||
Get or set audio information as encoded in the audio_info structure.
|
||||
For historical reasons, the audio_info structure has three different
|
||||
layer's parameters: track, track mixer and hardware rich mixer.
|
||||
.Bd -literal
|
||||
typedef struct audio_info {
|
||||
struct audio_prinfo play; /* info for play (output) side */
|
||||
struct audio_prinfo record; /* info for record (input) side */
|
||||
u_int monitor_gain; /* input to output mix */
|
||||
u_int monitor_gain; /* input to output mix [HWmixer] */
|
||||
/* BSD extensions */
|
||||
u_int blocksize; /* H/W read/write block size */
|
||||
u_int hiwat; /* output high water mark */
|
||||
u_int lowat; /* output low water mark */
|
||||
u_int blocksize; /* read/write block size [track] */
|
||||
u_int hiwat; /* output high water mark [track] */
|
||||
u_int lowat; /* output low water mark [track] */
|
||||
u_int _ispare1;
|
||||
u_int mode; /* current device mode */
|
||||
u_int mode; /* current operation mode [track] */
|
||||
#define AUMODE_PLAY 0x01
|
||||
#define AUMODE_RECORD 0x02
|
||||
#define AUMODE_PLAY_ALL 0x04 /* do not do real-time correction */
|
||||
#define AUMODE_PLAY_ALL 0x04 /* Not used anymore */
|
||||
} audio_info_t;
|
||||
.Ed
|
||||
.Pp
|
||||
|
@ -392,13 +301,14 @@ first.
|
|||
.Pp
|
||||
The
|
||||
.Va mode
|
||||
field should be set to
|
||||
.Dv AUMODE_PLAY ,
|
||||
.Dv AUMODE_RECORD ,
|
||||
.Dv AUMODE_PLAY_ALL ,
|
||||
or a bitwise OR combination of the three.
|
||||
Only full-duplex audio devices support
|
||||
simultaneous record and playback.
|
||||
field indicates current operation mode, either one of
|
||||
.Dv AUMODE_PLAY
|
||||
or
|
||||
.Dv AUMODE_RECORD .
|
||||
These two flags can not be changed once this descriptor is opened.
|
||||
On playback mode, obsoleted
|
||||
.Dv AUMODE_PLAY_ALL
|
||||
can be set but has no effect.
|
||||
.Pp
|
||||
.Va hiwat
|
||||
and
|
||||
|
@ -423,41 +333,40 @@ sets the current audio blocksize.
|
|||
The generic audio driver layer and the hardware driver have the
|
||||
opportunity to adjust this block size to get it within
|
||||
implementation-required limits.
|
||||
Upon return from an
|
||||
.Dv AUDIO_SETINFO
|
||||
call, the actual blocksize set is returned in this field.
|
||||
Normally the
|
||||
.Va blocksize
|
||||
is calculated to correspond to 50ms of sound and it is recalculated
|
||||
when the encoding parameter changes, but if the
|
||||
is calculated to correspond to 40ms
|
||||
(For some hardware, this value may be different due to
|
||||
the hardware restrictions)
|
||||
of sound and it is recalculated
|
||||
when the encoding parameter changes.
|
||||
If the descriptor is opened for read only,
|
||||
.Va blocksize
|
||||
is set explicitly this value becomes sticky, i.e. it remains
|
||||
even when the encoding is changed.
|
||||
The stickiness can be cleared by reopening the device or setting the
|
||||
indicates the blocksize on recording track.
|
||||
Otherwise,
|
||||
.Va blocksize
|
||||
to 0.
|
||||
indicates the blocksize on playback track.
|
||||
.Bd -literal
|
||||
struct audio_prinfo {
|
||||
u_int sample_rate; /* sample rate in samples/s */
|
||||
u_int channels; /* number of channels, usually 1 or 2 */
|
||||
u_int precision; /* number of bits/sample */
|
||||
u_int encoding; /* data encoding (AUDIO_ENCODING_* below) */
|
||||
u_int gain; /* volume level */
|
||||
u_int port; /* selected I/O port */
|
||||
u_long seek; /* BSD extension */
|
||||
u_int avail_ports; /* available I/O ports */
|
||||
u_int buffer_size; /* total size audio buffer */
|
||||
u_int sample_rate; /* sample rate in samples/s [track] */
|
||||
u_int channels; /* number of channels, usually 1 or 2 [track] */
|
||||
u_int precision; /* number of bits/sample [track] */
|
||||
u_int encoding; /* data encoding (AUDIO_ENCODING_* below) [track] */
|
||||
u_int gain; /* volume level [HWmixer] */
|
||||
u_int port; /* selected I/O port [HWmixer] */
|
||||
u_long seek; /* BSD extension [track] */
|
||||
u_int avail_ports; /* available I/O ports [HWmixer] */
|
||||
u_int buffer_size; /* total size audio buffer [track] */
|
||||
u_int _ispare[1];
|
||||
/* Current state of device: */
|
||||
u_int samples; /* number of samples */
|
||||
u_int eof; /* End Of File (zero-size writes) counter */
|
||||
u_char pause; /* non-zero if paused, zero to resume */
|
||||
u_char error; /* non-zero if underflow/overflow occurred */
|
||||
u_char waiting; /* non-zero if another process hangs in open */
|
||||
u_char balance; /* stereo channel balance */
|
||||
u_int samples; /* number of samples [track] */
|
||||
u_int eof; /* End Of File (zero-size writes) counter [track] */
|
||||
u_char pause; /* non-zero if paused, zero to resume [track] */
|
||||
u_char error; /* non-zero if underflow/overflow occurred [track] */
|
||||
u_char waiting; /* non-zero if another process hangs in open [track] */
|
||||
u_char balance; /* stereo channel balance [HWmixer] */
|
||||
u_char cspare[2];
|
||||
u_char open; /* non-zero if currently open */
|
||||
u_char active; /* non-zero if I/O is currently active */
|
||||
u_char open; /* non-zero if currently open [trackmixer] */
|
||||
u_char active; /* non-zero if I/O is currently active [trackmixer] */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
|
@ -494,6 +403,13 @@ unsigned linear encoding with big endian byte order
|
|||
Dolby Digital AC3
|
||||
.El
|
||||
.Pp
|
||||
Regardless of format supported by underlying driver,
|
||||
audio driver accepts following formats.
|
||||
encoding and precision is one of those obtained by
|
||||
.Dv AUDIO_GETENC .
|
||||
channels ranges from 1 to 12.
|
||||
frequency ranges from 1000Hz to 192000Hz.
|
||||
.Pp
|
||||
The
|
||||
.Va gain ,
|
||||
.Va port
|
||||
|
@ -556,7 +472,7 @@ and
|
|||
.Dv AUDIO_GETBUFINFO .
|
||||
.Va seek
|
||||
represents the count of
|
||||
samples pending;
|
||||
bytes pending;
|
||||
.Va samples
|
||||
represents the total number of bytes recorded or played, less those
|
||||
that were dropped due to inadequate consumption/production rates.
|
||||
|
@ -567,6 +483,54 @@ For
|
|||
.Dv AUDIO_SETINFO ,
|
||||
if the pause value is specified it will either pause
|
||||
or unpause the particular direction.
|
||||
.It Dv AUDIO_QUERYFORMAT (audio_format_query_t)
|
||||
This command enumerates formats supported by the hardware.
|
||||
Similarly to
|
||||
.Dv AUDIO_GETENC ,
|
||||
to query all the supported formats,
|
||||
start with an index field of 0 and continue with successive formats
|
||||
(1, 2, ...) until the command returns an error.
|
||||
.Bd -literal
|
||||
typedef struct audio_format_query {
|
||||
u_int index;
|
||||
struct audio_format fmt;
|
||||
} audio_format_query_t;
|
||||
.Ed
|
||||
.It Dv AUDIO_GETFORMAT (audio_info_t)
|
||||
This command fetches the current hardware format.
|
||||
Only following members in audio_info_t are used.
|
||||
Members which is not listed here or belong in invalid direction are
|
||||
filled by -1.
|
||||
.\" XXX I want something like <ul> on HTML...
|
||||
.Bd -literal
|
||||
mode
|
||||
play.encoding
|
||||
play.precision
|
||||
play.channels
|
||||
play.sample_rate
|
||||
record.encoding
|
||||
record.precision
|
||||
record.channels
|
||||
record.sample_rate
|
||||
.Ed
|
||||
.Pp
|
||||
.Va mode
|
||||
indicates which direction is valid.
|
||||
.It Dv AUDIO_SETFORMAT (audio_info_t)
|
||||
This command sets the hardware format.
|
||||
It will fail if there are any opened descriptors.
|
||||
So obviously, it must be issued on
|
||||
.Pa /dev/audioctl .
|
||||
Similarly to
|
||||
.Dv AUDIO_GETFORMAT ,
|
||||
only above members in audio_info_t are used.
|
||||
Members which is not listed or belong in invalid direction are ignored.
|
||||
The parameters can be chosen from the choices obtained by
|
||||
.Dv AUDIO_QUERYFORMAT .
|
||||
.It Dv AUDIO_GETCHAN (int)
|
||||
This command is obsoleted.
|
||||
.It Dv AUDIO_SETCHAN (int)
|
||||
This command is obsoleted.
|
||||
.El
|
||||
.Sh MIXER DEVICE
|
||||
The mixer device,
|
||||
|
@ -773,13 +737,13 @@ string values.
|
|||
.It Pa /dev/mixer
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr audiocfg 1 ,
|
||||
.Xr audioctl 1 ,
|
||||
.Xr mixerctl 1 ,
|
||||
.Xr ioctl 2 ,
|
||||
.Xr ossaudio 3 ,
|
||||
.Xr midi 4 ,
|
||||
.Xr radio 4 ,
|
||||
.Xr sysctl 8
|
||||
.Ss ISA bus
|
||||
.Xr aria 4 ,
|
||||
.Xr ess 4 ,
|
||||
|
@ -812,8 +776,10 @@ string values.
|
|||
.Xr bba 4
|
||||
.Ss USB
|
||||
.Xr uaudio 4
|
||||
.Ss The NetBSD audio specification
|
||||
.Xr audio_system 9
|
||||
.Sh HISTORY
|
||||
Support for virtual channels and mixing first appeared in
|
||||
.Nx 8.0 .
|
||||
.Sh BUGS
|
||||
If the device is used in
|
||||
.Xr mmap 2
|
||||
it is currently always mapped for writing (playing) due to VM system weirdness.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.436 2019/04/06 03:06:24 thorpej Exp $
|
||||
# $NetBSD: Makefile,v 1.437 2019/05/08 14:25:39 isaki Exp $
|
||||
|
||||
# Makefile for section 9 (kernel function and variable) manual pages.
|
||||
|
||||
MAN= accept_filter.9 accf_data.9 accf_http.9 \
|
||||
altq.9 arp.9 audio.9 audio_system.9 autoconf.9 \
|
||||
altq.9 arp.9 audio.9 autoconf.9 \
|
||||
bcdtobin.9 bcmp.9 bcopy.9 bintime_add.9 bluetooth.9 boothowto.9 bpf.9 \
|
||||
buffercache.9 bufferio.9 bufq.9 bus_dma.9 bus_space.9 byteorder.9 \
|
||||
bzero.9 \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: audio.9,v 1.51 2019/02/16 07:00:56 wiz Exp $
|
||||
.\" $NetBSD: audio.9,v 1.52 2019/05/08 14:25:39 isaki Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -44,12 +44,11 @@ structure.
|
|||
struct audio_hw_if {
|
||||
int (*open)(void *, int);
|
||||
void (*close)(void *);
|
||||
int (*drain)(void *);
|
||||
|
||||
int (*query_encoding)(void *, struct audio_encoding *);
|
||||
int (*set_params)(void *, int, int,
|
||||
audio_params_t *, audio_params_t *,
|
||||
stream_filter_list_t *, stream_filter_list_t *);
|
||||
int (*query_format)(void *, audio_format_query_t *);
|
||||
int (*set_format)(void *, int,
|
||||
const audio_params_t *, const audio_params_t *,
|
||||
audio_filter_reg_t *, audio_filter_reg_t *);
|
||||
int (*round_blocksize)(void *, int, int, const audio_params_t *);
|
||||
|
||||
int (*commit_settings)(void *);
|
||||
|
@ -68,7 +67,6 @@ struct audio_hw_if {
|
|||
#define SPKR_OFF 0
|
||||
|
||||
int (*getdev)(void *, struct audio_device *);
|
||||
int (*setfd)(void *, int);
|
||||
|
||||
int (*set_port)(void *, mixer_ctrl_t *);
|
||||
int (*get_port)(void *, mixer_ctrl_t *);
|
||||
|
@ -78,7 +76,6 @@ struct audio_hw_if {
|
|||
void *(*allocm)(void *, int, size_t);
|
||||
void (*freem)(void *, void *, size_t);
|
||||
size_t (*round_buffersize)(void *, int, size_t);
|
||||
paddr_t (*mappage)(void *, void *, off_t, int);
|
||||
|
||||
int (*get_props)(void *);
|
||||
|
||||
|
@ -130,6 +127,15 @@ the hardware request another block a block of silence will be used instead.
|
|||
Furthermore, if the user process does not read data quickly enough during
|
||||
recording data will be thrown away.
|
||||
.Pp
|
||||
The phase that these functions are called is classified into three.
|
||||
Attach phase, Closed phase and Opened phase.
|
||||
Attach phase is during device attach and
|
||||
it transits to the Closed phase when the attach succeeded.
|
||||
Closed phase is when no sampling device is opened and
|
||||
it transits to the Opened phase when open succeeded.
|
||||
Opened phase is when any sampling device is opened and
|
||||
it transits to the Closed phase when close succeeded.
|
||||
.Pp
|
||||
The fields of
|
||||
.Va audio_hw_if
|
||||
are described in some more detail below.
|
||||
|
@ -138,147 +144,173 @@ Some fields are optional and can be set to
|
|||
if not needed.
|
||||
.Bl -tag -width indent
|
||||
.It Dv int open(void *hdl, int flags)
|
||||
optional, is called when the audio device is opened.
|
||||
It should initialize the hardware for I/O.
|
||||
optional, is called when the first device combining playback and recording
|
||||
is opened.
|
||||
On a full duplex hardware,
|
||||
.Dv (FREAD | FWRITE)
|
||||
is passed to flags.
|
||||
On a half duplex hardware,
|
||||
.Dv FWRITE
|
||||
is passed for playback, or
|
||||
.Dv FREAD
|
||||
for recording.
|
||||
Every successful call to
|
||||
.Va open
|
||||
is matched by a call to
|
||||
.Va close .
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Closed phase.
|
||||
.It Dv void close(void *hdl)
|
||||
optional, is called when the audio device is closed.
|
||||
.It Dv int drain(void *hdl)
|
||||
optional, is called before the device is closed or when
|
||||
.Dv AUDIO_DRAIN
|
||||
is called.
|
||||
It should make sure that no samples remain in to be played that could
|
||||
be lost when
|
||||
.Va close
|
||||
is called.
|
||||
Return 0 on success, otherwise an error code.
|
||||
.It Dv int query_encoding(void *hdl, struct audio_encoding *ae)
|
||||
is used when
|
||||
.Dv AUDIO_GETENC
|
||||
is called.
|
||||
It should fill the
|
||||
.Va audio_encoding
|
||||
structure and return 0 or, if there is no encoding with the
|
||||
given number, return EINVAL.
|
||||
.It Dv int set_params(void *hdl, int setmode, int usemode,
|
||||
.Dv "audio_params_t *play, audio_params_t *rec,"
|
||||
optional, is called when the last audio device combining
|
||||
playback and recording is closed.
|
||||
It is called at Opened phase.
|
||||
.It Dv int query_format(void *hdl, audio_format_query_t *afp)
|
||||
is called to enumerate formats supported by the hardware.
|
||||
It should fill the audio_format_t structure according to given number
|
||||
afp->index.
|
||||
If there is no format with given number, return EINVAL.
|
||||
It is called at any time.
|
||||
.Bd -literal
|
||||
typedef struct audio_format_query {
|
||||
u_int index;
|
||||
struct audio_format fmt;
|
||||
} audio_format_query_t;
|
||||
.Ed
|
||||
.Pp
|
||||
.Dv "stream_filter_list_t *pfil, stream_filter_list_t *rfil)"
|
||||
It is also used to determine the default format.
|
||||
The upper layer chooses the most preferred one as default format by following:
|
||||
.\" XXX I don't know syntax to represent <OL> in html
|
||||
1. Higher priority is preferred (normally 0, the highest is 3, the lowest is 0).
|
||||
2. AUDIO_ENCODING_SLINEAR_NE:16 is preferred if exists.
|
||||
3. AUDIO_ENCODING_SLINEAR_OE:16 is preferred if exists.
|
||||
4. More channels is preferred.
|
||||
.Pp
|
||||
Called to set the audio encoding mode.
|
||||
If the driver supports SLINEAR_NE:16 and the upper layer chooses it,
|
||||
the driver does not need to provide conversion function in
|
||||
.Va set_format .
|
||||
Similarly, if the driver supports SLINEAR_OE:16 and the upper layer chooses it,
|
||||
the driver does not need to provide conversion function.
|
||||
Because the upper layer only supports conversion between
|
||||
SLINEAR_NE:16 and SLINEAR_OE:16 for convenience.
|
||||
If the upper layer chooses other format,
|
||||
the driver needs to provide conversion function in
|
||||
.Va set_format .
|
||||
See also
|
||||
.Va set_format .
|
||||
If the driver can not provide the conversion from/to SLINEAR_NE:16,
|
||||
set priority to -1.
|
||||
It means that the hardware supports this format but the driver does not
|
||||
(e.g. AC3), and it will never be chosen.
|
||||
.It Dv int set_foramt(void *hdl, int setmode,
|
||||
.Dv "const audio_params_t *play, const audio_params_t *rec,"
|
||||
.Dv "audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)"
|
||||
.Pp
|
||||
is called to set specified format to the hardware,
|
||||
when the device is attached or the hardware format is changed.
|
||||
.Va setmode
|
||||
is a combination of the
|
||||
.Dv AUMODE_RECORD
|
||||
and
|
||||
.Dv AUMODE_PLAY
|
||||
flags to indicate which mode(s) are to be set.
|
||||
.Va usemode
|
||||
is also a combination of these flags, but indicates the current
|
||||
mode of the device (i.e., the value of
|
||||
.Va mode
|
||||
in the
|
||||
.Va audio_info
|
||||
struct).
|
||||
flags to indicate which modes are to be set.
|
||||
.Pp
|
||||
The
|
||||
.Va play
|
||||
and
|
||||
.Va rec
|
||||
structures contain the encoding parameters that should be set.
|
||||
The values of the structures may also be modified if the hardware
|
||||
cannot be set to exactly the requested mode (e.g., if the requested
|
||||
sampling rate is not supported, but one close enough is).
|
||||
.Pp
|
||||
If the hardware requires software assistance with some encoding
|
||||
(e.g., it might be lacking mu-law support) it should fill the
|
||||
structures contain the encoding parameters that should be set to the hardware.
|
||||
If the driver has query_format interface,
|
||||
all parameters on
|
||||
.Va play
|
||||
and/or
|
||||
.Va rec
|
||||
are chosen from formats returned by query_format.
|
||||
Therefore
|
||||
.Va play
|
||||
and/or
|
||||
.Va rec
|
||||
are always settable.
|
||||
If the driver does not have query_format interface,
|
||||
the driver has to validate the format.
|
||||
If the hardware does not support
|
||||
.Dv AUDIO_ENCODING_SLINEAR_{NE,OE}:16 ,
|
||||
conversion information should be filled the
|
||||
.Va pfil
|
||||
for playing or
|
||||
.Va rfil
|
||||
for recording with conversion information.
|
||||
For example, if
|
||||
.Va play
|
||||
requests [8000Hz, mu-law, 8/8bit, 1ch] and the hardware does not
|
||||
support 8bit mu-law, but 16bit slinear_le, the driver should call
|
||||
.Dv pfil->append()
|
||||
with
|
||||
.Va pfil ,
|
||||
.Va mulaw_to_linear16 ,
|
||||
and audio_params_t representing [8000Hz, slinear_le, 16/16bit, 2ch].
|
||||
If the driver needs multiple conversions, a conversion nearest to the
|
||||
hardware should be set to the head of
|
||||
.Va pfil
|
||||
or
|
||||
.Va rfil .
|
||||
The definition of
|
||||
.Dv stream_filter_list_t
|
||||
follows:
|
||||
for recording.
|
||||
The definition of audio_filter_reg_t and related structure follow:
|
||||
.Bd -literal
|
||||
typedef struct stream_filter_list {
|
||||
void (*append)(struct stream_filter_list *,
|
||||
stream_filter_factory_t,
|
||||
const audio_params_t *);
|
||||
void (*prepend)(struct stream_filter_list *,
|
||||
stream_filter_factory_t,
|
||||
const audio_params_t *);
|
||||
void (*set)(struct stream_filter_list *, int,
|
||||
stream_filter_factory_t,
|
||||
const audio_params_t *);
|
||||
int req_size;
|
||||
struct stream_filter_req {
|
||||
stream_filter_factory_t *factory;
|
||||
audio_params_t param; /* from-param for recording,
|
||||
to-param for playing */
|
||||
} filters[AUDIO_MAX_FILTERS];
|
||||
} stream_filter_list_t;
|
||||
typedef struct {
|
||||
const void *src;
|
||||
const audio_format2_t *srcfmt;
|
||||
void *dst;
|
||||
const audio_format2_t *dstfmt;
|
||||
int count;
|
||||
void *context;
|
||||
} audio_filter_arg_t;
|
||||
|
||||
typedef void(*audio_filter_t)(audio_filter_arg_t *arg);
|
||||
|
||||
typedef struct {
|
||||
audio_filter_t codec;
|
||||
void *context;
|
||||
} audio_filter_reg_t;
|
||||
.Ed
|
||||
.Pp
|
||||
For playing,
|
||||
.Va pfil
|
||||
constructs conversions as follows:
|
||||
.Bd -literal
|
||||
(play) == write(2) input
|
||||
| pfil->filters[pfil->req_size-1].factory
|
||||
(pfil->filters[pfil->req_size-1].param)
|
||||
| pfil->filters[pfil->req_size-2].factory
|
||||
:
|
||||
| pfil->filters[1].factory
|
||||
(pfil->filters[1].param)
|
||||
| pfil->filters[0].factory
|
||||
(pfil->filters[0].param) == hardware input
|
||||
.Ed
|
||||
.Va codec
|
||||
is conversion function and
|
||||
.Va context
|
||||
is optional opaque pointer passed to
|
||||
.Va codec .
|
||||
.Pp
|
||||
For recording,
|
||||
.Va rfil
|
||||
constructs conversions as follows:
|
||||
.Bd -literal
|
||||
(rfil->filters[0].param) == hardware output
|
||||
| rfil->filters[0].factory
|
||||
(rfil->filters[1].param)
|
||||
| rfil->filters[1].factory
|
||||
:
|
||||
| rfil->filters[rfil->req_size-2].factory
|
||||
(rfil->filters[rfil->req_size-1].param)
|
||||
| rfil->filters[rfil->req_size-1].factory
|
||||
(rec) == read(2) output
|
||||
.Ed
|
||||
When
|
||||
.Va codec
|
||||
is called, all parameters required by
|
||||
.Va codec
|
||||
are contained in
|
||||
.Va arg .
|
||||
.Va src
|
||||
points input buffer block,
|
||||
.Va srcfmt
|
||||
contains input encoding parameter,
|
||||
.Va dst
|
||||
points output buffer block and
|
||||
.Va dstfmt
|
||||
contains output encoding parameter.
|
||||
.Va count
|
||||
represents the number of frames to process on this call.
|
||||
.Va src
|
||||
and
|
||||
.Va dst
|
||||
are guaranteed to be able to consecutively access number of frames
|
||||
specified by
|
||||
.Va count.
|
||||
.Va codec
|
||||
must fill entire
|
||||
.Va dst .
|
||||
For example, let count = 100, srcfmt is { precision = 16, channels = 3 },
|
||||
dstfmt is { precision = 8, channels = 4 },
|
||||
in this case,
|
||||
src block length = 2(bytes) * 3(channels) * 100(frames) = 600 bytes,
|
||||
The length to be written to
|
||||
.Va dst
|
||||
block is 1(byte) * 4(channels) * 100(frames) = 400 bytes.
|
||||
.Va codec
|
||||
cannot abort the conversion halfway and there is no error reporting mechanism.
|
||||
.Va context
|
||||
is a opaque pointer that can be used by
|
||||
.Va codec
|
||||
if necessary.
|
||||
.Pp
|
||||
If the device does not have the
|
||||
.Dv AUDIO_PROP_INDEPENDENT
|
||||
property the same value is passed in both
|
||||
.Va play
|
||||
and
|
||||
.Va rec
|
||||
and the encoding parameters from
|
||||
.Va play
|
||||
is copied into
|
||||
.Va rec
|
||||
after the call to
|
||||
.Va set_params .
|
||||
.Va rec .
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Attach or Closed phase.
|
||||
.It Dv int round_blocksize(void *hdl, int bs, int mode,
|
||||
.Dv "const audio_params_t *param)"
|
||||
.Pp
|
||||
|
@ -294,6 +326,7 @@ and
|
|||
encoding parameters for the hardware.
|
||||
It should return a block size, possibly changed according to the needs
|
||||
of the hardware driver.
|
||||
It is called at Attach or Closed phase.
|
||||
.It Dv int commit_settings(void *hdl)
|
||||
optional, is called after all calls to
|
||||
.Va set_params ,
|
||||
|
@ -304,6 +337,7 @@ A hardware driver that needs to get the hardware in and out of command
|
|||
mode for each change can save all the changes during previous calls and
|
||||
do them all here.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Attach or Closed phase.
|
||||
.It Dv int init_output(void *hdl, void *buffer, int size)
|
||||
optional, is called before any output starts, but when the total
|
||||
.Va size
|
||||
|
@ -312,6 +346,7 @@ of the output
|
|||
has been determined.
|
||||
It can be used to initialize looping DMA for hardware that needs that.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Attach or Closed phase.
|
||||
.It Dv int init_input(void *hdl, void *buffer, int size)
|
||||
optional, is called before any input starts, but when the total
|
||||
.Va size
|
||||
|
@ -320,6 +355,7 @@ of the input
|
|||
has been determined.
|
||||
It can be used to initialize looping DMA for hardware that needs that.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Attach or Closed phase.
|
||||
.It Dv int start_output(void *hdl, void *block, int blksize,
|
||||
.Dv "void (*intr)(void*), void *intrarg)"
|
||||
.Pp
|
||||
|
@ -339,6 +375,7 @@ Calling
|
|||
will normally initiate another call to
|
||||
.Va start_output .
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int start_input(void *hdl, void *block, int blksize,
|
||||
.Dv "void (*intr)(void*), void *intrarg)"
|
||||
.Pp
|
||||
|
@ -358,32 +395,32 @@ Calling
|
|||
will normally initiate another call to
|
||||
.Va start_input .
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int halt_output(void *hdl)
|
||||
is called to abort the output transfer (started by
|
||||
.Va start_output )
|
||||
in progress.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int halt_input(void *hdl)
|
||||
is called to abort the input transfer (started by
|
||||
.Va start_input )
|
||||
in progress.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int speaker_ctl(void *hdl, int on)
|
||||
optional, is called when a half duplex device changes between
|
||||
playing and recording.
|
||||
It can, e.g., be used to turn on
|
||||
and off the speaker.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int getdev(void *hdl, struct audio_device *ret)
|
||||
Should fill the
|
||||
.Va audio_device
|
||||
struct with relevant information about the driver.
|
||||
Return 0 on success, otherwise an error code.
|
||||
.It Dv int setfd(void *hdl, int fd)
|
||||
optional, is called when
|
||||
.Dv AUDIO_SETFD
|
||||
is used, but only if the device has AUDIO_PROP_FULLDUPLEX set.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int set_port(void *hdl, mixer_ctrl_t *mc)
|
||||
is called in when
|
||||
.Dv AUDIO_MIXER_WRITE
|
||||
|
@ -392,6 +429,7 @@ It should take data from the
|
|||
.Va mixer_ctrl_t
|
||||
struct at set the corresponding mixer values.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened or Closed phase.
|
||||
.It Dv int get_port(void *hdl, mixer_ctrl_t *mc)
|
||||
is called in when
|
||||
.Dv AUDIO_MIXER_READ
|
||||
|
@ -400,6 +438,7 @@ It should fill the
|
|||
.Va mixer_ctrl_t
|
||||
struct.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened or Closed phase.
|
||||
.It Dv int query_devinfo(void *hdl, mixer_devinfo_t *di)
|
||||
is called in when
|
||||
.Dv AUDIO_MIXER_DEVINFO
|
||||
|
@ -408,6 +447,7 @@ It should fill the
|
|||
.Va mixer_devinfo_t
|
||||
struct.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at any time.
|
||||
.It Dv "void *allocm(void *hdl, int direction, size_t size)"
|
||||
optional, is called to allocate the device buffers.
|
||||
If not present
|
||||
|
@ -419,12 +459,14 @@ is that some buses need special allocation to do DMA.
|
|||
Returns the address of the buffer, or
|
||||
.Dv NULL
|
||||
on failure.
|
||||
It is called at Attached or Closed phase.
|
||||
.It Dv void freem(void *hdl, void *addr, size_t size)
|
||||
optional, is called to free memory allocated by
|
||||
.Va allocm .
|
||||
If not supplied
|
||||
.Xr free 9
|
||||
is used.
|
||||
It is called at Attached or Closed phase.
|
||||
.It Dv size_t round_buffersize(void *hdl, int direction, size_t bufsize)
|
||||
optional, is called at startup to determine the audio
|
||||
buffer size.
|
||||
|
@ -432,21 +474,14 @@ The upper layer supplies the suggested size in
|
|||
.Va bufsize ,
|
||||
which the hardware driver can then change if needed.
|
||||
E.g., DMA on the ISA bus cannot exceed 65536 bytes.
|
||||
.It Dv "paddr_t mappage(void *hdl, void *addr, off_t offs, int prot)"
|
||||
.Pp
|
||||
optional, is called for
|
||||
.Xr mmap 2 .
|
||||
Should return the map value for the page at offset
|
||||
.Va offs
|
||||
from address
|
||||
.Va addr
|
||||
mapped with protection
|
||||
.Va prot .
|
||||
Returns -1 on failure, or a machine dependent opaque value
|
||||
on success.
|
||||
It is called at Attached or Closed phase.
|
||||
.It Dv int get_props(void *hdl)
|
||||
Should return the device properties; i.e., a combination of
|
||||
AUDIO_PROP_xxx.
|
||||
It is called at any time.
|
||||
.Pp
|
||||
.Dv AUDIO_PROP_MMAP
|
||||
is acceptable but obsoleted, so new drivers should not return this property.
|
||||
.It Dv int trigger_output(void *hdl, void *start, void *end,
|
||||
.Dv "int blksize, void (*intr)(void*), void *intrarg,"
|
||||
.Pp
|
||||
|
@ -471,6 +506,7 @@ should be called with the argument
|
|||
Once started the transfer may be stopped using
|
||||
.Va halt_output .
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int trigger_input(void *hdl, void *start, void *end,
|
||||
.Dv "int blksize, void (*intr)(void*), void *intrarg,"
|
||||
.Pp
|
||||
|
@ -495,6 +531,7 @@ should be called with the argument
|
|||
Once started the transfer may be stopped using
|
||||
.Va halt_input .
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv int dev_ioctl(void *hdl, u_long cmd, void *addr,
|
||||
.Pp
|
||||
.Dv "int flag, struct lwp *l)"
|
||||
|
@ -503,8 +540,10 @@ optional, is called when an
|
|||
.Xr ioctl 2
|
||||
is not recognized by the generic audio driver.
|
||||
Return 0 on success, otherwise an error code.
|
||||
It is called at Opened phase.
|
||||
.It Dv void get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread)
|
||||
Returns the interrupt and thread locks to the common audio layer.
|
||||
It is called at Attach phase.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
|
@ -591,8 +630,7 @@ and that is a control named
|
|||
of class
|
||||
.Dv AudioCmonitor .
|
||||
.Sh SEE ALSO
|
||||
.Xr audio 4 ,
|
||||
.Xr audio_system 9
|
||||
.Xr audio 4
|
||||
.Sh HISTORY
|
||||
This
|
||||
.Nm
|
||||
|
|
|
@ -1,307 +0,0 @@
|
|||
.\" $NetBSD: audio_system.9,v 1.1 2018/05/28 00:18:06 nat Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2016 - 2018 Nathanial Sloss <nathanialsloss@yahoo.com.au>
|
||||
.\" 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 28, 2018
|
||||
.Dt AUDIO_SYSTEM 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm audio_system
|
||||
.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 represent vchan 0 (the mix ring), 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
|
||||
is the same as specifying
|
||||
.Fl p Ar 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
|
||||
This is for compatibility with existing applications and shell scripts
|
||||
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).
|
||||
.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.
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: intro.9,v 1.23 2018/07/15 05:16:41 maxv Exp $
|
||||
.\" $NetBSD: intro.9,v 1.24 2019/05/08 14:25:39 isaki Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997, 2007 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -435,11 +435,6 @@ Interface between low and high level audio drivers.
|
|||
See
|
||||
.Xr audio 9 .
|
||||
.Pp
|
||||
The
|
||||
.Nx audio specification.
|
||||
See
|
||||
.Xr audio_system 9 .
|
||||
.Pp
|
||||
Bluetooth Device/Protocol API.
|
||||
See
|
||||
.Xr bluetooth 9 .
|
||||
|
|
Loading…
Reference in New Issue