| AUDIO(4) | Device Drivers Manual | AUDIO(4) | 
audio —
#include <sys/audioio.h>
audio driver provides support for various audio
  peripherals. It provides a uniform programming interface layer above different
  underlying audio hardware drivers. The audio layer provides full-duplex
  operation if the underlying hardware configuration supports it.
There are four device files available for audio operation: /dev/audio, /dev/sound, /dev/audioctl, and /dev/mixer.
/dev/audio and /dev/sound are used for recording or playback of digital samples.
/dev/mixer is used to manipulate volume, recording source, or other audio mixer functions.
/dev/audioctl accepts the same ioctl(2) operations as /dev/sound, but no other operations. It can be opened at any time and can be used to manipulate the audio device while it is in use.
On a full-duplex device, reads and writes may operate concurrently without interference.
On a half-duplex device, if there are any recording descriptors already, opening with write mode will fail. Similarly, if there are any playback descriptors already, opening with read mode will fail. If both playback and recording are requested on a half-duplex device, it will be treated as playback mode.
On either type of device, opening with write mode will start in playback mode, opening with read mode will start in recording mode.
If the playback mode is paused then silence is played instead of the provided samples, and if recording is paused then the process blocks in read(2) until recording is unpaused.
If a writing process does not call write(2) frequently enough to provide samples at the pace the hardware consumes them silence is inserted. If a reading process does not call read(2) frequently enough, it will simply miss samples.
The audio driver supports track multiplexing. All sampling devices can be opened at any time without interference. For playback, all tracks opened simultaneously are mixed, even if their specified format is different. For recording, recorded data is distributed to all opened tracks, even if their specified format is different. To achieve this, the audio driver has a small efficient encoding converter, a channel mixer, and a frequency converter. The frequency conversion adapts the simplest way (interpolation method for upward, and simple thinning method for downward) due to restriction in kernel resources and processing time. It will work well in most case but don't expect excessive quality.
The audio device is normally accessed with
    read(2) or
    write(2) calls, but it can also
    be mapped into user memory with
    mmap(2). Once the device has
    been mapped it can no longer be accessed by read or write; all access is by
    reading and writing to the mapped memory. The mmap'ped buffer appears as a
    block of memory of size buffersize (as available via
    AUDIO_GETINFO or
    AUDIO_GETBUFINFO). The audio driver will
    continuously move data from this buffer from/to the mixing buffer, wrapping
    around at the end of the buffer. To find out where the hardware is currently
    accessing data in the buffer the AUDIO_GETIOFFS and
    AUDIO_GETOOFFS calls can be used. Note that
    mmap(2) no longer maps hardware
    buffers directly. Now it is achieved by emulation so don't expect any
    improvements excessively rather than normal
    write(2). For historical
    reasons, only encodings that are not set
    AUDIO_ENCODINGFLAG_EMULATED are able to
    mmap(2).
The audio device, like most devices, can be used in
    select(2), can be set in
    non-blocking mode and can be set (with a FIOASYNC
    ioctl) to send a SIGIO when I/O is possible. The
    mixer device can be set to generate a SIGIO whenever
    a mixer value is changed.
The following ioctl(2) commands are supported on the sample devices:
AUDIO_FLUSHAUDIO_PERROR
    (int)AUDIO_RERROR
    (int)AUDIO_WSEEK
    (u_long)AUDIO_DRAINAUDIO_GETDEV
    (audio_device_t)
typedef struct audio_device {
        char name[MAX_AUDIO_DEV_LEN];
        char version[MAX_AUDIO_DEV_LEN];
        char config[MAX_AUDIO_DEV_LEN];
} audio_device_t;
    
    AUDIO_GETENC
    (audio_encoding_t)
typedef struct audio_encoding {
	int index;      /* input: nth encoding */
	char name[MAX_AUDIO_DEV_LEN]; /* name of encoding */
	int encoding;   /* value for encoding parameter */
	int precision;  /* value for precision parameter */
	int flags;
#define AUDIO_ENCODINGFLAG_EMULATED 1 /* software emulation mode */
} audio_encoding_t;
    
    To query all the supported encodings, start with an index field of 0 and continue with successive encodings (1, 2, ...) until the command returns an error.
AUDIO_GETFD
    (int)AUDIO_SETFD
    (int)AUDIO_GETPROPS
    (int)AUDIO_PROP_FULLDUPLEXAUDIO_PROP_MMAPAUDIO_PROP_INDEPENDENTAUDIO_PROP_PLAYBACKAUDIO_PROP_CAPTUREAUDIO_GETIOFFS
    (audio_offset_t)AUDIO_GETOOFFS
    (audio_offset_t)
typedef struct audio_offset {
	u_int	samples;   /* Total number of bytes transferred */
	u_int	deltablks; /* Blocks transferred since last checked */
	u_int	offset;    /* Physical transfer offset in buffer */
} audio_offset_t;
    
    AUDIO_GETINFO
    (audio_info_t)AUDIO_GETBUFINFO
    (audio_info_t)AUDIO_SETINFO
    (audio_info_t)
typedef struct audio_info {
	struct	audio_prinfo play;   /* info for play (output) side */
	struct	audio_prinfo record; /* info for record (input) side */
        u_int	monitor_gain;			/* input to output mix [HWmixer] */
	/* BSD extensions */
	u_int	blocksize;	/* read/write block size [track] */
	u_int	hiwat;		/* output high water mark [track] */
	u_int	lowat;		/* output low water mark [track] */
	u_int	_ispare1;
	u_int	mode;		/* current operation mode [track] */
#define AUMODE_PLAY	0x01
#define AUMODE_RECORD	0x02
#define AUMODE_PLAY_ALL 0x04	/* Not used anymore */
} audio_info_t;
    
    When setting the current state with
        AUDIO_SETINFO, the audio_info structure should
        first be initialized with
        AUDIO_INITINFO(&info) and then the
        particular values to be changed should be set. This allows the audio
        driver to only set those things that you wish to change and eliminates
        the need to query the device with AUDIO_GETINFO
        or AUDIO_GETBUFINFO first.
The mode field indicates current
        operation mode, either one of AUMODE_PLAY or
        AUMODE_RECORD. These two flags can not be
        changed once this descriptor is opened. For playback mode, the obsolete
        AUMODE_PLAY_ALL flag can be set but has no
        effect.
hiwat and lowat are used to control write behavior. Writes to the audio devices will queue up blocks until the high-water mark is reached, at which point any more write calls will block until the queue is drained to the low-water mark. hiwat and lowat set those high- and low-water marks (in audio blocks). The default for hiwat is the maximum value and for lowat 75% of hiwat.
blocksize sets the current audio blocksize. The generic audio driver layer and the hardware driver have the opportunity to adjust this block size to get it within implementation-required limits. Normally the blocksize is calculated to correspond to the value of the hw.audioX.blk_ms sysctl and is recalculated when the encoding parameters change. If the descriptor is opened for read only, blocksize indicates the blocksize for the recording track. Otherwise, blocksize indicates the blocksize for the playback track.
struct audio_prinfo {
	u_int	sample_rate;	/* sample rate in samples/s [track] */
	u_int	channels;	/* number of channels, usually 1 or 2 [track] */
	u_int	precision;	/* number of bits/sample [track] */
	u_int	encoding;	/* data encoding (AUDIO_ENCODING_* below) [track] */
	u_int	gain;		/* volume level [HWmixer] */
	u_int	port;		/* selected I/O port [HWmixer] */
	u_long	seek;		/* BSD extension [track] */
	u_int	avail_ports;	/* available I/O ports [HWmixer] */
	u_int	buffer_size;	/* total size audio buffer [track] */
	u_int	_ispare[1];
	u_int	samples;	/* number of samples [track] */
	u_int	eof;		/* End Of File (zero-size writes) counter [track] */
	u_char	pause;		/* non-zero if paused, zero to resume [track] */
	u_char	error;		/* non-zero if underflow/overflow occurred [track] */
	u_char	waiting;	/* non-zero if another process hangs in open [track] */
	u_char	balance;	/* stereo channel balance [HWmixer] */
	u_char	cspare[2];
	u_char	open;		/* non-zero if currently open [trackmixer] */
	u_char	active;		/* non-zero if I/O is currently active [trackmixer] */
};
    
    Note: many hardware audio drivers require identical playback
        and recording sample rates, sample encodings, and channel counts. The
        playing information is always set last and will prevail on such
        hardware. If the hardware can handle different settings the
        AUDIO_PROP_INDEPENDENT property is set.
The encoding parameter can have the following values:
AUDIO_ENCODING_ULAWAUDIO_ENCODING_ALAWAUDIO_ENCODING_SLINEARAUDIO_ENCODING_ULINEARAUDIO_ENCODING_ADPCMAUDIO_ENCODING_SLINEAR_LEAUDIO_ENCODING_SLINEAR_BEAUDIO_ENCODING_ULINEAR_LEAUDIO_ENCODING_ULINEAR_BEAUDIO_ENCODING_AC3The audio driver accepts the following
        formats. encoding and
        precision are one of the values obtained by
        AUDIO_GETENC, regardless of formats supported by
        underlying driver. frequency ranges from 1000Hz to
        192000Hz, regardless of frequency (ranges) supported by underlying
        driver. channels depends your underlying driver.
        If the underlying driver only supports monaural (1channel) or stereo
        (2channels), you can specify 1 or 2 regardless of number of channels
        supported by underlying driver. If the underlying driver supports three
        or more channels, you can specify the number of channels supported by
        the underlying driver or less.
The gain, port and
        balance settings provide simple shortcuts to the
        richer mixer interface described below and are not obtained by
        AUDIO_GETBUFINFO. The gain should be in the
        range [AUDIO_MIN_GAIN,
        AUDIO_MAX_GAIN] and the balance in the range
        [AUDIO_LEFT_BALANCE,
        AUDIO_RIGHT_BALANCE] with the normal setting at
        AUDIO_MID_BALANCE.
The input port should be a combination of:
AUDIO_MICROPHONEAUDIO_LINE_INAUDIO_CDThe output port should be a combination of:
AUDIO_SPEAKERAUDIO_HEADPHONEAUDIO_LINE_OUTThe available ports can be found in
        avail_ports
        (AUDIO_GETBUFINFO only).
buffer_size is the total size of the audio buffer. The buffer size divided by the blocksize gives the maximum value for hiwat. Currently the buffer_size can only be read and not set.
The seek and
        samples fields are only used by
        AUDIO_GETINFO and
        AUDIO_GETBUFINFO. seek
        represents the count of bytes pending; samples
        represents the total number of bytes recorded or played, less those that
        were dropped due to inadequate consumption/production rates.
pause returns the current pause/unpause
        state for recording or playback. For
        AUDIO_SETINFO, if the pause value is specified
        it will either pause or unpause the particular direction.
AUDIO_QUERYFORMAT
    (audio_format_query_t)AUDIO_GETENC, to query all the supported formats,
      start with an index field of 0 and continue with successive formats (1, 2,
      ...) until the command returns an error.
    
typedef struct audio_format_query {
	u_int	index;
	struct audio_format fmt;
} audio_format_query_t;
    
    AUDIO_GETFORMAT
    (audio_info_t)mode indicates which direction is valid.
AUDIO_SETFORMAT
    (audio_info_t)AUDIO_GETFORMAT, only above members in
      audio_info_t are used. Members which is not listed or belong in invalid
      direction are ignored. The parameters can be chosen from the choices
      obtained by AUDIO_QUERYFORMAT.AUDIO_GETCHAN
    (int)AUDIO_SETCHAN
    (int)AUDIO_GETDEV
    (audio_device_t)AUDIO_MIXER_READ
    (mixer_ctrl_t)AUDIO_MIXER_WRITE
    (mixer_ctrl_t)
#define AUDIO_MIXER_CLASS  0
#define AUDIO_MIXER_ENUM   1
#define AUDIO_MIXER_SET    2
#define AUDIO_MIXER_VALUE  3
typedef struct mixer_ctrl {
	int dev;			/* input: nth device */
	int type;
	union {
		int ord;		/* enum */
		int mask;		/* set */
		mixer_level_t value;	/* value */
	} un;
} mixer_ctrl_t;
#define AUDIO_MIN_GAIN  0
#define AUDIO_MAX_GAIN  255
typedef struct mixer_level {
        int num_channels;
        u_char level[8];               /* [num_channels] */
} mixer_level_t;
#define AUDIO_MIXER_LEVEL_MONO  0
#define AUDIO_MIXER_LEVEL_LEFT  0
#define AUDIO_MIXER_LEVEL_RIGHT 1
    
    For a mixer value, the value field
        specifies both the number of channels and the values for each channel.
        If the channel count does not match the current channel count, the
        attempt to change the setting may fail (depending on the hardware device
        driver implementation). For an enumeration value, the
        ord field should be set to one of the possible
        values as returned by a prior
        AUDIO_MIXER_DEVINFO command. The type
        AUDIO_MIXER_CLASS is only used for classifying
        particular mixer device types and is not used for
        AUDIO_MIXER_READ or
        AUDIO_MIXER_WRITE.
AUDIO_MIXER_DEVINFO
    (mixer_devinfo_t)
typedef struct mixer_devinfo {
	int index;		/* input: nth mixer device */
	audio_mixer_name_t label;
	int type;
	int mixer_class;
	int next, prev;
#define AUDIO_MIXER_LAST	-1
	union {
		struct audio_mixer_enum {
			int num_mem;
			struct {
				audio_mixer_name_t label;
				int ord;
			} member[32];
		} e;
		struct audio_mixer_set {
			int num_mem;
			struct {
				audio_mixer_name_t label;
				int mask;
			} member[32];
		} s;
		struct audio_mixer_value {
			audio_mixer_name_t units;
			int num_channels;
			int delta;
		} v;
	} un;
} mixer_devinfo_t;
    
    The label field identifies the name of
        this particular mixer control. The index field may
        be used as the dev field in
        AUDIO_MIXER_READ and
        AUDIO_MIXER_WRITE commands. The
        type field identifies the type of this mixer
        control. Enumeration types are typically used for on/off style controls
        (e.g. a mute control) or for input/output device selection (e.g. select
        recording input source from CD, line in, or microphone). Set types are
        similar to enumeration types but any combination of the mask bits can be
        used.
The mixer_class field identifies what
        class of control this is. The (arbitrary) value set by the hardware
        driver may be determined by examining the
        mixer_class field of the class itself, a mixer of
        type AUDIO_MIXER_CLASS. For example, a mixer
        controlling the input gain on the line in circuit would have a
        mixer_class that matches an input class device
        with the name “inputs”
        (AudioCinputs), and would have a
        label of “line”
        (AudioNline). Mixer controls which control audio
        circuitry for a particular audio source (e.g. line-in, CD in, DAC
        output) are collected under the input class, while those which control
        all audio sources (e.g. master volume, equalization controls) are under
        the output class. Hardware devices capable of recording typically also
        have a record class, for controls that only affect recording, and also a
        monitor class.
The next and prev
        may be used by the hardware device driver to provide hints for the next
        and previous devices in a related set (for example, the line in level
        control would have the line in mute as its “next” value).
        If there is no relevant next or previous value,
        AUDIO_MIXER_LAST is specified.
For AUDIO_MIXER_ENUM mixer control
        types, the enumeration values and their corresponding names are filled
        in. For example, a mute control would return appropriate values paired
        with AudioNon and
        AudioNoff. For
        AUDIO_MIXER_VALUE and
        AUDIO_MIXER_SET mixer control types, the channel
        count is returned; the units name specifies what the level controls
        (typical values are AudioNvolume,
        AudioNtreble,
        AudioNbass).
By convention, all the mixer devices can be distinguished from
    other mixer controls because they use a name from one of the
    AudioC* string values.
| March 28, 2020 | NetBSD 10.1 |