Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
AUDIO(9)	       FreeBSD Kernel Developer's Manual	      AUDIO(9)

NAME
     audio -- interface	between	low and	high level audio drivers

DESCRIPTION
     The audio device driver is	divided	into a high level, hardware indepen-
     dent layer, and a low level, hardware dependent layer.  The interface be-
     tween these is the	audio_hw_if structure.

     struct audio_hw_if	{
	     int     (*open)(void *, int);
	     void    (*close)(void *);
	     int     (*set_params)(void	*, int,	int,
			 struct	audio_params *,	struct audio_params *);
	     int     (*round_blocksize)(void *,	int);

	     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     (*setfd)(void *, int);

	     int     (*set_port)(void *, struct	mixer_ctrl *);
	     int     (*get_port)(void *, struct	mixer_ctrl *);

	     int     (*query_devinfo)(void *, struct mixer_devinfo *);

	     void    *(*allocm)(void *,	int, size_t, int, int);
	     void    (*freem)(void *, void *, int);
	     size_t  (*round_buffersize)(void *, int, size_t);
	     int     (*get_props)(void *);

	     int     (*trigger_output)(void *, void *, void *, int,
			 void (*)(void *), void	*, struct audio_params *);
	     int     (*trigger_input)(void *, void *, void *, int,
			 void (*)(void *), void	*, struct audio_params *);
	     void    (*copy_output)(void *hdl, size_t bytes);
	     void    (*underrun)(void *hdl);
	     int     (*set_blksz)(void *, int,
			 struct	audio_params *,	struct audio_params *, int);
	     int     (*set_nblks)(void *, int, int,
			 struct	audio_params *,	int);
     };

     struct audio_params {
	     u_long  sample_rate;	     /*	sample rate */
	     u_int   encoding;		     /*	mu-law,	linear,	etc */
	     u_int   precision;		     /*	bits/sample */
	     u_int   bps;		     /*	bytes/sample */
	     u_int   msb;		     /*	data alignment */
	     u_int   channels;		     /*	mono(1), stereo(2) */
     };

     The high level audio driver attaches to the low level driver when the
     latter calls audio_attach_mi().  This call	is:

	   struct device *
	   audio_attach_mi(struct audio_hw_if *ahwp, void *hdl,
			   struct device *dev);

     The audio_hw_if struct is as shown	above.	The hdl	argument is a handle
     to	some low level data structure.	It is sent as the first	argument to
     all the functions in ahwp when the	high level driver calls	them.  dev is
     the device	struct for the hardware	device.

     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	pro-
     cesses in these.  The data	is presented to	the lower level	in smaller
     chunks, called blocks.  During playback, if there is no data available
     from the user process when	the hardware requests another block, a block
     of	silence	will be	used instead.  Similarly, if the user process does not
     read data quickly enough during recording,	data will be thrown away.

     The fields	of audio_hw_if are described in	some more detail below.	 Some
     fields are	optional and can be set	to NULL	if not needed.

     int (*open)(void *hdl, int	flags)
	     This function is called when the audio device is opened, with
	     flags the kernel representation of	flags passed to	the open(2)
	     system call (see OFLAGS and FFLAGS	in <sys/fcntl.h>).  It ini-
	     tializes the hardware for I/O.  Every successful call to open()
	     is	matched	by a call to close().  This function returns 0 on suc-
	     cess, otherwise an	error code.

     void (*close)(void	*hdl)
	     This function is called when the audio device is closed.

     int (*set_params)(void *hdl, int setmode, int usemode, struct
	     audio_params *play, struct	audio_params *rec)
	     This function is called to	set the	audio encoding mode.  setmode
	     is	a combination of the AUMODE_RECORD and AUMODE_PLAY flags to
	     indicate which mode(s) are	to be set.  usemode is also a combina-
	     tion of these flags, but indicates	the current mode of the	device
	     (i.e., the	value corresponding to the flags argument to the
	     open() function).	The play and rec structures contain the	encod-
	     ing parameters that will be set.  The values of the structures
	     must 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).  Except the channel count,
	     the same value is passed in both play and rec.

	     The machine independent audio driver does some preliminary	param-
	     eter checking; it verifies	that the precision is compatible with
	     the encoding, and it translates AUDIO_ENCODING_[US]LINEAR to
	     AUDIO_ENCODING_[US]LINEAR_{LE,BE}.

	     This function returns 0 on	success, otherwise an error code.

     int (*round_blocksize)(void *hdl, int bs)
	     This function is optional.	 If supplied, it is called with	the
	     block size, bs, which has been computed by	the upper layer.  It
	     returns a block size, possibly changed according to the needs of
	     the hardware driver.

     int (*commit_settings)(void *hdl)
	     This function is optional.	 If supplied, it is called after all
	     calls to set_params() and 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.  This function returns 0 on	success, otherwise an
	     error code.

     int (*init_output)(void *hdl, void	*buffer, int size)
	     This function is optional.	 If supplied, it is called before any
	     output starts, but	only after the total size of the output	buffer
	     has been determined.  It can be used to initialize	looping	DMA
	     for hardware that needs it.  This function	returns	0 on success,
	     otherwise an error	code.

     int (*init_input)(void *hdl, void *buffer,	int size)
	     This function is optional.	 If supplied, it is called before any
	     input starts, but only after the total size of the	input buffer
	     has been determined.  It can be used to initialize	looping	DMA
	     for hardware that needs it.  This function	returns	0 on success,
	     otherwise an error	code.

     int (*start_output)(void *hdl, void *block, int bsize, void (*intr)(void
	     *), void *intrarg)
	     This function is called to	start the transfer of bsize bytes from
	     block to the audio	hardware.  The call returns when the data
	     transfer has been initiated (normally with	DMA).  When the	hard-
	     ware is ready to accept more samples the function intr will be
	     called with the argument intrarg.	Calling	intr will normally
	     initiate another call to start_output().  This function returns 0
	     on	success, otherwise an error code.

     int (*start_input)(void *hdl, void	*block,	int bsize, void	(*intr)(void
	     *), void *intrarg)
	     This function is called to	start the transfer of bsize bytes to
	     block from	the audio hardware.  The call returns when the data
	     transfer has been initiated (normally with	DMA).  When the	hard-
	     ware is ready to deliver more samples the function	intr will be
	     called with the argument intrarg.	Calling	intr will normally
	     initiate another call to start_input().  This function returns 0
	     on	success, otherwise an error code.

     int (*halt_output)(void *hdl)
	     This function is called to	abort the output transfer (started by
	     start_output()) in	progress.  This	function returns 0 on success,
	     otherwise an error	code.

     int (*halt_input)(void *hdl)
	     This function is called to	abort the input	transfer (started by
	     start_input()) in progress.  This function	returns	0 on success,
	     otherwise an error	code.

     int (*speaker_ctl)(void *hdl, int on)
	     This function is optional.	 If supplied, it is called when	a half
	     duplex device changes between playing and recording.  It can,
	     e.g., be used to turn the speaker on and off.  This function re-
	     turns 0 on	success, otherwise an error code.

     int (*setfd)(void *hdl, int fd)
	     This function is optional.	 If supplied, it is called when	the
	     device is opened in full-duplex mode, but only if the device has
	     AUDIO_PROP_FULLDUPLEX set.	 This function returns 0 on success,
	     otherwise an error	code.

     int (*set_port)(void *hdl,	struct mixer_ctrl *mc)
	     This function is called when the AUDIO_MIXER_WRITE	ioctl(2) is
	     used.  It takes data from mc and sets the corresponding mixer
	     values.  This function returns 0 on success, otherwise an error
	     code.

     int (*get_port)(void *hdl,	struct mixer_ctrl *mc)
	     This function is called when the AUDIO_MIXER_READ ioctl(2)	is
	     used.  It fills mc	and returns 0 on success, or it	returns	an er-
	     ror code on failure.

     int (*query_devinfo)(void *hdl, struct mixer_devinfo *di)
	     This function is called when the AUDIO_MIXER_DEVINFO ioctl(2) is
	     used.  It fills di	and returns 0 on success, or it	returns	an er-
	     ror code on failure.

     void * (*allocm)(void *hdl, int direction,	size_t size, int type, int
	     flags)
	     This function is optional.	 If supplied, it is called to allocate
	     the device	buffers.  If not supplied, malloc(9) is	used instead
	     (with the same arguments but the first two).  The reason for us-
	     ing a device dependent routine instead of malloc(9) is that some
	     buses need	special	allocation to do DMA.  direction is
	     AUMODE_PLAY or AUMODE_RECORD.  This function returns the address
	     of	the buffer on success, or 0 on failure.

     void (*freem)(void	*hdl, void *addr, int type)
	     This function is optional.	 If supplied, it is called to free
	     memory allocated by allocm().  If not supplied, free(9) is	used
	     instead.

     size_t (*round_buffersize)(void *hdl, int direction, size_t bufsize)
	     This function is optional.	 If supplied, it is called at startup
	     to	determine the audio buffer size.  The upper layer supplies the
	     suggested size in bufsize,	which the hardware driver can then
	     change if needed.	E.g., DMA on the ISA bus cannot	exceed 65536
	     bytes.  Note that the buffer size is always a multiple of the
	     block size, so round_blocksize() and round_buffersize() must be
	     consistent.

     int (*get_props)(void *hdl)
	     This function returns a combination of AUDIO_PROP_xxx properties.

     int (*trigger_output)(void	*hdl, void *start, void	*end, int blksize,
	     void (*intr)(void *), void	*intrarg, struct audio_params *param)
	     This function is optional.	 If supplied, it is called to start
	     the transfer of data from the circular buffer delimited by	start
	     and end to	the audio hardware, parameterized as in	param.	The
	     call returns when the data	transfer has been initiated (normally
	     with DMA).	 When the hardware is finished transferring each
	     blksize sized block, the function intr will be called with	the
	     argument intrarg (typically from the audio	hardware interrupt
	     service routine).	Once started, the transfer may be stopped us-
	     ing halt_output().	 This function returns 0 on success, otherwise
	     an	error code.

     int (*trigger_input)(void *hdl, void *start, void *end, int blksize, void
	     (*intr)(void *), void *intrarg, struct audio_params *param)
	     This function is optional.	 If supplied, it is called to start
	     the transfer of data from the audio hardware, parameterized as in
	     param, to the circular buffer delimited by	start and end.	The
	     call returns when the data	transfer has been initiated (normally
	     with DMA).	 When the hardware is finished transferring each
	     blksize sized block, the function intr will be called with	the
	     argument intrarg (typically from the audio	hardware interrupt
	     service routine).	Once started, the transfer may be stopped us-
	     ing halt_input().	This function returns 0	on success, otherwise
	     an	error code.

     void (*copy_output)(void *hdl, size_t bytes)
	     This function is called whenever the given	amount of bytes	was
	     appended to the play ring buffer, typically during	a write(2)
	     system call.  Drivers using bounce	buffers	for transfers between
	     the audio ring buffer and the device could	implement this func-
	     tion to copy the given amount of bytes into their bounce buffers.
	     There's no	analogue function for recording	as data	is produced by
	     the device	and could simply be copied upon	transfer completion.

     void (*underrun)(void *hdl)
	     This function is called at	interrupt context whenever a play
	     block was skipped by the audio(4) driver.	Drivers	using bounce
	     buffers for transfers between the audio ring buffer and the de-
	     vice must implement this method to	skip one block from the	audio
	     ring buffer and transfer the corresponding	amount of silence to
	     the device.

     int (*set_blksz)(void *hdl, int mode, struct audio_params *play, struct
	     audio_params *rec,	int blksz)
	     This function is called to	set the	audio block size.  mode	is a
	     combination of the	AUMODE_RECORD and AUMODE_PLAY flags indicating
	     the current mode set with the open() function.  The play and rec
	     structures	contain	the current encoding set with the set_params()
	     function.	blksz is the desired block size	in frames.  It may be
	     adjusted to match hardware	constraints.  This function returns
	     the adjusted block	size.

     int (*set_nblks)(void *hdl, int dir, int blksz, struct audio_params
	     *params, int nblks)
	     This function is called to	set the	number of audio	blocks in the
	     ring buffer.  dir is either the AUMODE_RECORD or the AUMODE_PLAY
	     flag, indicating which ring buffer	size is	set.  The params
	     structure contains	the encoding parameters	set by the
	     set_params() method.  blksz is the	current	block size in frames
	     set with the set_params function.	The params structure is	the
	     current encoding parameters, set with the set_params() function.
	     nblks is the desired number of blocks in the ring buffer.	It may
	     be	lowered	to at least two, to match hardware constraints.	 This
	     function returns the adjusted number of blocks.

     If	the audio hardware is capable of input from more than one source it
     should define AudioNsource	in class AudioCrecord.	This mixer control
     should be of type AUDIO_MIXER_ENUM	or AUDIO_MIXER_SET and enumerate the
     possible input sources.  For each of the named sources there should be a
     control in	the AudioCinputs class of type AUDIO_MIXER_VALUE if recording
     level of the source can be	set.  If the overall recording level can be
     changed (i.e., regardless of the input source) then this control should
     be	named AudioNrecord and be of class AudioCinputs.

     If	the audio hardware is capable of output	to more	than one destination
     it	should define AudioNoutput in class AudioCmonitor.  This mixer control
     should be of type AUDIO_MIXER_ENUM	or AUDIO_MIXER_SET and enumerate the
     possible destinations.  For each of the named destinations	there should
     be	a control in the AudioCoutputs class of	type AUDIO_MIXER_VALUE if out-
     put level of the destination can be set.  If the overall output level can
     be	changed	(i.e., regardless of the destination) then this	control	should
     be	named AudioNmaster and be of class AudioCoutputs.

SEE ALSO
     ioctl(2), open(2),	sio_open(3), audio(4), free(9),	malloc(9)

HISTORY
     This audio	interface first	appeared in OpenBSD 1.2.

FreeBSD	13.0		      September	13, 2019		  FreeBSD 13.0

NAME | DESCRIPTION | SEE ALSO | HISTORY

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=audio&sektion=9&manpath=OpenBSD+6.9>

home | help