Reference

sndstat(4)

nvlist-based PCM audio device enumeration interface

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`0,
		    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 ⟨[email protected]⟩.

History