1.\" 2.\" SPDX-License-Identifier: BSD-2-Clause 3.\" 4.\" This software was developed by Ka Ho Ng 5.\" under sponsorship from the FreeBSD Foundation. 6.\" 7.\" Copyright (c) 2020 The FreeBSD Foundation 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" SUCH DAMAGE. 29.\" 30.\" Note: The date here should be updated whenever a non-trivial 31.\" change is made to the manual page. 32.Dd June 5, 2024 33.Dt SNDSTAT 4 34.Os 35.Sh NAME 36.Nm sndstat 37.Nd "nvlist-based PCM audio device enumeration interface" 38.Sh SYNOPSIS 39To compile the driver into the kernel, 40place the following lines in the 41kernel configuration file: 42.Bd -ragged -offset indent 43.Cd "device sound" 44.Ed 45.Sh DESCRIPTION 46The ioctl interface provided by 47.Pa /dev/sndstat 48device allows callers to enumerate PCM audio devices available for use. 49In other words, it provides means to get the list of all audio devices 50available to the system. 51.Sh IOCTLS 52For ioctl calls that take an argument, the following structure is used: 53.Bd -literal -offset indent 54struct sndstioc_nv_arg { 55 size_t nbytes; 56 void *buf; 57}; 58.Ed 59.Pp 60Here is an example of an nvlist object with explanations of the common fields: 61.Bd -literal -offset indent 62dsps (NVLIST ARRAY): 1 63 from_user (BOOL): FALSE 64 nameunit (STRING): [pcm0] 65 devnode (STRING): [dsp0] 66 desc (STRING): [Generic (0x8086) (Analog Line-out)] 67 pchan (NUMBER): 1 68 rchan (NUMBER): 0 69 info_play (NVLIST): 70 min_rate (NUMBER): 48000 71 max_rate (NUMBER): 48000 72 formats (NUMBER): 16 73 min_chn (NUMBER): 2 74 max_chn (NUMBER): 2 75 provider_info (NVLIST): 76 unit (NUMBER): 0 77 bitperfect (BOOL): FALSE 78 pvchan (NUMBER): 1 79 rvchan (NUMBER): 0 80 channel_info (NVLIST_ARRAY): 1 81 name (STRING): pcm0:virtual_play:dsp0.vp0 82 parentchan (STRING): pcm0:play:dsp0.p0 83 unit (NUMBER): 1 84 latency (NUMBER): 2 85 rate (NUMBER): 48000 86 format (NUMBER): 0x201000 87 pid (NUMBER): 1234 88 comm (STRING): mpv 89 interrupts (NUMBER): 0 90 feedcount (NUMBER): 0 91 xruns (NUMBER): 0 92 left_volume (NUMBER): 45 93 right_volume (NUMBER): 45 94 hwbuf_fmt (NUMBER): 0x200010 95 hwbuf_size (NUMBER): 0 96 hwbuf_blksz (NUMBER): 0 97 hwbuf_blkcnt (NUMBER): 0 98 hwbuf_free (NUMBER): 0 99 hwbuf_ready (NUMBER): 0 100 swbuf_fmt (NUMBER): 0x201000 101 swbuf_size (NUMBER): 16384 102 swbuf_blksz (NUMBER): 2048 103 swbuf_blkcnt (NUMBER): 8 104 swbuf_free (NUMBER): 16384 105 swbuf_ready (NUMBER): 0 106 feederchain (STRING): 107 [userland -> 108 feeder_root(0x00201000) -> 109 feeder_format(0x00201000 -> 0x00200010) -> 110 feeder_volume(0x00200010) -> hardware] 111 provider (STRING): [sound(4)] 112.Ed 113.Bl -tag -width ".Dv provider_info" 114.It Dv from_user 115Whether the PCM audio device node is created by in-kernel audio subsystem or 116userspace providers. 117.It Dv nameunit 118The device identification in the form of subsystem plus a unit number. 119.It Dv devnode 120The PCM audio device node relative path in devfs. 121.It Dv desc 122The description of the PCM audio device. 123.It Dv pchan 124The number of playback channels supported by hardware. 125This can be 0 if this PCM audio device does not support playback at all. 126.It Dv rchan 127The number of recording channels supported by hardware. 128This can be 0 if this PCM audio device does not support recording at all. 129.It Dv info_play 130Supported configurations in playback direction. 131This exists only if this PCM audio device supports playback. 132There are a number of name/value pairs inside this field: 133.Bl -tag -width ".Dv min_rate" 134.It Dv min_rate 135Minimum supported sampling rate. 136.It Dv max_rate 137Maximum supported sampling rate. 138.It Dv formats 139Supported sample formats. 140.It Dv min_chn 141Minimum supported number of channels in channel layout 142.It Dv max_chn 143Maximum supported number of channels in channel layout 144.El 145.It Dv info_rec 146Supported configurations in recording direction. 147This exists only if this PCM audio device supports recording. 148There are a number of name/value pairs inside this field: 149.Bl -tag -width ".Dv min_rate" 150.It Dv min_rate 151Minimum supported sampling rate. 152.It Dv max_rate 153Maximum supported sampling rate. 154.It Dv formats 155Supported sample formats. 156.It Dv min_chn 157Minimum supported number of channels in channel layout 158.It Dv max_chn 159Maximum supported number of channels in channel layout 160.El 161.It Dv provider_info 162Provider-specific fields. 163This field may not exist if the PCM audio device is not provided by in-kernel 164interface. 165This field will not exist if the provider field is an empty string. 166For the 167.Xr sound 4 168provider, there are a number of name/value pairs inside this field: 169.Bl -tag -width ".Dv channel_info" 170.It Dv unit 171Sound card unit. 172.It Dv bitperfect 173Whether the sound card has bit-perfect mode enabled. 174.It Dv pvchan 175Number of playback virtual channels. 176.It Dv rvchan 177Number of recording virtual channels. 178.It Dv channel_info 179Channel information. 180There are a number of name/value pairs inside this field: 181.Bl -tag -width ".Dv hwbuf_blkcnt" 182.It Dv name 183Channel name. 184.It Dv parenchan 185Parent channel name (e.g., in the case of virtual channels). 186.It Dv unit 187Channel unit. 188.It Dv latency 189Latency. 190.It Dv rate 191Sampling rate. 192.It Dv format 193Sampling format. 194.It Dv pid 195PID of the process consuming the channel. 196.It Dv comm 197Name of the process consuming the channel. 198.It Dv interrupts 199Number of interrupts since the channel has been opened. 200.It Dv xruns 201Number of overruns/underruns, depending on channel direction. 202.It Dv feedcount 203Number of read/written bytes since the channel has been opened. 204.It Dv left_volume 205Left volume. 206.It Dv right_volume 207Right volume. 208.It Dv hwbuf_format 209Hardware buffer format. 210.It Dv hwbuf_size 211Hardware buffer size. 212.It Dv hwbuf_blksz 213Hardware buffer block size. 214.It Dv hwbuf_blkcnt 215Hardware buffer block count. 216.It Dv hwbuf_free 217Free space in hardware buffer (in bytes). 218.It Dv hwbuf_ready 219Number of bytes ready to be read/written from hardware buffer. 220.It Dv swbuf_format 221Software buffer format. 222.It Dv swbuf_size 223Software buffer size. 224.It Dv swbuf_blksz 225Software buffer block size. 226.It Dv swbuf_blkcnt 227Software buffer block count. 228.It Dv swbuf_free 229Free space in software buffer (in bytes). 230.It Dv swbuf_ready 231Number of bytes ready to be read/written from software buffer. 232.It Dv feederchain 233Channel feeder chain. 234.El 235.El 236.It Dv provider 237A string specifying the provider of the PCm audio device. 238.El 239.Pp 240The following ioctls are provided for use: 241.Bl -tag -width ".Dv SNDSTIOC_FLUSH_USER_DEVS" 242.It Dv SNDSTIOC_REFRESH_DEVS 243Drop any previously fetched PCM audio devices list snapshots. 244This ioctl takes no arguments. 245.It Dv SNDSTIOC_GET_DEVS 246Generate and/or return PCM audio devices list snapshots to callers. 247This ioctl takes a pointer to 248.Fa struct sndstioc_nv_arg 249as the first and the only argument. 250Callers need to provide a sufficiently large buffer to hold a serialized 251nvlist. 252If there is no existing PCM audio device list snapshot available in the 253internal structure of the opened sndstat. 254.Fa fd , 255a new PCM audio device list snapshot will be automatically generated. 256Callers have to set 257.Fa nbytes 258to either 0 or the size of buffer provided. 259In case 260.Fa nbytes 261is 0, the buffer size required to hold a serialized nvlist 262stream of current snapshot will be returned in 263.Fa nbytes , 264and 265.Fa buf 266will be ignored. 267Otherwise, if the buffer is not sufficiently large, 268the ioctl returns success, and 269.Fa nbytes 270will be set to 0. 271If the buffer provided is sufficiently large, 272.Fa nbytes 273will be set to the size of the serialized nvlist written to the provided buffer. 274Once a PCM audio device list snapshot is returned to user-space successfully, 275the snapshot stored in the subsystem's internal structure of the given 276.Fa fd 277will be freed. 278.It Dv SNDSTIOC_ADD_USER_DEVS 279Add a list of PCM audio devices provided by callers to 280.Pa /dev/sndstat 281device. 282This ioctl takes a pointer to 283.Fa struct sndstioc_nv_arg 284as the first and the only argument. 285Callers have to provide a buffer holding a serialized nvlist. 286.Fa nbytes 287should be set to the length in bytes of the serialized nvlist. 288.Fa buf 289should be pointed to a buffer storing the serialized nvlist. 290Userspace-backed PCM audio device nodes should be listed inside the serialized 291nvlist. 292.It Dv SNDSTIOC_FLUSH_USER_DEVS 293Flush any PCM audio devices previously added by callers. 294This ioctl takes no arguments. 295.El 296.Sh FILES 297.Bl -tag -width ".Pa /dev/sndstat" -compact 298.It Pa /dev/sndstat 299.El 300.Sh EXAMPLES 301The following code enumerates all available PCM audio devices: 302.Bd -literal -offset indent 303#include <sys/types.h> 304#include <err.h> 305#include <fcntl.h> 306#include <stdio.h> 307#include <stdlib.h> 308#include <sys/nv.h> 309#include <sys/sndstat.h> 310#include <sysexits.h> 311#include <unistd.h> 312 313int 314main() 315{ 316 int fd; 317 struct sndstioc_nv_arg arg; 318 const nvlist_t * const *di; 319 size_t i, nitems; 320 nvlist_t *nvl; 321 322 /* Open sndstat node in read-only first */ 323 fd = open("/dev/sndstat", O_RDONLY); 324 325 if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)) 326 err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)"); 327 328 /* Get the size of snapshot, when nbytes = 0 */ 329 arg.nbytes = 0; 330 arg.buf = NULL; 331 if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg)) 332 err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)"); 333 334 /* Get snapshot data */ 335 arg.buf = malloc(arg.nbytes); 336 if (arg.buf == NULL) 337 err(EX_OSERR, "malloc"); 338 if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg)) 339 err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)"); 340 341 /* Deserialize the nvlist stream */ 342 nvl = nvlist_unpack(arg.buf, arg.nbytes, 0); 343 free(arg.buf); 344 345 /* Get DSPs array */ 346 di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems); 347 for (i = 0; i < nitems; i++) { 348 const char *nameunit, *devnode, *desc; 349 350 /* 351 * Examine each device nvlist item 352 */ 353 354 nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT); 355 devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE); 356 desc = nvlist_get_string(di[i], SNDST_DSPS_DESC); 357 printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n", 358 nameunit, devnode, desc); 359 } 360 361 nvlist_destroy(nvl); 362 return (0); 363} 364.Ed 365.Sh SEE ALSO 366.Xr sound 4 , 367.Xr nv 9 368.Sh HISTORY 369The nvlist-based ioctls support for 370.Nm 371device first appeared in 372.Fx 13.0 . 373.Sh AUTHORS 374This manual page was written by 375.An Ka Ho Ng Aq Mt khng@FreeBSD.org . 376