1.\" 2.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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.\" $FreeBSD$ 31.\" 32.\" Note: The date here should be updated whenever a non-trivial 33.\" change is made to the manual page. 34.Dd December 7, 2020 35.Dt SNDSTAT 4 36.Os 37.Sh NAME 38.Nm sndstat 39.Nd "nvlist-based PCM audio device enumeration interface" 40.Sh SYNOPSIS 41To compile the driver into the kernel, 42place the following lines in the 43kernel configuration file: 44.Bd -ragged -offset indent 45.Cd "device sound" 46.Ed 47.Sh DESCRIPTION 48The ioctl interface provided by 49.Pa /dev/sndstat 50device allows callers to enumeration PCM audio devices available for use. 51.Sh IOCTLS 52For all ioctls requiring data exchange between the subsystem and callers, 53the following structures are used to describe a serialized nvlist: 54.Bd -literal -offset indent 55struct sndstat_nvlbuf_arg { 56 size_t nbytes; 57 void *buf; 58}; 59.Ed 60.Pp 61Here is an example of an nvlist, with explanations of the common fields: 62.Bd -literal -offset indent 63dsps (NVLIST ARRAY): 1 64 from_user (BOOL): FALSE 65 nameunit (STRING): [pcm0] 66 devnode (STRING): [dsp0] 67 desc (STRING): [Generic (0x8086) (Analog Line-out)] 68 pchan (NUMBER): 1 (1) (0x1) 69 rchan (NUMBER): 0 (0) (0x0) 70 pminrate (NUMBER): 48000 (48000) (0xbb80) 71 pmaxrate (NUMBER): 48000 (48000) (0xbb80) 72 pfmts (NUMBER): 2097168 (2097168) (0x200010) 73 provider_info (NVLIST): 74 unit (NUMBER): 0 (0) (0x0) 75 bitperfect (BOOL): FALSE 76 pvchan (NUMBER): 1 (1) (0x1) 77 rvchan (NUMBER): 0 (0) (0x0) 78 provider (STRING): [sound(4)] 79 , 80.Ed 81.Bl -tag -width ".Dv provider_info" 82.It Dv from_user 83Whether the PCM audio device node is created by in-kernel audio subsystem or 84userspace providers. 85.It Dv nameunit 86The device identification in the form of subsystem plus a unit number. 87.It Dv devnode 88The PCM audio device node relative path in devfs. 89.It Dv desc 90The descripton of the PCM audio device. 91.It Dv pchan 92The number of playback channels supported by hardware. 93This can be 0 if this PCM audio device does not support playback at all. 94.It Dv rchan 95The number of recording channels supported by hardware. 96This can be 0 if this PCM audio device does not support recording at all. 97.It Dv pminrate 98The minimum supported playback direction sampling rate. 99Only exists if pchan is greater than 0. 100.It Dv pmaxrate 101The maximum supported playback direction sampling rate. 102Only exists if pchan is greater than 0. 103.It Dv pfmts 104The supported playback direction sample format. 105Only exists if pchan is greater than 0. 106.It Dv rminrate 107The minimum supported recording direction sampling rate. 108Only exists if rchan is greater than 0. 109.It Dv rmaxrate 110The maximum supported recording direction sampling rate. 111Only exists if rchan is greater than 0. 112.It Dv rfmts 113The supported playback recording sample format. 114Only exists if rchan is greater than 0. 115.It Dv provider_info 116Provider-specific fields. 117This field may not exist if the PCM audio device is not provided by in-kernel 118interface. 119This field will not exist if the provider field is an empty string. 120.It Dv provider 121A string specifying the provider of the PCm audio device. 122.El 123.Pp 124The following ioctls are providede for use: 125.Bl -tag -width ".Dv SNDSTAT_FLUSH_USER_DEVS" 126.It Dv SNDSTAT_REFRESH_DEVS 127Drop any previously fetched PCM audio devices list snapshots. 128This ioctl takes no arguments. 129.It Dv SNDSTAT_GET_DEVS 130Generate and/or return PCM audio devices list snapshots to callers. 131This ioctl takes a pointer to 132.Fa struct sndstat_nvlbuf_arg 133as the first and the only argument. 134Callers need to provide a sufficiently large buffer to hold a serialized 135nvlist. 136If there is no existing PCM audio device list snapshot available in the 137internal structure of the opened sndstat. 138.Fa fd , 139a new PCM audio device list snapshot will be automatically generated. 140Callers have to set 141.Fa nbytes 142to either 0 or the size of buffer provided. 143In case 144.Fa nbytes 145is 0, the buffer size required to hold a serialized nvlist 146stream of current snapshot will be returned in 147.Fa nbytes , 148and 149.Fa buf 150will be ignored. 151Otherwise, if the buffer is not sufficiently large, 152the ioctl returns success, and 153.Fa nbytes 154will be set to 0. 155If the buffer provided is sufficiently large, 156.Fa nbytes 157will be set to the size of the serialized nvlist written to the provided buffer. 158Once a PCM audio device list snapshot is returned to user-space successfully, 159the snapshot stored in the subsystem's internal structure of the given 160.Fa fd 161will be freed. 162.It Dv SNDSTAT_ADD_USER_DEVS 163Add a list of PCM audio devices provided by callers to 164.Pa /dev/sndstat 165device. 166This ioctl takes a pointer to 167.Fa struct sndstat_nvlbuf_arg 168as the first and the only argument. 169Callers have to provide a buffer holding a serialized nvlist. 170.Fa nbytes 171should be set to the length in bytes of the serialized nvlist. 172.Fa buf 173should be pointed to a buffer storing the serialized nvlist. 174Userspace-backed PCM audio device nodes should be listed inside the serialized 175nvlist. 176.It Dv SNDSTAT_FLUSH_USER_DEVS 177Flush any PCM audio devices previously added by callers. 178This ioctl takes no arguments. 179.El 180.Sh FILES 181.Bl -tag -width ".Pa /dev/sndstat" -compact 182.It Pa /dev/sndstat 183.El 184.Sh EXAMPLES 185The following code enumerates all available PCM audio devices: 186.Bd -literal -offset indent 187#include <sys/types.h> 188#include <err.h> 189#include <fcntl.h> 190#include <stdio.h> 191#include <stdlib.h> 192#include <sys/nv.h> 193#include <sys/sndstat.h> 194#include <sysexits.h> 195#include <unistd.h> 196 197int 198main() 199{ 200 int fd; 201 struct sndstat_nvlbuf_arg arg; 202 const nvlist_t * const *di; 203 size_t i, nitems; 204 nvlist_t *nvl; 205 206 /* Open sndstat node in read-only first */ 207 fd = open("/dev/sndstat", O_RDONLY); 208 209 if (ioctl(fd, SNDSTAT_REFRESH_DEVS, NULL)) 210 err(1, "ioctl(fd, SNDSTAT_REFRESH_DEVS, NULL)"); 211 212 /* Get the size of snapshot, when nbytes = 0 */ 213 arg.nbytes = 0; 214 arg.buf = NULL; 215 if (ioctl(fd, SNDSTAT_GET_DEVS, &arg)) 216 err(1, "ioctl(fd, SNDSTAT_GET_DEVS, &arg)"); 217 218 /* Get snapshot data */ 219 arg.buf = malloc(arg.nbytes); 220 if (arg.buf == NULL) 221 err(EX_OSERR, "malloc"); 222 if (ioctl(fd, SNDSTAT_GET_DEVS, &arg)) 223 err(1, "ioctl(fd, SNDSTAT_GET_DEVS, &arg)"); 224 225 /* Deserialize the nvlist stream */ 226 nvl = nvlist_unpack(arg.buf, arg.nbytes, 0); 227 free(arg.buf); 228 229 /* Get DSPs array */ 230 di = nvlist_get_nvlist_array(nvl, SNDSTAT_LABEL_DSPS, &nitems); 231 for (i = 0; i < nitems; i++) { 232 const char *nameunit, *devnode, *desc; 233 234 /* 235 * Examine each device nvlist item 236 */ 237 238 nameunit = nvlist_get_string(di[i], SNDSTAT_LABEL_NAMEUNIT); 239 devnode = nvlist_get_string(di[i], SNDSTAT_LABEL_DEVNODE); 240 desc = nvlist_get_string(di[i], SNDSTAT_LABEL_DESC); 241 printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n", 242 nameunit, devnode, desc); 243 } 244 245 nvlist_destroy(nvl); 246 return (0); 247} 248.Ed 249.Sh SEE ALSO 250.Xr sound 4 , 251.Xr nv 9 252.Sh HISTORY 253The nvlist-based ioctls support for 254.Nm 255device first appeared in 256.Fx 13.0 . 257.Sh AUTHORS 258This manual page was written by 259.An Ka Ho Ng Aq Mt khng@FreeBSD.org . 260