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 April 15, 2021 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 (1) (0x1) 68 rchan (NUMBER): 0 (0) (0x0) 69 info_play (NVLIST): 70 min_rate (NUMBER): 48000 (48000) (0xbb80) 71 max_rate (NUMBER): 48000 (48000) (0xbb80) 72 formats (NUMBER): 16 (16) (0x10) 73 min_chn (NUMBER): 2 (2) (0x2) 74 max_chn (NUMBER): 2 (2) (0x2) 75 provider_info (NVLIST): 76 unit (NUMBER): 0 (0) (0x0) 77 bitperfect (BOOL): FALSE 78 pvchan (NUMBER): 1 (1) (0x1) 79 rvchan (NUMBER): 0 (0) (0x0) 80 provider (STRING): [sound(4)] 81 , 82.Ed 83.Bl -tag -width ".Dv provider_info" 84.It Dv from_user 85Whether the PCM audio device node is created by in-kernel audio subsystem or 86userspace providers. 87.It Dv nameunit 88The device identification in the form of subsystem plus a unit number. 89.It Dv devnode 90The PCM audio device node relative path in devfs. 91.It Dv desc 92The description of the PCM audio device. 93.It Dv pchan 94The number of playback channels supported by hardware. 95This can be 0 if this PCM audio device does not support playback at all. 96.It Dv rchan 97The number of recording channels supported by hardware. 98This can be 0 if this PCM audio device does not support recording at all. 99.It Dv info_play 100Supported configurations in playback direction. 101This exists only if this PCM audio device supports playback. 102There are a number of name/value pairs inside this field: 103.Bl -tag -width ".Dv min_rate" 104.It Dv min_rate 105Minimum supported sampling rate. 106.It Dv max_rate 107Maximum supported sampling rate. 108.It Dv formats 109Supported sample formats. 110.It Dv min_chn 111Minimum supported number of channels in channel layout 112.It Dv max_chn 113Maximum supported number of channels in channel layout 114.El 115.It Dv info_rec 116Supported configurations in recording direction. 117This exists only if this PCM audio device supports recording. 118There are a number of name/value pairs inside this field: 119.Bl -tag -width ".Dv min_rate" 120.It Dv min_rate 121Minimum supported sampling rate. 122.It Dv max_rate 123Maximum supported sampling rate. 124.It Dv formats 125Supported sample formats. 126.It Dv min_chn 127Minimum supported number of channels in channel layout 128.It Dv max_chn 129Maximum supported number of channels in channel layout 130.El 131.It Dv provider_info 132Provider-specific fields. 133This field may not exist if the PCM audio device is not provided by in-kernel 134interface. 135This field will not exist if the provider field is an empty string. 136.It Dv provider 137A string specifying the provider of the PCm audio device. 138.El 139.Pp 140The following ioctls are provided for use: 141.Bl -tag -width ".Dv SNDSTIOC_FLUSH_USER_DEVS" 142.It Dv SNDSTIOC_REFRESH_DEVS 143Drop any previously fetched PCM audio devices list snapshots. 144This ioctl takes no arguments. 145.It Dv SNDSTIOC_GET_DEVS 146Generate and/or return PCM audio devices list snapshots to callers. 147This ioctl takes a pointer to 148.Fa struct sndstioc_nv_arg 149as the first and the only argument. 150Callers need to provide a sufficiently large buffer to hold a serialized 151nvlist. 152If there is no existing PCM audio device list snapshot available in the 153internal structure of the opened sndstat. 154.Fa fd , 155a new PCM audio device list snapshot will be automatically generated. 156Callers have to set 157.Fa nbytes 158to either 0 or the size of buffer provided. 159In case 160.Fa nbytes 161is 0, the buffer size required to hold a serialized nvlist 162stream of current snapshot will be returned in 163.Fa nbytes , 164and 165.Fa buf 166will be ignored. 167Otherwise, if the buffer is not sufficiently large, 168the ioctl returns success, and 169.Fa nbytes 170will be set to 0. 171If the buffer provided is sufficiently large, 172.Fa nbytes 173will be set to the size of the serialized nvlist written to the provided buffer. 174Once a PCM audio device list snapshot is returned to user-space successfully, 175the snapshot stored in the subsystem's internal structure of the given 176.Fa fd 177will be freed. 178.It Dv SNDSTIOC_ADD_USER_DEVS 179Add a list of PCM audio devices provided by callers to 180.Pa /dev/sndstat 181device. 182This ioctl takes a pointer to 183.Fa struct sndstioc_nv_arg 184as the first and the only argument. 185Callers have to provide a buffer holding a serialized nvlist. 186.Fa nbytes 187should be set to the length in bytes of the serialized nvlist. 188.Fa buf 189should be pointed to a buffer storing the serialized nvlist. 190Userspace-backed PCM audio device nodes should be listed inside the serialized 191nvlist. 192.It Dv SNDSTIOC_FLUSH_USER_DEVS 193Flush any PCM audio devices previously added by callers. 194This ioctl takes no arguments. 195.El 196.Sh FILES 197.Bl -tag -width ".Pa /dev/sndstat" -compact 198.It Pa /dev/sndstat 199.El 200.Sh EXAMPLES 201The following code enumerates all available PCM audio devices: 202.Bd -literal -offset indent 203#include <sys/types.h> 204#include <err.h> 205#include <fcntl.h> 206#include <stdio.h> 207#include <stdlib.h> 208#include <sys/nv.h> 209#include <sys/sndstat.h> 210#include <sysexits.h> 211#include <unistd.h> 212 213int 214main() 215{ 216 int fd; 217 struct sndstioc_nv_arg arg; 218 const nvlist_t * const *di; 219 size_t i, nitems; 220 nvlist_t *nvl; 221 222 /* Open sndstat node in read-only first */ 223 fd = open("/dev/sndstat", O_RDONLY); 224 225 if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)) 226 err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)"); 227 228 /* Get the size of snapshot, when nbytes = 0 */ 229 arg.nbytes = 0; 230 arg.buf = NULL; 231 if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg)) 232 err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)"); 233 234 /* Get snapshot data */ 235 arg.buf = malloc(arg.nbytes); 236 if (arg.buf == NULL) 237 err(EX_OSERR, "malloc"); 238 if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg)) 239 err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)"); 240 241 /* Deserialize the nvlist stream */ 242 nvl = nvlist_unpack(arg.buf, arg.nbytes, 0); 243 free(arg.buf); 244 245 /* Get DSPs array */ 246 di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems); 247 for (i = 0; i < nitems; i++) { 248 const char *nameunit, *devnode, *desc; 249 250 /* 251 * Examine each device nvlist item 252 */ 253 254 nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT); 255 devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE); 256 desc = nvlist_get_string(di[i], SNDST_DSPS_DESC); 257 printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n", 258 nameunit, devnode, desc); 259 } 260 261 nvlist_destroy(nvl); 262 return (0); 263} 264.Ed 265.Sh SEE ALSO 266.Xr sound 4 , 267.Xr nv 9 268.Sh HISTORY 269The nvlist-based ioctls support for 270.Nm 271device first appeared in 272.Fx 13.0 . 273.Sh AUTHORS 274This manual page was written by 275.An Ka Ho Ng Aq Mt khng@FreeBSD.org . 276