SNDSTAT(4)

NAME
sndstat - nvlist-based PCM audio device enumeration interface

SYNOPSIS
To compile the driver into the kernel, place the following lines in the kernel configuration file:

device sound

DESCRIPTION
The ioctl interface provided by /dev/sndstat device allows callers to enumerate PCM audio devices available for use. In other words, it provides means to get the list of all audio devices available to the system.

IOCTLS
For ioctl calls that take an argument, the following structure is used:

    struct sndstioc_nv_arg {
    	size_t nbytes;
    	void *buf;
    };

Here is an example of an nvlist object with explanations of the common fields:

    dsps (NVLIST ARRAY): 1
    	from_user (BOOL): FALSE
    	nameunit (STRING): [pcm0]
    	devnode (STRING): [dsp0]
    	desc (STRING): [Generic (0x8086) (Analog Line-out)]
    	pchan (NUMBER): 1
    	rchan (NUMBER): 0
    	info_play (NVLIST):
    		min_rate (NUMBER): 48000
    		max_rate (NUMBER): 48000
    		formats (NUMBER): 16
    		min_chn (NUMBER): 2
    		max_chn (NUMBER): 2
    	provider_info (NVLIST):
    		unit (NUMBER): 0
    		status (STRING): on hdaa0
    		bitperfect (BOOL): FALSE
    		pvchan (BOOL): TRUE
    		pvchanrate (NUMBER): 48000
    		pvchanformat (NUMBER): 0x00000010
    		rvchan (BOOL): TRUE
    		rvchanrate (NUMBER): 48000
    		rvchanformat (NUMBER): 0x00000010
    		channel_info (NVLIST_ARRAY): 1
    			name (STRING): dsp0.virtual_play.0
    			parentchan (STRING): dsp0.play.0
    			unit (NUMBER): 1
    			caps (NUMBER): 0x073200
    			latency (NUMBER): 2
    			rate (NUMBER): 48000
    			format (NUMBER): 0x201000
    			pid (NUMBER): 1234
    			comm (STRING): mpv
    			interrupts (NUMBER): 0
    			feedcount (NUMBER): 0
    			xruns (NUMBER): 0
    			left_volume (NUMBER): 45
    			right_volume (NUMBER): 45
    			hwbuf_fmt (NUMBER): 0x200010
    			hwbuf_rate (NUMBER): 48000
    			hwbuf_size (NUMBER): 0
    			hwbuf_blksz (NUMBER): 0
    			hwbuf_blkcnt (NUMBER): 0
    			hwbuf_free (NUMBER): 0
    			hwbuf_ready (NUMBER): 0
    			swbuf_fmt (NUMBER): 0x201000
    			swbuf_rate (NUMBER): 48000
    			swbuf_size (NUMBER): 16384
    			swbuf_blksz (NUMBER): 2048
    			swbuf_blkcnt (NUMBER): 8
    			swbuf_free (NUMBER): 16384
    			swbuf_ready (NUMBER): 0
    			feederchain (STRING):
    				[userland ->
    				feeder_root(0x00201000) ->
    				feeder_format(0x00201000 -> 0x00200010) ->
    				feeder_volume(0x00200010) -> hardware]
    	provider (STRING): [sound(4)]

from_user
    Whether the PCM audio device node is created by in-kernel audio subsystem or userspace providers.

nameunit
    The device identification in the form of subsystem plus a unit number.

devnode
    The PCM audio device node relative path in devfs.

desc
    The description of the PCM audio device.

pchan
    The number of playback channels supported by hardware. This can be 0 if this PCM audio device does not support playback at all.

rchan
    The number of recording channels supported by hardware. This can be 0 if this PCM audio device does not support recording at all.

info_play
    Supported configurations in playback direction. This exists only if this PCM audio device supports playback. There are a number of name/value pairs inside this field:

    min_rate
        Minimum supported sampling rate.

    max_rate
        Maximum supported sampling rate.

    formats
        Supported sample formats.

    min_chn
        Minimum supported number of channels in channel layout

    max_chn
        Maximum supported number of channels in channel layout

info_rec
    Supported configurations in recording direction. This exists only if this PCM audio device supports recording. There are a number of name/value pairs inside this field:

    min_rate
        Minimum supported sampling rate.

    max_rate
        Maximum supported sampling rate.

    formats
        Supported sample formats.

    min_chn
        Minimum supported number of channels in channel layout

    max_chn
        Maximum supported number of channels in channel layout

provider_info
    Provider-specific fields. This field may not exist if the PCM audio device is not provided by in-kernel interface. This field will not exist if the provider field is an empty string. For the sound(4) provider, there are a number of name/value pairs inside this field:

    unit
        Sound card unit.

    status
        Status string. Usually reports the driver the device is attached on.

    bitperfect
        Whether the sound card has bit-perfect mode enabled.

    pvchan
        Playback virtual channels enabled.

    pvchanrate
        Playback virtual channel sample rate.

    pvchanformat
        Playback virtual channel format.

    rvchan
        Recording virtual channels enabled.

    rvchanrate
        Recording virtual channel sample rate.

    rvchanformat
        Recording virtual channel format.

    channel_info
        Channel information. There are a number of name/value pairs inside this field:

        name
            Channel name.

        parentchan
            Parent channel name (e.g., in the case of virtual channels).

        unit
            Channel unit.

        caps
            OSS capabilities.

        latency
            Latency.

        rate
            Sampling rate.

        format
            Sampling format.

        pid PID of the process consuming the channel.

        comm
            Name of the process consuming the channel.

        interrupts
            Number of interrupts since the channel has been opened.

        xruns
            Number of overruns/underruns, depending on channel direction.

        feedcount
            Number of read/written bytes since the channel has been opened.

        left_volume
            Left volume.

        right_volume
            Right volume.

        hwbuf_format
            Hardware buffer format.

        hwbuf_rate
            Hardware buffer sample rate;

        hwbuf_size
            Hardware buffer size.

        hwbuf_blksz
            Hardware buffer block size.

        hwbuf_blkcnt
            Hardware buffer block count.

        hwbuf_free
            Free space in hardware buffer (in bytes).

        hwbuf_ready
            Number of bytes ready to be read/written from hardware buffer.

        swbuf_format
            Software buffer format.

        swbuf_rate
            Software buffer sample rate;

        swbuf_size
            Software buffer size.

        swbuf_blksz
            Software buffer block size.

        swbuf_blkcnt
            Software buffer block count.

        swbuf_free
            Free space in software buffer (in bytes).

        swbuf_ready
            Number of bytes ready to be read/written from software buffer.

        feederchain
            Channel feeder chain.

provider
    A string specifying the provider of the PCm audio device.

The following ioctls are provided for use:

SNDSTIOC_REFRESH_DEVS
    Drop any previously fetched PCM audio devices list snapshots. This ioctl takes no arguments.

SNDSTIOC_GET_DEVS
    Generate and/or return PCM audio devices list snapshots to callers. This ioctl takes a pointer to struct sndstioc_nv_arg as the first and the only argument. Callers need to provide a sufficiently large buffer to hold a serialized nvlist. If there is no existing PCM audio device list snapshot available in the internal structure of the opened sndstat. fd, a new PCM audio device list snapshot will be automatically generated. Callers have to set nbytes to either 0 or the size of buffer provided. In case nbytes is 0, the buffer size required to hold a serialized nvlist stream of current snapshot will be returned in nbytes, and buf will be ignored. Otherwise, if the buffer is not sufficiently large, the ioctl returns success, and nbytes will be set to 0. If the buffer provided is sufficiently large, nbytes will be set to the size of the serialized nvlist written to the provided buffer. Once a PCM audio device list snapshot is returned to user-space successfully, the snapshot stored in the subsystem's internal structure of the given fd will be freed.

SNDSTIOC_ADD_USER_DEVS
    Add a list of PCM audio devices provided by callers to /dev/sndstat device. This ioctl takes a pointer to struct sndstioc_nv_arg as the first and the only argument. Callers have to provide a buffer holding a serialized nvlist. nbytes should be set to the length in bytes of the serialized nvlist. buf should be pointed to a buffer storing the serialized nvlist. Userspace-backed PCM audio device nodes should be listed inside the serialized nvlist.

SNDSTIOC_FLUSH_USER_DEVS
    Flush any PCM audio devices previously added by callers. This ioctl takes no arguments.

FILES
/dev/sndstat

EXAMPLES
The following code enumerates all available PCM audio devices:

    #include <sys/types.h>
    #include <err.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/nv.h>
    #include <sys/sndstat.h>
    #include <sysexits.h>
    #include <unistd.h>
    int
    main()
    {
    	int fd;
    	struct sndstioc_nv_arg arg;
    	const nvlist_t * const *di;
    	size_t i, nitems;
    	nvlist_t *nvl;
    	/* Open sndstat node in read-only first */
    	fd = open("/dev/sndstat", O_RDONLY);
    	if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL))
    		err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)");
    	/* Get the size of snapshot, when nbytes = 0 */
    	arg.nbytes = 0;
    	arg.buf = NULL;
    	if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
    		err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
    	/* Get snapshot data */
    	arg.buf = malloc(arg.nbytes);
    	if (arg.buf == NULL)
    		err(EX_OSERR, "malloc");
    	if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
    		err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
    	/* Deserialize the nvlist stream */
    	nvl = nvlist_unpack(arg.buf, arg.nbytes, 0);
    	free(arg.buf);
    	/* Get DSPs array */
    	di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems);
    	for (i = 0; i < nitems; i++) {
    		const char *nameunit, *devnode, *desc;
    		/*
    		 * Examine each device nvlist item
    		 */
    		nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT);
    		devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE);
    		desc = nvlist_get_string(di[i], SNDST_DSPS_DESC);
    		printf("Name unit: `%s`, Device node: `%s`, Description: `%s`,
    		    nameunit, devnode, desc);
    	}
    	nvlist_destroy(nvl);
    	return (0);
    }

SEE ALSO
sound(4), nv(9)

HISTORY
The nvlist-based ioctls support for sndstat device first appeared in FreeBSD 13.0.

AUTHORS
This manual page was written by Ka Ho Ng <khng@FreeBSD.org>.