summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/audio.9
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/audio.9')
-rw-r--r--static/netbsd/man9/audio.9676
1 files changed, 676 insertions, 0 deletions
diff --git a/static/netbsd/man9/audio.9 b/static/netbsd/man9/audio.9
new file mode 100644
index 00000000..9bec5ed4
--- /dev/null
+++ b/static/netbsd/man9/audio.9
@@ -0,0 +1,676 @@
+.\" $NetBSD: audio.9,v 1.61 2021/03/28 07:42:06 isaki Exp $
+.\"
+.\" Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Lennart Augustsson.
+.\"
+.\" 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 February 2, 2021
+.Dt AUDIO 9
+.Os
+.Sh NAME
+.Nm audio
+.Nd interface between low and high level audio drivers
+.Sh DESCRIPTION
+The audio device driver is divided into a high level,
+hardware independent layer, and a low level hardware
+dependent layer.
+The interface between these is the
+.Va audio_hw_if
+structure.
+.Bd -literal
+struct audio_hw_if {
+ int (*open)(void *, int);
+ void (*close)(void *);
+
+ 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 *);
+
+ int (*init_output)(void *, void *, int);
+ int (*init_input)(void *, void *, int);
+ int (*start_output)(void *, void *, int, void (*)(void *),
+ void *);
+ int (*start_input)(void *, void *, int, void (*)(void *),
+ void *);
+ int (*halt_output)(void *);
+ int (*halt_input)(void *);
+
+ int (*speaker_ctl)(void *, int);
+#define SPKR_ON 1
+#define SPKR_OFF 0
+
+ int (*getdev)(void *, struct audio_device *);
+
+ int (*set_port)(void *, mixer_ctrl_t *);
+ int (*get_port)(void *, mixer_ctrl_t *);
+
+ int (*query_devinfo)(void *, mixer_devinfo_t *);
+
+ void *(*allocm)(void *, int, size_t);
+ void (*freem)(void *, void *, size_t);
+ size_t (*round_buffersize)(void *, int, size_t);
+
+ int (*get_props)(void *);
+
+ int (*trigger_output)(void *, void *, void *, int,
+ void (*)(void *), void *, const audio_params_t *);
+ int (*trigger_input)(void *, void *, void *, int,
+ void (*)(void *), void *, const audio_params_t *);
+ int (*dev_ioctl)(void *, u_long, void *, int, struct lwp *);
+ void (*get_locks)(void *, kmutex_t **, kmutex_t **);
+};
+
+typedef struct audio_params {
+ u_int sample_rate; /* sample rate */
+ u_int encoding; /* e.g. mu-law, linear, etc */
+ u_int precision; /* bits/subframe */
+ u_int validbits; /* valid bits in a subframe */
+ u_int channels; /* mono(1), stereo(2) */
+} audio_params_t;
+.Ed
+.Pp
+The high level audio driver attaches to the low level driver
+when the latter calls
+.Va audio_attach_mi .
+This call should be
+.Bd -literal
+ device_t
+ audio_attach_mi(const struct audio_hw_if *ahwp, void *hdl, device_t dev);
+.Ed
+.Pp
+The
+.Va audio_hw_if
+struct is as shown above.
+The
+.Va hdl
+argument is a handle to some low level data structure.
+It is sent as the first argument to all the functions
+in
+.Va audio_hw_if
+when the high level driver calls them.
+.Va dev
+is the device struct for the hardware device.
+.Pp
+The upper layer of the audio driver allocates one buffer for playing
+and one for recording.
+It handles the buffering of data from the user processes in these.
+The data is presented to the lower level in smaller chunks, called blocks.
+If, during playback, there is no data available from the user process when
+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.
+Some fields are optional and can be set to
+.Dv NULL
+if not needed.
+.Bl -tag -width indent
+.It Dv int open(void *hdl, int flags)
+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 in the Closed phase.
+.It Dv void close(void *hdl)
+optional, is called when the last audio device combining
+playback and recording is closed.
+Before call to this,
+.Va halt_input
+and
+.Va halt_output
+are called if necessary.
+It is called in the 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
+.Vt audio_format_t
+structure according to given number
+.Va afp->index .
+If there is no format with the given number, return
+.Er EINVAL .
+It can be called at any time.
+.Bd -literal
+typedef struct audio_format_query {
+ u_int index;
+ struct audio_format fmt;
+} audio_format_query_t;
+.Ed
+.Pp
+It is also used by the upper layer to determine the default format, as follows:
+.Bl -enum
+.It
+Higher priority is preferred (normally 0, the highest is 3, the lowest is 0).
+.It
+.Dv AUDIO_ENCODING_SLINEAR_NE:16
+is preferred if exists.
+.It
+.Dv AUDIO_ENCODING_SLINEAR_OE:16
+is preferred if exists.
+.It
+The format with more channels is preferred.
+.El
+.Pp
+If the driver supports
+.Dv SLINEAR_NE:16
+and the upper layer chooses it,
+the driver does not need to provide a conversion function in
+.Va set_format .
+Similarly, if the driver supports
+.Dv SLINEAR_OE:16
+and the upper layer chooses it,
+the driver does not need to provide a conversion function,
+because the upper layer supports conversion between
+.Dv SLINEAR_NE:16
+and
+.Dv SLINEAR_OE:16
+for convenience.
+If the upper layer chooses another format,
+the driver needs to provide a conversion function in
+.Va set_format .
+See also
+.Va set_format .
+If the driver can not provide the conversion from/to
+.Dv 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_format(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 modes are to be set.
+.Pp
+The
+.Va play
+and
+.Va rec
+structures contain the encoding parameters that should be set to the hardware.
+All of these parameters are chosen from formats returned by
+.Va query_format .
+Therefore
+.Va play
+and/or
+.Va rec
+are always settable.
+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.
+The definition of
+.Vt audio_filter_reg_t
+and a related structure follow:
+.Bd -literal
+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
+.Va codec
+is a conversion function and
+.Va context
+is an optional opaque pointer passed to
+.Va codec .
+.Pp
+When
+.Va codec
+is called, all parameters required by
+.Va codec
+are contained in
+.Va arg .
+.Va src
+points to the input buffer block,
+.Va srcfmt
+contains the input encoding parameters,
+.Va dst
+points to the output buffer block and
+.Va dstfmt
+contains the output encoding parameters.
+.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 the entirety of
+.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 .
+Returns 0 on success, otherwise an error code.
+It is called in the Attach or Closed phases.
+.It Dv int round_blocksize(void *hdl, int bs, int mode,
+.Dv "const audio_params_t *param)"
+.Pp
+optional, is called with the block size,
+.Va bs ,
+that has been computed by the upper layer,
+.Va mode ,
+.Dv AUMODE_PLAY
+or
+.Dv AUMODE_RECORD ,
+and
+.Va param ,
+encoding parameters for the hardware.
+.Va bs
+passed is always non-zero and a multiple of the frame size represented by
+param->channels * param->precision / 8.
+It should return a block size, possibly changed according to the needs
+of the hardware driver.
+The return value also must be non-zero and a multiple of the frame size.
+It is called in the Attach or Closed phases.
+.It Dv int commit_settings(void *hdl)
+optional, is called after all calls to
+.Va set_format ,
+and
+.Va set_port ,
+are done.
+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.
+Returns 0 on success, otherwise an error code.
+It is called in the Attach or Closed phases.
+.It Dv int init_output(void *hdl, void *buffer, int size)
+optional, is called before any output starts, but when the total
+.Va size
+of the output
+.Va buffer
+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 in the Attach or Closed phases.
+.It Dv int init_input(void *hdl, void *buffer, int size)
+optional, is called before any input starts, but when the total
+.Va size
+of the input
+.Va buffer
+has been determined.
+It can be used to initialize looping DMA for hardware that needs that.
+Returns 0 on success, otherwise an error code.
+It is called in the Attach or Closed phases.
+.It Dv int start_output(void *hdl, void *block, int blksize,
+.Dv "void (*intr)(void*), void *intrarg)"
+.Pp
+is called to start the transfer of
+.Va blksize
+bytes from
+.Va block
+to the audio hardware.
+The call should return when the data transfer has been initiated
+(normally with DMA).
+When the hardware is ready to accept more samples the function
+.Va intr
+should be called with the argument
+.Va intrarg .
+Calling
+.Va intr
+will normally initiate another call to
+.Va start_output .
+Returns 0 on success, otherwise an error code.
+This field is optional only if the driver doesn't support playback.
+It is called in the Opened phase.
+.It Dv int start_input(void *hdl, void *block, int blksize,
+.Dv "void (*intr)(void*), void *intrarg)"
+.Pp
+is called to start the transfer of
+.Va blksize
+bytes to
+.Va block
+from the audio hardware.
+The call should return when the data transfer has been initiated
+(normally with DMA).
+When the hardware is ready to deliver more samples the function
+.Va intr
+should be called with the argument
+.Va intrarg .
+Calling
+.Va intr
+will normally initiate another call to
+.Va start_input .
+Returns 0 on success, otherwise an error code.
+This field is optional only if the driver doesn't support recording.
+It is called in the Opened phase.
+.It Dv int halt_output(void *hdl)
+is called to abort the output transfer (started by
+.Va start_output )
+in progress.
+Returns 0 on success, otherwise an error code.
+This field is optional only if the driver doesn't support playback.
+It is called in the Opened phase.
+.It Dv int halt_input(void *hdl)
+is called to abort the input transfer (started by
+.Va start_input )
+in progress.
+Returns 0 on success, otherwise an error code.
+This field is optional only if the driver doesn't support recording,
+It is called in the 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.
+Returns 0 on success, otherwise an error code.
+It is called in the 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.
+Returns 0 on success, otherwise an error code.
+It is called in the Opened phase.
+.It Dv int set_port(void *hdl, mixer_ctrl_t *mc)
+is called in when
+.Dv AUDIO_MIXER_WRITE
+is used.
+It should take data from the
+.Va mixer_ctrl_t
+struct and set the corresponding mixer values.
+Returns 0 on success, otherwise an error code.
+It is called in the Opened or Closed phases.
+.It Dv int get_port(void *hdl, mixer_ctrl_t *mc)
+is called in when
+.Dv AUDIO_MIXER_READ
+is used.
+It should fill the
+.Va mixer_ctrl_t
+struct.
+Returns 0 on success, otherwise an error code.
+It is called in the Opened or Closed phases.
+.It Dv int query_devinfo(void *hdl, mixer_devinfo_t *di)
+is called in when
+.Dv AUDIO_MIXER_DEVINFO
+is used.
+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
+.Xr malloc 9
+is used instead (with the same arguments but the first two).
+The reason for using a device dependent routine instead of
+.Xr malloc 9
+is that some buses need special allocation to do DMA.
+Returns the address of the buffer, or
+.Dv NULL
+on failure.
+It is called in the Attached or Closed phases.
+.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 in the Attached or Closed phases.
+.It Dv size_t round_buffersize(void *hdl, int direction, size_t bufsize)
+optional, is called at startup to determine the audio
+buffer size.
+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 is called in the Attached or Closed phases.
+.It Dv int get_props(void *hdl)
+Should return the device properties in a combination of following flags:
+.Pp
+.Bl -tag -width AUDIO_PROP_INDEPENDENT -compact
+.It Dv AUDIO_PROP_PLAYBACK
+the device is capable of audio playback.
+.It Dv AUDIO_PROP_CAPTURE
+the device is capable of audio capture.
+.It Dv AUDIO_PROP_FULLDUPLEX
+the device admits full duplex operation.
+Don't set it if the device is unidirectional.
+.It Dv AUDIO_PROP_INDEPENDENT
+the device can set the playing and recording encoding parameters
+independently.
+Don't set it if the device is unidirectional.
+.It Dv AUDIO_PROP_MMAP
+is handled in the upper layer, so new drivers should not return this property.
+.El
+It is called in the Attach phase.
+.It Dv int trigger_output(void *hdl, void *start, void *end,
+.Dv "int blksize, void (*intr)(void*), void *intrarg,"
+.Pp
+.Dv "const audio_params_t *param)"
+.Pp
+optional, is called to start the transfer of data from the circular buffer
+delimited by
+.Va start
+and
+.Va end
+to the audio hardware, parameterized as in
+.Va param .
+The call should return when the data transfer has been initiated
+(normally with DMA).
+When the hardware is finished transferring each
+.Va blksize
+sized block, the function
+.Va intr
+should be called with the argument
+.Va intrarg
+(typically from the audio hardware interrupt service routine).
+Once started the transfer may be stopped using
+.Va halt_output .
+Return 0 on success, otherwise an error code.
+It is called in the Opened phase.
+.It Dv int trigger_input(void *hdl, void *start, void *end,
+.Dv "int blksize, void (*intr)(void*), void *intrarg,"
+.Pp
+.Dv "const audio_params_t *param)"
+.Pp
+optional, is called to start the transfer of data from the audio hardware,
+parameterized as in
+.Va param ,
+to the circular buffer delimited by
+.Va start
+and
+.Va end .
+The call should return when the data transfer has been initiated
+(normally with DMA).
+When the hardware is finished transferring each
+.Va blksize
+sized block, the function
+.Va intr
+should be called with the argument
+.Va intrarg
+(typically from the audio hardware interrupt service routine).
+Once started the transfer may be stopped using
+.Va halt_input .
+Return 0 on success, otherwise an error code.
+It is called in the Opened phase.
+.It Dv int dev_ioctl(void *hdl, u_long cmd, void *addr,
+.Pp
+.Dv "int flag, struct lwp *l)"
+.Pp
+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 in the 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 in the Attach phase.
+.El
+.Pp
+The
+.Va query_devinfo
+method should define certain mixer controls for
+.Dv AUDIO_SETINFO
+to be able to change the port and gain,
+and
+.Dv AUDIO_GETINFO
+to read them, as follows.
+.Pp
+If the record mixer is capable of input from more than one source,
+it should define
+.Dv AudioNsource
+in class
+.Dv AudioCrecord .
+This mixer control should be of type
+.Dv AUDIO_MIXER_ENUM
+or
+.Dv AUDIO_MIXER_SET
+and enumerate the possible input sources.
+Each of the named sources for which the recording level can be set
+should have a control in the
+.Dv AudioCrecord
+class of type
+.Dv AUDIO_MIXER_VALUE ,
+except the
+.Qq mixerout
+source is special,
+and will never have its own control.
+Its selection signifies,
+rather,
+that various sources in class
+.Dv AudioCrecord
+will be combined and presented to the single recording output
+in the same fashion that the sources of class
+.Dv AudioCinputs
+are combined and presented to the playback output(s).
+If the overall recording level can be changed,
+regardless of the input source,
+then this control should be named
+.Dv AudioNmaster
+and be of class
+.Dv AudioCrecord .
+.Pp
+Controls for various sources that affect only the playback output,
+as opposed to recording,
+should be in the
+.Dv AudioCinputs
+class,
+as of course should any controls that affect both playback and recording.
+.Pp
+If the play
+mixer is capable of output to more than one destination,
+it should define
+.Dv AudioNselect
+in class
+.Dv AudioCoutputs .
+This mixer control should be of type
+.Dv AUDIO_MIXER_ENUM
+or
+.Dv AUDIO_MIXER_SET
+and enumerate the possible destinations.
+For each of the named destinations for which the output level can be set,
+there should be
+a control in the
+.Dv AudioCoutputs
+class of type
+.Dv AUDIO_MIXER_VALUE .
+If the overall output level can be changed,
+which is invariably the case,
+then this control should be named
+.Dv AudioNmaster
+and be of class
+.Dv AudioCoutputs .
+.Pp
+There's one additional source recognized specially by
+.Dv AUDIO_SETINFO
+and
+.Dv AUDIO_GETINFO ,
+to be presented as monitor_gain,
+and that is a control named
+.Dv AudioNmonitor ,
+of class
+.Dv AudioCmonitor .
+.Sh SEE ALSO
+.Xr audio 4
+.Sh HISTORY
+This
+.Nm
+interface first appeared in
+.Nx 1.3 .