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

FreeBSD Manual Pages

  
 
  

home | help
SIO_OPEN(3)		    Library Functions Manual		   SIO_OPEN(3)

NAME
       sio_open,  sio_close,  sio_setpar,  sio_getpar,	sio_getcap, sio_start,
       sio_stop,  sio_flush,  sio_read,	  sio_write,   sio_onmove,   sio_nfds,
       sio_pollfd,  sio_revents,  sio_eof, sio_setvol, sio_onvol, sio_initpar,
       SIO_BPS -- sndio	interface to audio devices

SYNOPSIS
       #include	<sndio.h>

       struct sio_hdl *
       sio_open(const char *name, unsigned int mode, int nbio_flag);

       void
       sio_close(struct	sio_hdl	*hdl);

       int
       sio_setpar(struct sio_hdl *hdl, struct sio_par *par);

       int
       sio_getpar(struct sio_hdl *hdl, struct sio_par *par);

       int
       sio_getcap(struct sio_hdl *hdl, struct sio_cap *cap);

       int
       sio_start(struct	sio_hdl	*hdl);

       int
       sio_stop(struct sio_hdl *hdl);

       int
       sio_flush(struct	sio_hdl	*hdl);

       size_t
       sio_read(struct sio_hdl *hdl, void *addr, size_t	nbytes);

       size_t
       sio_write(struct	sio_hdl	*hdl, const void *addr,	size_t nbytes);

       void
       sio_onmove(struct sio_hdl *hdl,	     void (*cb)(void *arg, int delta),
	   void	*arg);

       int
       sio_nfds(struct sio_hdl *hdl);

       int
       sio_pollfd(struct sio_hdl *hdl, struct pollfd *pfd, int events);

       int
       sio_revents(struct sio_hdl *hdl,	struct pollfd *pfd);

       int
       sio_eof(struct sio_hdl *hdl);

       int
       sio_setvol(struct sio_hdl *hdl, unsigned	int vol);

       int
       sio_onvol(struct	sio_hdl	*hdl, void (*cb)(void *arg, unsigned int vol),
	   void	*arg);

       void
       sio_initpar(struct sio_par *par);

       unsigned	int
       SIO_BPS(unsigned	int bits);

DESCRIPTION
       The sndio library allows	user processes to access audio(4) hardware and
       the sndiod(8) audio server in a uniform way.

   Opening and closing an audio	device
       First  the  application	must  call the sio_open() function to obtain a
       handle to the device; later it will be passed as	the  hdl  argument  of
       most  other functions.  The name	parameter gives	the device string dis-
       cussed in sndio(7).  In most cases it should be set  to	SIO_DEVANY  to
       allow the user to select	it using the AUDIODEVICE environment variable.

       The following values of the mode	parameter are supported:

       SIO_PLAY		   Play-only  mode: data written will be played	by the
			   device.

       SIO_REC		   Record-only mode: samples are recorded by  the  de-
			   vice	and must be read.

       SIO_PLAY	| SIO_REC  The	device	plays  and records synchronously; this
			   means that the n-th recorded	sample was  physically
			   sampled exactly when	the n-th played	sample was ac-
			   tually played.

       If  the nbio_flag argument is true (i.e.	non-zero), then	the sio_read()
       and sio_write() functions (see below) will be non-blocking.

       The sio_close() function	stops the device as if	sio_stop()  is	called
       and  frees the handle.  Thus, no	samples	submitted with sio_write() are
       discarded.

   Negotiating audio parameters
       Audio samples are interleaved.  A frame consists	of one sample for each
       channel.	 For example, a	16-bit stereo encoding	has  two  samples  per
       frame and, two bytes per	sample (thus 4 bytes per frame).

       The  set	of parameters of the device that can be	controlled is given by
       the following structure:

       struct sio_par {
	       unsigned	int bits;      /* bits per sample */
	       unsigned	int bps;       /* bytes	per sample */
	       unsigned	int sig;       /* 1 = signed, 0	= unsigned int */
	       unsigned	int le;	       /* 1 = LE, 0 = BE byte order */
	       unsigned	int msb;       /* 1 = MSB, 0 = LSB aligned */
	       unsigned	int rchan;     /* number channels for recording	*/
	       unsigned	int pchan;     /* number channels for playback */
	       unsigned	int rate;      /* frames per second */
	       unsigned	int appbufsz;  /* minimum buffer size without xruns */
	       unsigned	int bufsz;     /* end-to-end buffer size (read-only) */
	       unsigned	int round;     /* optimal buffer size divisor */
       #define SIO_IGNORE      0       /* pause	during xrun */
       #define SIO_SYNC	       1       /* resync after xrun */
       #define SIO_ERROR       2       /* terminate on xrun */
	       unsigned	int xrun;      /* what to do on	overrun/underrun */
       };

       The parameters are as follows:

       bits	 Number	of bits	per sample: must be between 1 and 32.

       bps	 Bytes per samples; if specified, it must be large  enough  to
		 hold  all bits.  By default it's set to the smallest power of
		 two large enough to hold bits.

       sig	 If set	(i.e. non-zero)	then the samples are signed, else  un-
		 signed.

       le	 If  set,  then	 the byte order	is little endian, else big en-
		 dian; it's meaningful only if bps > 1.

       msb	 If set, then the bits are aligned in the packet to  the  most
		 significant  bit  (i.e.  lower	 bits are padded), else	to the
		 least significant bit (i.e. higher  bits  are	padded);  it's
		 meaningful only if bits < bps * 8.

       rchan	 The  number  of recorded channels; meaningful only if SIO_REC
		 mode was selected.

       pchan	 The number of played channels;	meaningful  only  if  SIO_PLAY
		 mode was selected.

       rate	 The sampling frequency	in Hz.

       appbufsz	 Size  of  the	buffer in frames the application must maintain
		 non-empty (on the play	end) or	non-full (on the  record  end)
		 by  calling  sio_write()  or  sio_read() fast enough to avoid
		 overrun or underrun conditions.  The audio subsystem may  use
		 additional  buffering,	thus this parameter cannot be used for
		 latency calculations.

       bufsz	 The maximum number of frames that may be buffered.  This  pa-
		 rameter  takes	 into account any buffers, and can be used for
		 latency calculations.	It is read-only.

       round	 Optimal number	of frames that the application buffers	should
		 be  a multiple	of, to get best	performance.  Applications can
		 use this parameter to round their block size.

       xrun	 The action when the client doesn't accept  recorded  data  or
		 doesn't  provide  data	 to play fast enough; it can be	set to
		 one of	the SIO_IGNORE,	SIO_SYNC, or SIO_ERROR constants.

       The following approach is recommended to	negotiate device parameters:

          Initialize a	sio_par	structure using	sio_initpar() and fill it with
	   the desired parameters.  Then call sio_setpar() to request the  de-
	   vice	 to  use them.	Parameters left	unset in the sio_par structure
	   will	be set to device-specific defaults.

          Call	sio_getpar() to	retrieve the actual parameters of  the	device
	   and	check that they	are usable.  If	they are not, then fail	or set
	   up a	conversion layer.  Sometimes the rate set can be slightly dif-
	   ferent to what was requested.  A difference of about	 0.5%  is  not
	   audible and should be ignored.

       Parameters  cannot  be  changed	after  sio_start()  has	 been  called,
       sio_stop() or sio_flush() must  be  called  before  parameters  can  be
       changed.

       If  the device is exposed by the	sndiod(8) server, which	is the default
       configuration, a	transparent emulation layer will automatically be  set
       up,  and	 in this case any combination of rate, encoding	and numbers of
       channels	is supported.

       To ease filling the sio_par structure,  the  following  macros  can  be
       used:

       SIO_BPS(bits)  Return the smallest value	for bps	that is	a power	of two
		      and that is large	enough to hold bits.

       SIO_LE_NATIVE  Can be used to set the le	parameter when native byte or-
		      der  is  required.   It is 1 if the native byte order is
		      little endian or 0 otherwise.

   Getting device capabilities
       There's no way to get an	exhaustive list	of all parameter  combinations
       the  device  supports.  Applications that need to have a	set of working
       parameter combinations in advance can use  the  sio_getcap()  function.
       However,	 for  most  new	applications it's generally not	recommended to
       use sio_getcap().  Instead, follow the recommendations for  negotiating
       device parameters (see above).

       The  sio_cap  structure	contains the list of parameter configurations.
       Each configuration contains multiple parameter sets.   The  application
       must  examine all configurations, and choose its	parameter set from one
       of the configurations.  Parameters of different configurations are  not
       usable together.

       struct sio_cap {
	       struct sio_enc {		       /* allowed encodings */
		       unsigned	int bits;
		       unsigned	int bps;
		       unsigned	int sig;
		       unsigned	int le;
		       unsigned	int msb;
	       } enc[SIO_NENC];
	       unsigned	int rchan[SIO_NCHAN];  /* allowed rchans */
	       unsigned	int pchan[SIO_NCHAN];  /* allowed pchans */
	       unsigned	int rate[SIO_NRATE];   /* allowed rates	*/
	       unsigned	int nconf;	       /* num. of confs[] */
	       struct sio_conf {
		       unsigned	int enc;       /* bitmask of enc[] indexes */
		       unsigned	int rchan;     /* bitmask of rchan[] indexes */
		       unsigned	int pchan;     /* bitmask of pchan[] indexes */
		       unsigned	int rate;      /* bitmask of rate[] indexes */
	       } confs[SIO_NCONF];
       };

       The parameters are as follows:

       enc[SIO_NENC]	 Array	of  supported  encodings.   The	tuple of bits,
			 bps, sig, le, and msb parameters are  usable  in  the
			 corresponding parameters of the sio_par structure.

       rchan[SIO_NCHAN]	 Array	of supported channel numbers for recording us-
			 able in the sio_par structure.

       pchan[SIO_NCHAN]	 Array of supported channel numbers for	 playback  us-
			 able in the sio_par structure.

       rate[SIO_NRATE]	 Array of supported sample rates usable	in the sio_par
			 structure.

       nconf		 Number	 of  different	configurations available, i.e.
			 number	of filled elements of the confs[] array.

       confs[SIO_NCONF]	 Array of available configurations.   Each  configura-
			 tion  contains	 bitmasks indicating which elements of
			 the above parameter arrays are	valid  for  the	 given
			 configuration.	  For  instance,  if the second	bit of
			 rate is set, in the sio_conf structure, then the sec-
			 ond element  of  the  rate[SIO_NRATE]	array  of  the
			 sio_cap  structure  is	 valid for this	configuration.
			 As such, when	reading	 the  array  elements  in  the
			 sio_cap  structure,  the  corresponding sio_conf bit-
			 masks should always be	used.

   Starting and	stopping the device
       The sio_start() function	prepares the device to start.  Once  the  play
       buffer is full, i.e. sio_par.bufsz samples are queued with sio_write(),
       playback	 starts	 automatically.	 If record-only	mode is	selected, then
       sio_start() starts recording immediately.  In full-duplex  mode,	 play-
       back  and recording will	start synchronously as soon as the play	buffer
       is full.

       The sio_stop() function puts the	audio subsystem	in the same  state  as
       before  sio_start()  was	 called.   It stops recording, drains the play
       buffer and then stops playback.	If samples  to	play  are  queued  but
       playback	 hasn't	started	yet then playback is forced immediately; play-
       back will actually stop once the	buffer is drained.   In	 no  case  are
       samples in the play buffer discarded.

       The sio_flush() function	stops playback and recording immediately, pos-
       sibly  discarding play buffer contents, and puts	the audio subsystem in
       the same	state as before	sio_start() was	called.

   Playing and recording
       When record mode	is selected, the sio_read() function must be called to
       retrieve	recorded data; it must be called often enough to  ensure  that
       internal	 buffers will not overrun.  It will store at most nbytes bytes
       at the addr location and	return the number of bytes stored.  Unless the
       nbio_flag flag is set, it will block until data becomes	available  and
       will return zero	only on	error.

       Similarly, when play mode is selected, the sio_write() function must be
       called  to  provide  data  to  play.   Unless  the  nbio_flag  is  set,
       sio_write() will	block until the	requested amount of data is written.

   Non-blocking	mode operation
       If the  nbio_flag  is  set  on  sio_open(),  then  the  sio_read()  and
       sio_write()  functions  will never block; if no data is available, they
       will return zero	immediately.

       The poll(2) system call can be used to check if data can	be  read  from
       or  written  to	the device.  The sio_pollfd() function fills the array
       pfd of pollfd structures, used by poll(2), with events; the latter is a
       bit-mask	of POLLIN and POLLOUT constants; refer to poll(2) for more de-
       tails.  The sio_revents() function returns the bit-mask set by  poll(2)
       in the pfd array	of pollfd structures.  If POLLIN is set, recorded sam-
       ples  are  available  in	 the  device  buffer  and  can	be  read  with
       sio_read().  If POLLOUT is set, space is	available in the device	buffer
       and new samples to play can be submitted	with sio_write().  POLLHUP may
       be  set	if  an	error  occurs,	even  if  it  is  not  selected	  with
       sio_pollfd().

       The  size of the	pfd array, which the caller must pre-allocate, is pro-
       vided by	the sio_nfds() function.

   Synchronizing non-audio events to the audio stream in real-time
       In order	to perform actions at precise positions	of the	audio  stream,
       such as displaying video	in sync	with the audio stream, the application
       must  be	 notified in real-time of the exact position in	the stream the
       hardware	is processing.

       The sio_onmove()	function can be	used to	 register  the	cb()  callback
       function	called at regular time intervals.  The delta argument contains
       the number of frames the	hardware played	and/or recorded	since the last
       call   of   cb().    It	is  called  by	sio_read(),  sio_write(),  and
       sio_revents().  When the	first sample is	played and/or recorded,	 right
       after  the device starts, the callback is invoked with a	zero delta ar-
       gument.	The value of the arg pointer is	passed to the callback and can
       contain anything.

       If desired, the application can maintain	the current position by	start-
       ing from	zero (when sio_start() is called) and adding  to  the  current
       position	delta every time cb() is called.

   Measuring the latency and buffers usage
       The playback latency is the delay it will take for the frame just writ-
       ten  to become audible, expressed in number of frames.  The exact play-
       back latency can	be obtained by subtracting the current	position  from
       the number of frames written.  Once playback is actually	started	(first
       sample audible),	the latency will never exceed the bufsz	parameter (see
       the  sections  above).	There's	 a phase during	which sio_write() only
       queues data; once there's enough	data, actual playback starts.	During
       this phase talking about	latency	is meaningless.

       In any cases, at	most bufsz frames are buffered.	 This value takes into
       account	all buffers.  The number of frames stored is equal to the num-
       ber of frames written minus the current position.

       The recording latency is	obtained similarly, by subtracting the	number
       of frames read from the current position.

       Note  that  sio_write() might block even	if there is buffer space left;
       using the buffer	usage to guess if sio_write() would block is false and
       leads to	unreliable programs - consider using poll(2) for this.

   Handling buffer overruns and	underruns
       When the	application cannot  accept  recorded  data  fast  enough,  the
       record  buffer  (of size	appbufsz) might	overrun; in this case recorded
       data is lost.  Similarly	if the application cannot provide data to play
       fast enough, the	play buffer underruns and silence is  played  instead.
       Depending  on  the  xrun	 parameter of the sio_par structure, the audio
       subsystem will behave as	follows:

       SIO_IGNORE  The device pauses during overruns and underruns,  thus  the
		   current  position (obtained through sio_onmove()) stops be-
		   ing incremented.  Once the overrun and/or  underrun	condi-
		   tion	 is  gone, the device resumes; play and	record are al-
		   ways	kept in	sync.  With this mode, the application	cannot
		   notice  underruns  and/or overruns and shouldn't care about
		   them.

		   This	mode is	the default.  It's suitable for	 applications,
		   like	 audio players and telephony, where time is not	impor-
		   tant	and overruns or	underruns are not short.

       SIO_SYNC	   If the play buffer underruns, then silence is  played,  but
		   in  order  to  reach	 the  right position in	time, the same
		   amount of written samples will be discarded once the	appli-
		   cation is unblocked.	 Similarly, if the record buffer over-
		   runs, then samples are discarded, but the  same  amount  of
		   silence  will be returned later.  The current position (ob-
		   tained through sio_onmove())	is  still  incremented.	  When
		   the	play  buffer  underruns	 the play latency might	become
		   negative; when the record buffer overruns, the  record  la-
		   tency might become larger than bufsz.

		   This	 mode is suitable for applications, like music produc-
		   tion, where time is important and where underruns or	 over-
		   runs	are short and rare.

       SIO_ERROR   With	this mode, on the first	play buffer underrun or	record
		   buffer overrun, playback and/or recording is	terminated and
		   no other function than sio_close() will succeed.

		   This	mode is	mostly useful for testing.

   Controlling the volume
       The sio_setvol()	function can be	used to	set playback attenuation.  The
       vol  parameter  takes  a	 value	between	 0  (maximum  attenuation) and
       SIO_MAXVOL (no attenuation).  It	specifies the weight the audio subsys-
       tem will	give to	this stream.  It is not	meant to control hardware  pa-
       rameters	 like  speaker	gain; the mixerctl(8) interface	should be used
       for that	purpose	instead.

       An application can use the sio_onvol() function to register a  callback
       function	that will be called each time the volume is changed, including
       when  sio_setvol()  is  used.   The  callback  is  always  invoked when
       sio_onvol() is called in	order to provide the initial volume.   An  ap-
       plication  can  safely assume that once sio_onvol() has returned	a non-
       zero value, the callback	has been invoked and thus the  current	volume
       is  available.  If there's no volume setting available, sio_onvol() re-
       turns 0 and the callback	is never invoked and calls to sio_setvol() are
       ignored.

       The sio_onvol() function	can be called with a NULL  argument  to	 check
       whether a volume	knob is	available.

   Error handling
       Errors  related	to  the	audio subsystem	(like hardware errors, dropped
       connections) and	programming errors (e.g. call to sio_read() on a play-
       only stream) are	considered fatal.  Once	an error occurs, all functions
       taking a	sio_hdl	argument, except sio_close() and sio_eof(), stop work-
       ing (i.e. always	return 0).  The	sio_eof() function can be used at  any
       stage.

RETURN VALUES
       The  sio_open() function	returns	the newly created handle on success or
       NULL on failure.

       The sio_setpar(), sio_getpar(), sio_getcap(), sio_start(),  sio_stop(),
       sio_flush(),  and  sio_setvol()	functions return 1 on success and 0 on
       failure.

       The sio_pollfd()	function  returns  the	number	of  pollfd  structures
       filled.	 The  sio_nfds()  function returns the number of pollfd	struc-
       tures the caller	must preallocate in order to be	sure that sio_pollfd()
       will never overrun.

       The sio_read() and sio_write() functions	return	the  number  of	 bytes
       transferred.

       The  sio_eof()  function	 returns  0 if there's no pending error, and a
       non-zero	value if there's an error.

ENVIRONMENT
       AUDIODEVICE     Device to use if	sio_open() is called  with  SIO_DEVANY
		       as the name argument.
       SNDIO_DEBUG     The debug level:	may be a value between 0 and 2.

SEE ALSO
       mio_open(3), sioctl_open(3), audio(4), sndio(7),	sndiod(8), audio(9)

HISTORY
       These functions first appeared in OpenBSD 4.5.

AUTHORS
       Alexandre Ratchov <ratchov@openbsd.org>

BUGS
       The  audio(4)  driver  doesn't drain playback buffers, thus if sndio is
       used to directly	access an audio(4)  device,  the  sio_stop()  function
       will stop playback immediately.

       If  the	application  doesn't  consume  recorded	 data fast enough then
       "control	messages" from the sndiod(8) server  are  delayed  and	conse-
       quently sio_onmove() callback or	volume changes may be delayed.

       The  sio_open(),	sio_setpar(), sio_getpar(), sio_getcap(), sio_start(),
       sio_stop(), and sio_flush() functions may block for a very short	period
       of time,	thus they should be avoided in code sections where blocking is
       not desirable.

FreeBSD	Ports 14.quarterly	  $Mdocdate$			   SIO_OPEN(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=sio_read&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help