*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->OpenBSD man pages -> audio (9)              
Title
Content
Arch
Section
 

AUDIO(9)

Contents


NAME    [Toc]    [Back]

     audio - interface between low and high level audio drivers

DESCRIPTION    [Toc]    [Back]

     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 audio_hw_if 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,
                         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     (*getdev)(void *, struct audio_device *);
             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);
             paddr_t (*mappage)(void *, void *, off_t, int);

             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 *);
     };

     struct audio_params {
             u_long  sample_rate;            /* sample rate */
             u_int    encoding;                /* mu-law, 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)(void *, u_char *, int);
             int      factor;                  /*  coding   space
change */
     };

     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 processes
  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 initializes
 the hardware  for  I/O.   Every  successful
call to open()
             is  matched by a call to close().  This function returns 0 on success,
 otherwise an error code.

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

     int (*drain)(void *hdl)
             This  function  is  optional.   If  supplied,  it is
called before the
             device is closed or when the AUDIO_DRAIN ioctl(2) is
called.  It
             makes  sure that no samples remain to be played that
could be lost
             when close() is called.  This function returns 0  on
success, otherwise
 an error code.

     int (*query_encoding)(void *hdl, struct audio_encoding *ae)
             This function is used when the AUDIO_GETENC ioctl(2)
is called.
             It fills ae and returns 0 or, if there is no  encoding with the
             given number, returns EINVAL.

     int  (*set_params)(void  *hdl,  int  setmode,  int  usemode,
struct au-
             dio_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 combination
  of these flags, but indicates the current mode
of the device
             (i.e., the value of mode in the audio_info  struct).
The play and
             rec  structures contain the encoding parameters that
will be set.
             If the hardware requires  software  assistance  with
some encoding
             (e.g.,  it might be lacking mu-law support), it will
fill the
             sw_code and factor fields of these structures.  See
             /usr/src/sys/dev/auconv.h  for  available   software
support.  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  AUDIO_PROP_INDEPENDENT property,
             the  same  value  is passed in both play and rec and
the encoding
             parameters from play are copied into rec  after  the
call to
             set_params().

             The  machine independent audio driver does some preliminary parameter
 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 hardware
  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 hardware
 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 returns
 0 on success, otherwise an error code.

     int (*getdev)(void *hdl, struct audio_device *ret)
             This function fills ret  with  relevant  information
about the driver
  and returns 0 on success, or it returns an error
code on failure.


     int (*setfd)(void *hdl, int fd)
             This function  is  optional.   If  supplied,  it  is
called when the
             AUDIO_SETFD ioctl(2) is used, 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 error
 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 error
 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 using
 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.

     paddr_t (*mappage)(void *hdl, void *addr,  off_t  offs,  int
prot)
             This  function  is  optional.   If  supplied,  it is
called for
             mmap(2).  It returns the map value for the  page  at
offset offs
             from address addr mapped with protection prot.  This
function returns
 -1 on failure, or a machine  dependent  opaque
value on success.


     int (*get_props)(void *hdl)
             This  function returns the device properties, as per
audio(4)
             AUDIO_GETPROPS ioctl(2), i.e., 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 using
  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 using
 halt_input().  This function returns 0  on  success, otherwise
             an error code.

     The  query_devinfo() method should define certain mixer controls for
     AUDIO_SETINFO to be able to change the port and gain.

     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 output
 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    [Toc]    [Back]

      
      
     ioctl(2), mmap(2), open(2), audio(4), free(9), malloc(9)

HISTORY    [Toc]    [Back]

     This audio interface first appeared in OpenBSD 1.2.

OpenBSD     3.6                        February     11,      2000
[ Back ]
 Similar pages
Name OS Title
radio NetBSD interface between low and high level radio drivers
radio OpenBSD interface between low and high level radio drivers
aptitude Linux high-level interface to the package manager.
stfe Tru64 routines that provide a high-level interface to basic functions needed to access and add to the symb...
stfe IRIX routines that provide a high-level interface to basic functions needed to access and add to the symbol table
evp Tru64 High-level cryptographic functions
openssl_evp NetBSD high-level cryptographic functions
alGetFillPoint IRIX get or set low- or high-water mark for an audio port
modprobe Linux high level handling of loadable modules
vn_isunder NetBSD high-level convenience functions for vnode operations
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service