Initial version of the documentation of the interface between the
low and high level audio drivers, the audio_hw_if struct.
This commit is contained in:
parent
dd5cf3d4d9
commit
bf1f51a5d1
423
share/man/man9/audio.9
Normal file
423
share/man/man9/audio.9
Normal file
@ -0,0 +1,423 @@
|
||||
.\" $NetBSD: audio.9,v 1.1 1997/08/24 22:46:41 augustss Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
.\" 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.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" 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 REGENTS 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 Jul 29, 1997
|
||||
.Dt AUDIO 9
|
||||
.Os NetBSD
|
||||
.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
|
||||
a audio_hw_if structure.
|
||||
.Bd -literal
|
||||
struct audio_hw_if {
|
||||
int (*open)__P((void *, int));
|
||||
void (*close)__P((void *));
|
||||
int (*drain)__P((void *));
|
||||
|
||||
int (*query_encoding)__P((void *, struct audio_encoding *));
|
||||
int (*set_params)__P((void *, int, int,
|
||||
struct audio_params *, struct audio_params *));
|
||||
int (*round_blocksize)__P((void *, int));
|
||||
|
||||
int (*set_out_port)__P((void *, int));
|
||||
int (*get_out_port)__P((void *));
|
||||
int (*set_in_port)__P((void *, int));
|
||||
int (*get_in_port)__P((void *));
|
||||
int (*commit_settings)__P((void *));
|
||||
|
||||
int (*init_output)__P((void *, void *, int));
|
||||
int (*init_input)__P((void *, void *, int));
|
||||
int (*start_output)__P((void *, void *, int,
|
||||
void (*)(void *), void *));
|
||||
int (*start_input)__P((void *, void *, int,
|
||||
void (*)(void *), void *));
|
||||
int (*halt_output)__P((void *));
|
||||
int (*halt_input)__P((void *));
|
||||
int (*cont_output)__P((void *));
|
||||
int (*cont_input)__P((void *));
|
||||
|
||||
int (*speaker_ctl)__P((void *, int));
|
||||
#define SPKR_ON 1
|
||||
#define SPKR_OFF 0
|
||||
|
||||
int (*getdev)__P((void *, struct audio_device *));
|
||||
int (*setfd)__P((void *, int));
|
||||
|
||||
int (*set_port)__P((void *, mixer_ctrl_t *));
|
||||
int (*get_port)__P((void *, mixer_ctrl_t *));
|
||||
|
||||
int (*query_devinfo)__P((void *, mixer_devinfo_t *));
|
||||
|
||||
void *(*alloc)__P((void *, unsigned long, int, int));
|
||||
void (*free)__P((void *, void *, int));
|
||||
unsigned long (*round_buffersize)__P((void *, unsigned long));
|
||||
int (*mappage)__P((void *, void *, int, int));
|
||||
|
||||
int (*get_props)__P((void *)); /* device properties */
|
||||
};
|
||||
|
||||
struct audio_params {
|
||||
u_long sample_rate; /* sample rate */
|
||||
u_int encoding; /* e.g. ulaw, linear, etc */
|
||||
u_int precision; /* bits/sample */
|
||||
u_int channels; /* mono(1), stereo(2) */
|
||||
/* Software en/decode functions, set if SW coding required by HW */
|
||||
void (*sw_code)__P((void *, u_char *, int));
|
||||
int factor; /* coding space change */
|
||||
};
|
||||
|
||||
.Ed
|
||||
|
||||
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
|
||||
void
|
||||
audio_attach_mi(ahwp, mhwp, hdl, dev)
|
||||
struct audio_hw_if *ahwp;
|
||||
struct midi_hw_if *mhwp;
|
||||
void *hdl;
|
||||
struct device *dev;
|
||||
.Ed
|
||||
The
|
||||
.Va audio_hw_if
|
||||
struct is as shown above and the
|
||||
.Va midi_hw_if
|
||||
is unused (at the moment). 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.
|
||||
|
||||
.Pp
|
||||
The fields of
|
||||
.Va audio_hw_if
|
||||
are described in some more detail below.
|
||||
Some fields are optional; and can be set to 0 if not needed.
|
||||
.Bl -tag -width indent -compact
|
||||
|
||||
.It Dv int open(void *hdl, int flags)
|
||||
is called when the audio device is opened. It should initialize
|
||||
the hardware for I/O. Every successful call to
|
||||
.Va open
|
||||
is matched by a call to
|
||||
.Va close .
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv void close(void *hdl)
|
||||
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 can 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 audio_encoding
|
||||
structure and return 0 or return EINVAL if there is no encoding with the
|
||||
given number.
|
||||
|
||||
.It Dv int set_params(void *hdl, int setmode, int usemode,
|
||||
struct audio_params *play, struct audio_params *rec)
|
||||
.br
|
||||
Called to set the audio encoding mode.
|
||||
.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).
|
||||
The
|
||||
.Va play
|
||||
and
|
||||
.Va rec
|
||||
structures contain the encoding parameters that should be set.
|
||||
If the hardware requires software assistance with some encoding
|
||||
(e.g., it might be lacking mulaw support) it should fill the
|
||||
.Va sw_code
|
||||
and
|
||||
.Va factor
|
||||
fields of these structures.
|
||||
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).
|
||||
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 .
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int round_blocksize(void *hdl, int bs)
|
||||
optional, called with the block size,
|
||||
.Va bs ,
|
||||
that has been computed by the upper layer. It should return
|
||||
a block size, possibly changed according to the needs of the
|
||||
hardware driver.
|
||||
|
||||
.It Dv int set_out_port(void *hdl, int port)
|
||||
called if the play
|
||||
.Va port
|
||||
is set in an
|
||||
.Dv AUDIO_SETINFO
|
||||
.Xr ioctl 2 .
|
||||
Calling this is a shortcut to changing some setting in the mixer device.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int get_out_port(void *hdl)
|
||||
called to fill the play
|
||||
.Va port
|
||||
for an
|
||||
.Dv AUDIO_GETINFO
|
||||
.Xr ioctl 2 .
|
||||
Calling this is a shortcut to getting some setting in the mixer device.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int set_in_port(void *hdl, int port)
|
||||
called if the record
|
||||
.Va port
|
||||
is set in an
|
||||
.Dv AUDIO_SETINFO
|
||||
.Xr ioctl 2 .
|
||||
Calling this is a shortcut to changing some setting in the mixer device.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int get_in_port(void *hdl)
|
||||
called to fill the record
|
||||
.Va port
|
||||
for an
|
||||
.Dv AUDIO_GETINFO
|
||||
.Xr ioctl 2 .
|
||||
Calling this is a shortcut to getting some setting in the mixer device.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int commit_settings(void *hdl)
|
||||
optional, called after all calls to
|
||||
.Va set_params ,
|
||||
.Va set_out_port ,
|
||||
.Va set_in_port ,
|
||||
.Va set_port ,
|
||||
etc. 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.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int init_output(void *hdl, void *buffer, int size)
|
||||
optional, 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 Dv int init_input(void *hdl, void *buffer, int size)
|
||||
optional, 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.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int start_output(void *hdl, void *block, int bsize,
|
||||
void (*intr)(void*), void *intrarg)
|
||||
.br
|
||||
called to start the transfer of
|
||||
.Va bsize
|
||||
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 .
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int start_input(void *hdl, void *block, int bsize,
|
||||
void (*intr)(void*), void *intrarg)
|
||||
.br
|
||||
called to start the transfer of
|
||||
.Va bsize
|
||||
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.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int halt_output(void *hdl)
|
||||
called to abort the output transfer (started by
|
||||
.Va start_output )
|
||||
in progress.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int halt_input(void *hdl)
|
||||
called to abort the input transfer (started by
|
||||
.Va start_input )
|
||||
in progress.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int cont_output(void *hdl)
|
||||
unused.
|
||||
|
||||
.It Dv int cont_input(void *hdl)
|
||||
unused.
|
||||
|
||||
.It Dv int speaker_ctl(void *hdl, int on)
|
||||
optional, 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 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, called when
|
||||
.Dv AUDIO_SETFD
|
||||
is used.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int set_port(void *hdl, mixer_ctl_t *mc)
|
||||
called in when
|
||||
.Dv AUDIO_MIXER_WRITE
|
||||
is used. Should fill the
|
||||
.Va di
|
||||
struct.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int get_port(void *hdl, mixer_ctl_t *mc)
|
||||
called in when
|
||||
.Dv AUDIO_MIXER_READ
|
||||
is used. Should fill the
|
||||
.Va di
|
||||
struct.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv int query_devinfo(void *hdl, mixer_devinfo_t *di)
|
||||
called in when
|
||||
.Dv AUDIO_MIXER_DEVINFO
|
||||
is used. Should fill the
|
||||
.Va di
|
||||
struct.
|
||||
Return 0 on success, otherwise an error code.
|
||||
|
||||
.It Dv void *alloc(void *hdl, u_long size,
|
||||
int type, int flags)
|
||||
.br
|
||||
optional, called to allocate the device buffers. If not present
|
||||
.Xr malloc 9
|
||||
is used instead (with the same arguments except the first).
|
||||
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 0 on failure.
|
||||
|
||||
.It Dv void free(void *hdl, void *addr, int type)
|
||||
optional, called to free memory allocated by
|
||||
.Va alloc .
|
||||
If not supplied
|
||||
.Xr free 9
|
||||
is used.
|
||||
|
||||
.It Dv u_long round_buffer(void *hdl, u_long bufsize)
|
||||
optional, 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 Dv int mappage(void *hdl, void *addr,
|
||||
int offs, int prot)
|
||||
.br
|
||||
optional, 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 Dv int get_props(void *hdl)
|
||||
Should return the device properties; i.e. a combination of
|
||||
AUDIO_PROP_xxx.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr audio 4
|
Loading…
Reference in New Issue
Block a user