mirror of
https://github.com/ericonr/sndio.git
synced 2024-02-18 04:45:21 -06:00
786 lines
21 KiB
Groff
786 lines
21 KiB
Groff
.\" $OpenBSD$
|
|
.\"
|
|
.\" Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org>
|
|
.\"
|
|
.\" Permission to use, copy, modify, and distribute this software for any
|
|
.\" purpose with or without fee is hereby granted, provided that the above
|
|
.\" copyright notice and this permission notice appear in all copies.
|
|
.\"
|
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
.\"
|
|
.Dd $Mdocdate$
|
|
.Dt SIO_OPEN 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm sio_open ,
|
|
.Nm sio_close ,
|
|
.Nm sio_setpar ,
|
|
.Nm sio_getpar ,
|
|
.Nm sio_getcap ,
|
|
.Nm sio_start ,
|
|
.Nm sio_stop ,
|
|
.Nm sio_read ,
|
|
.Nm sio_write ,
|
|
.Nm sio_onmove ,
|
|
.Nm sio_nfds ,
|
|
.Nm sio_pollfd ,
|
|
.Nm sio_revents ,
|
|
.Nm sio_eof ,
|
|
.Nm sio_setvol ,
|
|
.Nm sio_onvol ,
|
|
.Nm sio_initpar
|
|
.Nd interface to bidirectional audio streams
|
|
.Sh SYNOPSIS
|
|
.Fd #include <sndio.h>
|
|
.Ft "struct sio_hdl *"
|
|
.Fn "sio_open" "const char *name" "unsigned int mode" "int nbio_flag"
|
|
.Ft "void"
|
|
.Fn "sio_close" "struct sio_hdl *hdl"
|
|
.Ft "int"
|
|
.Fn "sio_setpar" "struct sio_hdl *hdl" "struct sio_par *par"
|
|
.Ft "int"
|
|
.Fn "sio_getpar" "struct sio_hdl *hdl" "struct sio_par *par"
|
|
.Ft "int"
|
|
.Fn "sio_getcap" "struct sio_hdl *hdl" "struct sio_cap *cap"
|
|
.Ft "int"
|
|
.Fn "sio_start" "struct sio_hdl *hdl"
|
|
.Ft "int"
|
|
.Fn "sio_stop" "struct sio_hdl *hdl"
|
|
.Ft "size_t"
|
|
.Fn "sio_read" "struct sio_hdl *hdl" "void *addr" "size_t nbytes"
|
|
.Ft "size_t"
|
|
.Fn "sio_write" "struct sio_hdl *hdl" "const void *addr" "size_t nbytes"
|
|
.Ft "void"
|
|
.Fn "sio_onmove" "struct sio_hdl *hdl" "void (*cb)(void *arg, int delta)" "void *arg"
|
|
.Ft "int"
|
|
.Fn "sio_nfds" "struct sio_hdl *hdl"
|
|
.Ft "int"
|
|
.Fn "sio_pollfd" "struct sio_hdl *hdl" "struct pollfd *pfd" "int events"
|
|
.Ft "int"
|
|
.Fn "sio_revents" "struct sio_hdl *hdl" "struct pollfd *pfd"
|
|
.Ft "int"
|
|
.Fn "sio_eof" "struct sio_hdl *hdl"
|
|
.Ft "int"
|
|
.Fn "sio_setvol" "struct sio_hdl *hdl" "unsigned int vol"
|
|
.Ft "int"
|
|
.Fn "sio_onvol" "struct sio_hdl *hdl" "void (*cb)(void *arg, unsigned int vol)" "void *arg"
|
|
.Ft "void"
|
|
.Fn "sio_initpar" "struct sio_par *par"
|
|
.\"Fd #define SIO_BPS(bits)
|
|
.\"Fd #define SIO_LE_NATIVE
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm sndio
|
|
library allows user processes to access
|
|
.Xr audio 4
|
|
hardware and the
|
|
.Xr sndiod 1
|
|
audio server in a uniform way.
|
|
It supports full-duplex operation, and when
|
|
used with the
|
|
.Xr sndiod 1
|
|
server it supports resampling and format
|
|
conversions on the fly.
|
|
.Ss Opening and closing an audio stream
|
|
First the application must call the
|
|
.Fn sio_open
|
|
function to obtain a handle representing the newly created stream;
|
|
later it will be passed as the
|
|
.Ar hdl
|
|
argument of most other functions.
|
|
The
|
|
.Fn sio_open
|
|
function first tries to connect to the
|
|
.Xr sndiod 1
|
|
audio server.
|
|
If that fails, it then tries to use the
|
|
.Xr audio 4
|
|
hardware device.
|
|
The
|
|
.Ar name
|
|
parameter gives the device string discussed in
|
|
.Xr sndio 7 .
|
|
In most cases it should be set to SIO_DEVANY to allow
|
|
the user to select it using the
|
|
.Ev AUDIODEVICE
|
|
environment variable.
|
|
.Pp
|
|
The
|
|
.Ar mode
|
|
parameter gives the direction of the stream.
|
|
The following are supported:
|
|
.Bl -tag -width "SIO_PLAY | SIO_REC"
|
|
.It SIO_PLAY
|
|
The stream is play-only; data written to the stream will be played
|
|
by the hardware.
|
|
.It SIO_REC
|
|
The stream is record-only; recorded samples by the hardware
|
|
must be read from the stream.
|
|
.It SIO_PLAY | SIO_REC
|
|
The stream plays and records synchronously; this means that
|
|
the n-th recorded sample was physically sampled exactly when
|
|
the n-th played sample was actually played.
|
|
.El
|
|
.Pp
|
|
If the
|
|
.Ar nbio_flag
|
|
argument is true (i.e. non-zero), then the
|
|
.Fn sio_read
|
|
and
|
|
.Fn sio_write
|
|
functions (see below) will be non-blocking.
|
|
.Pp
|
|
The
|
|
.Fn sio_close
|
|
function closes the stream and frees all allocated resources
|
|
associated with the
|
|
.Nm libsndio
|
|
handle.
|
|
If the stream is not stopped it will be stopped first as if
|
|
.Fn sio_stop
|
|
is called.
|
|
.Ss Negotiating audio parameters
|
|
Audio streams always use linear interleaved encoding.
|
|
A frame consists of one sample for each channel in the stream.
|
|
For example, a 16-bit stereo stream has two samples per frame
|
|
and, typically, two bytes per sample (thus 4 bytes per frame).
|
|
.Pp
|
|
The set of parameters of the stream that can be controlled
|
|
is given by the following structure:
|
|
.Bd -literal
|
|
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 */
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The parameters are as follows:
|
|
.Bl -tag -width "appbufsz"
|
|
.It Va bits
|
|
Number of bits per sample: must be between 1 and 32.
|
|
.It Va 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
|
|
.Va bits .
|
|
.It Va sig
|
|
If set (i.e. non-zero) then the samples are signed, else unsigned.
|
|
.It Va le
|
|
If set, then the byte order is little endian, else big endian;
|
|
it's meaningful only if
|
|
.Va bps
|
|
\*(Gt 1.
|
|
.It Va msb
|
|
If set, then the
|
|
.Va 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
|
|
.Va bits
|
|
\*(Lt
|
|
.Va bps
|
|
* 8.
|
|
.It Va rchan
|
|
The number of recorded channels; meaningful only if
|
|
.Va SIO_REC
|
|
mode was selected.
|
|
.It Va pchan
|
|
The number of played channels; meaningful only if
|
|
.Va SIO_PLAY
|
|
mode was selected.
|
|
.It Va rate
|
|
The sampling frequency in Hz.
|
|
.It Va bufsz
|
|
The maximum number of frames that may be buffered.
|
|
This parameter takes into account any buffers, and
|
|
can be used for latency calculations.
|
|
It is read-only.
|
|
.It Va 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
|
|
.Fn sio_write
|
|
or
|
|
.Fn 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.
|
|
.It Va 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.
|
|
.It Va 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
|
|
.Va SIO_IGNORE ,
|
|
.Va SIO_SYNC
|
|
or
|
|
.Va SIO_ERROR
|
|
constants.
|
|
.El
|
|
.Pp
|
|
The following approach is recommended to negotiate parameters of the stream:
|
|
.Bl -bullet
|
|
.It
|
|
Initialize a
|
|
.Va sio_par
|
|
structure using
|
|
.Fn sio_initpar
|
|
and fill it with
|
|
the desired parameters.
|
|
If the application supports any value for a given parameter,
|
|
then the corresponding parameter should be left unset.
|
|
Then call
|
|
.Fn sio_setpar
|
|
to request the stream to use them.
|
|
.It
|
|
Call
|
|
.Fn sio_getpar
|
|
to retrieve the actual parameters of the stream
|
|
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 different to what was requested.
|
|
A difference of about 0.5% is not audible and should be ignored.
|
|
.El
|
|
.Pp
|
|
Parameters cannot be changed while the stream is in a waiting state;
|
|
if
|
|
.Fn sio_start
|
|
has been called,
|
|
.Fn sio_stop
|
|
must be called before parameters can be changed.
|
|
.Pp
|
|
If
|
|
.Nm libsndio
|
|
is used to connect to the
|
|
.Xr sndiod 1
|
|
server, a transparent emulation layer will
|
|
automatically be set up, and in this case any
|
|
parameters are supported.
|
|
.Pp
|
|
To ease filling the
|
|
.Va sio_par
|
|
structure, the
|
|
following macros can be used:
|
|
.Bl -tag -width "SIO_BPS(bits)"
|
|
.It "SIO_BPS(bits)"
|
|
Return the smallest value for
|
|
.Va bps
|
|
that is a power of two and that is large enough to
|
|
hold
|
|
.Va bits .
|
|
.It "SIO_LE_NATIVE"
|
|
Can be used to set the
|
|
.Va le
|
|
parameter when native byte order is required.
|
|
.El
|
|
.Ss Getting stream capabilities
|
|
There's no way to get an exhaustive list of all parameter
|
|
combinations the stream supports.
|
|
Applications that need to have a set of working
|
|
parameter combinations in advance can use the
|
|
.Fn sio_getcap
|
|
function.
|
|
.Pp
|
|
The
|
|
.Va 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
|
|
.Em one
|
|
of the configurations.
|
|
Parameters of different configurations
|
|
.Em are not
|
|
usable together.
|
|
.Bd -literal
|
|
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];
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The parameters are as follows:
|
|
.Bl -tag -width "rchan[SIO_NCHAN]"
|
|
.It Va enc[SIO_NENC]
|
|
Array of supported encodings.
|
|
The tuple of
|
|
.Va bits ,
|
|
.Va bps ,
|
|
.Va sig ,
|
|
.Va le
|
|
and
|
|
.Va msb
|
|
parameters are usable in the corresponding parameters
|
|
of the
|
|
.Va sio_par
|
|
structure.
|
|
.It Va rchan[SIO_NCHAN]
|
|
Array of supported channel numbers for recording usable
|
|
in the
|
|
.Va sio_par
|
|
structure.
|
|
.It Va pchan[SIO_NCHAN]
|
|
Array of supported channel numbers for playback usable
|
|
in the
|
|
.Va sio_par
|
|
structure.
|
|
.It Va rate[SIO_NRATE]
|
|
Array of supported sample rates usable
|
|
in the
|
|
.Va sio_par
|
|
structure.
|
|
.It Va nconf
|
|
Number of different configurations available, i.e. number
|
|
of filled elements of the
|
|
.Va confs[]
|
|
array.
|
|
.It Va confs[SIO_NCONF]
|
|
Array of available configurations.
|
|
Each configuration contains bitmasks indicating which
|
|
elements of the above parameter arrays are valid for the
|
|
given configuration.
|
|
For instance, if the second bit of
|
|
.Va rate
|
|
is set, in the
|
|
.Va sio_conf
|
|
structure, then the second element of the
|
|
.Va rate[SIO_NRATE]
|
|
array of the
|
|
.Va sio_cap
|
|
structure is valid for this configuration.
|
|
.El
|
|
.Ss Starting and stopping the stream
|
|
The
|
|
.Fn sio_start
|
|
function puts the stream in a waiting state:
|
|
the stream will wait for playback data to be provided
|
|
(using the
|
|
.Fn sio_write
|
|
function).
|
|
Once enough data is queued to ensure that play buffers
|
|
will not underrun, actual playback is started automatically.
|
|
If record mode only is selected, then recording starts
|
|
immediately.
|
|
In full-duplex mode, playback and recording will start
|
|
synchronously as soon as enough data to play is available.
|
|
.Pp
|
|
The
|
|
.Fn sio_stop
|
|
function stops playback and recording and puts the audio subsystem
|
|
in the same state as after
|
|
.Fn sio_open
|
|
is called.
|
|
Samples in the play buffers are not discarded, and will continue to
|
|
be played after
|
|
.Fn sio_stop
|
|
returns.
|
|
If samples to play are queued but playback hasn't started yet
|
|
then playback is forced immediately; the stream will actually stop
|
|
once the buffer is drained.
|
|
.Ss Playing and recording
|
|
When record mode is selected, the
|
|
.Fn 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
|
|
.Ar nbytes
|
|
bytes at the
|
|
.Ar addr
|
|
location and return the number of bytes stored.
|
|
Unless the
|
|
.Ar nbio_flag
|
|
flag is set, it will block until data becomes available and
|
|
will return zero only on error.
|
|
.Pp
|
|
Similarly, when play mode is selected, the
|
|
.Fn sio_write
|
|
function must be called to provide data to play.
|
|
Unless the
|
|
.Ar nbio_flag
|
|
is set,
|
|
.Fn sio_write
|
|
will block until the requested amount of data is written.
|
|
.Ss Non-blocking mode operation
|
|
If the
|
|
.Ar nbio_flag
|
|
is set on
|
|
.Fn sio_open ,
|
|
then the
|
|
.Fn sio_read
|
|
and
|
|
.Fn sio_write
|
|
functions will never block; if no data is available, they will
|
|
return zero immediately.
|
|
.Pp
|
|
Note that non-blocking mode must be used on bidirectional streams.
|
|
For instance, if recording is blocked in
|
|
.Fn sio_read
|
|
then, even if samples can be played,
|
|
.Fn sio_write
|
|
cannot be called and the play buffers may underrun.
|
|
.Pp
|
|
To avoid busy loops when non-blocking mode is used, the
|
|
.Xr poll 2
|
|
system call can be used to check if data can be
|
|
read from or written to the stream.
|
|
The
|
|
.Fn sio_pollfd
|
|
function fills the array
|
|
.Ar pfd
|
|
of
|
|
.Va pollfd
|
|
structures, used by
|
|
.Xr poll 2 ,
|
|
with
|
|
.Ar events ;
|
|
the latter is a bit-mask of
|
|
.Va POLLIN
|
|
and
|
|
.Va POLLOUT
|
|
constants; refer to
|
|
.Xr poll 2
|
|
for more details.
|
|
.Fn sio_pollfd
|
|
returns the number of
|
|
.Va pollfd
|
|
structures filled.
|
|
The
|
|
.Fn sio_revents
|
|
function returns the bit-mask set by
|
|
.Xr poll 2
|
|
in the
|
|
.Va pfd
|
|
array of
|
|
.Va pollfd
|
|
structures.
|
|
If
|
|
.Va POLLIN
|
|
is set,
|
|
.Fn sio_read
|
|
can be called without blocking.
|
|
If
|
|
.Va POLLOUT
|
|
is set,
|
|
.Fn sio_write
|
|
can be called without blocking.
|
|
POLLHUP may be set if an error occurs, even if
|
|
it is not selected with
|
|
.Fn sio_pollfd .
|
|
.Pp
|
|
The
|
|
.Fn sio_nfds
|
|
function returns the number of
|
|
.Va pollfd
|
|
structures the caller must preallocate in order to be sure
|
|
that
|
|
.Fn sio_pollfd
|
|
will never overrun.
|
|
.Ss Synchronizing non-audio events to the stream in real-time
|
|
In order to perform actions at precise positions of the 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.
|
|
.Pp
|
|
The
|
|
.Fn sio_onmove
|
|
function can be used to register the
|
|
.Va cb
|
|
callback function that will be called by the
|
|
.Nm sndio
|
|
library at regular time intervals to notify the application
|
|
the position in the stream changed.
|
|
The
|
|
.Va delta
|
|
argument contains the number of frames the hardware moved in the stream
|
|
since the last call of
|
|
.Va cb .
|
|
When the stream starts, the callback is invoked with a zero
|
|
.Va delta
|
|
argument.
|
|
The value of the
|
|
.Va arg
|
|
pointer is passed to the callback and can contain anything.
|
|
.Pp
|
|
If desired, the application can maintain the current position by
|
|
starting from zero (when
|
|
.Fn sio_start
|
|
is called) and adding to the current position
|
|
.Va delta
|
|
every time
|
|
.Fn cb
|
|
is called.
|
|
.Ss Measuring the latency and buffers usage
|
|
The playback latency is the delay it will take for the
|
|
frame just written to become audible, expressed in number of frames.
|
|
The exact playback
|
|
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
|
|
.Va bufsz
|
|
parameter (see the sections above).
|
|
There's a phase during which
|
|
.Fn sio_write
|
|
only queues data;
|
|
once there's enough data, actual playback starts.
|
|
During this phase talking about latency is meaningless.
|
|
.Pp
|
|
In any cases, at most
|
|
.Va bufsz
|
|
frames are buffered.
|
|
This value takes into account all buffers,
|
|
including device, kernel and socket buffers.
|
|
The number of frames stored is equal to the number of frames
|
|
written minus the current position.
|
|
.Pp
|
|
The recording latency is obtained similarly, by subtracting
|
|
the number of frames read from the current position.
|
|
.Pp
|
|
It is strongly discouraged to use the latency and/or the buffer
|
|
usage for anything but monitoring.
|
|
Especially, note that
|
|
.Fn sio_write
|
|
might block even if there is buffer space left;
|
|
using the buffer usage to guess if
|
|
.Fn sio_write
|
|
would block is false and leads to unreliable programs \(en consider using
|
|
.Xr poll 2
|
|
for this.
|
|
.Ss Handling buffer overruns and underruns
|
|
When the application cannot accept recorded data fast enough,
|
|
the record buffer (of size
|
|
.Va 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
|
|
.Va xrun
|
|
parameter of the
|
|
.Va sio_par
|
|
structure, the audio subsystem will behave as follows:
|
|
.Bl -tag -width "SIO_IGNORE"
|
|
.It SIO_IGNORE
|
|
The stream is paused during overruns and underruns,
|
|
thus the current position (obtained through
|
|
.Va sio_onmove )
|
|
stops being incremented.
|
|
Once the overrun and/or underrun condition is gone, the stream is unpaused;
|
|
play and record are always kept in sync.
|
|
With this mode, the application cannot notice
|
|
underruns and/or overruns and shouldn't care about them.
|
|
.Pp
|
|
This mode is the default.
|
|
It's suitable for applications,
|
|
like audio players and telephony, where time
|
|
is not important and overruns or underruns are not short.
|
|
.It 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 application is unblocked.
|
|
Similarly, if the record buffer overruns, then
|
|
samples are discarded, but the same amount of silence will be
|
|
returned later.
|
|
The current position (obtained through
|
|
.Va sio_onmove )
|
|
is still incremented.
|
|
When the play buffer underruns the play latency might become negative;
|
|
when the record buffer overruns, the record latency might become
|
|
larger than
|
|
.Va bufsz .
|
|
.Pp
|
|
This mode is suitable for applications, like music production,
|
|
where time is important and where underruns or overruns are
|
|
short and rare.
|
|
.It SIO_ERROR
|
|
With this mode, on the first play buffer underrun or
|
|
record buffer overrun, the stream is terminated and
|
|
no other function than
|
|
.Fn sio_close
|
|
will succeed.
|
|
.Pp
|
|
This mode is mostly useful for testing; portable
|
|
applications shouldn't depend on it, since it's not available
|
|
on other systems.
|
|
.El
|
|
.Ss Controlling the volume
|
|
The
|
|
.Fn sio_setvol
|
|
function can be used to set playback attenuation.
|
|
The
|
|
.Va vol
|
|
parameter takes a value between 0 (maximum attenuation)
|
|
and
|
|
.Dv SIO_MAXVOL
|
|
(no attenuation).
|
|
It specifies the weight the audio subsystem will
|
|
give to this stream.
|
|
It is not meant to control hardware parameters like
|
|
speaker gain; the
|
|
.Xr mixerctl 1
|
|
interface should be used for that purpose instead.
|
|
.Pp
|
|
An application can use the
|
|
.Fn sio_onvol
|
|
function to register a callback function that
|
|
will be called each time the volume is changed,
|
|
including when
|
|
.Fn sio_setvol
|
|
is used.
|
|
The callback is always invoked when
|
|
.Fn sio_onvol
|
|
is called in order to provide the initial volume.
|
|
An application can safely assume that once
|
|
.Fn 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,
|
|
.Fn sio_onvol
|
|
returns 0 and the callback is never invoked and calls to
|
|
.Fn sio_setvol
|
|
are ignored.
|
|
.Pp
|
|
The
|
|
.Fn sio_onvol
|
|
function can be called with a NULL argument to check whether
|
|
a volume knob is available.
|
|
.Ss Error handling
|
|
Errors related to the audio subsystem
|
|
(like hardware errors, dropped connections) and
|
|
programming errors (e.g. call to
|
|
.Fn sio_read
|
|
on a play-only stream) are considered fatal.
|
|
Once an error occurs, all functions taking a
|
|
.Va sio_hdl
|
|
argument, except
|
|
.Fn sio_close
|
|
and
|
|
.Fn sio_eof ,
|
|
stop working (i.e. always return 0).
|
|
.Pp
|
|
The
|
|
.Fn sio_eof
|
|
function can be used at any stage;
|
|
it returns 0 if there's no pending error, and a non-zero
|
|
value if there's an error.
|
|
.Sh RETURN VALUES
|
|
The
|
|
.Fn sio_open
|
|
function returns the newly created handle on success or NULL
|
|
on failure.
|
|
The
|
|
.Fn sio_setpar ,
|
|
.Fn sio_getpar ,
|
|
.Fn sio_getcap ,
|
|
.Fn sio_start ,
|
|
.Fn sio_stop ,
|
|
.Fn sio_pollfd
|
|
and
|
|
.Fn sio_setvol
|
|
functions return 1 on success and 0 on failure.
|
|
The
|
|
.Fn sio_read
|
|
and
|
|
.Fn sio_write
|
|
functions return the number of bytes transferred.
|
|
.Sh ENVIRONMENT
|
|
.Bl -tag -width "SNDIO_DEBUGXXX" -compact
|
|
.It Ev AUDIODEVICE
|
|
Device to use if
|
|
.Fn sio_open
|
|
is called with SIO_DEVANY
|
|
.Va name
|
|
argument.
|
|
.It Ev SNDIO_DEBUG
|
|
The debug level:
|
|
may be a value between 0 and 2.
|
|
.El
|
|
.Sh FILES
|
|
.Bl -tag -width "/tmp/aucat-<uid>/aucat0" -compact
|
|
.It Pa /tmp/aucat-<uid>/aucat0
|
|
Default path to
|
|
.Xr sndiod 1
|
|
socket to connect to.
|
|
.It Pa /dev/audio
|
|
Default
|
|
.Xr audio 4
|
|
device to use.
|
|
.El
|
|
.\".Sh EXAMPLES
|
|
.\".Bd -literal -offset indent
|
|
.\".Ed
|
|
.Sh SEE ALSO
|
|
.Xr sndiod 1 ,
|
|
.Xr audio 4 ,
|
|
.Xr sndio 7 ,
|
|
.Xr audio 9
|
|
.Sh BUGS
|
|
The
|
|
.Xr audio 4
|
|
driver cannot drain playback buffers in the background, thus if
|
|
.Nm libsndio
|
|
is used to directly access an
|
|
.Xr audio 4
|
|
device,
|
|
the
|
|
.Fn sio_stop
|
|
function will stop playback immediately.
|
|
.Pp
|
|
The
|
|
.Xr sndiod 1
|
|
server doesn't implement flow control (for performance reasons).
|
|
If the application doesn't consume recorded data fast enough then
|
|
.Dq "control messages"
|
|
are delayed and consequently
|
|
.Va sio_onmove
|
|
callback or volume changes may be delayed.
|
|
.Pp
|
|
The
|
|
.Fn sio_open ,
|
|
.Fn sio_setpar ,
|
|
.Fn sio_getpar ,
|
|
.Fn sio_getcap ,
|
|
.Fn sio_start
|
|
and
|
|
.Fn sio_stop
|
|
functions may block for a very short period of time, thus they should
|
|
be avoided in code sections where blocking is not desirable.
|