2 .\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 .\" This software was developed by Ka Ho Ng
5 .\" under sponsorship from the FreeBSD Foundation.
7 .\" Copyright (c) 2020 The FreeBSD Foundation
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
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.
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
32 .\" Note: The date here should be updated whenever a non-trivial
33 .\" change is made to the manual page.
39 .Nd "nvlist-based PCM audio device enumeration interface"
41 To compile the driver into the kernel,
42 place the following lines in the
43 kernel configuration file:
44 .Bd -ragged -offset indent
48 The ioctl interface provided by
50 device allows callers to enumerate PCM audio devices available for use.
51 In other words, it provides means to get the list of all audio devices
52 available to the system.
54 For ioctl calls that take an argument, the following structure is used:
55 .Bd -literal -offset indent
56 struct sndstioc_nv_arg {
62 Here is an example of an nvlist object with explanations of the common fields:
63 .Bd -literal -offset indent
64 dsps (NVLIST ARRAY): 1
65 from_user (BOOL): FALSE
66 nameunit (STRING): [pcm0]
67 devnode (STRING): [dsp0]
68 desc (STRING): [Generic (0x8086) (Analog Line-out)]
69 pchan (NUMBER): 1 (1) (0x1)
70 rchan (NUMBER): 0 (0) (0x0)
72 min_rate (NUMBER): 48000 (48000) (0xbb80)
73 max_rate (NUMBER): 48000 (48000) (0xbb80)
74 formats (NUMBER): 16 (16) (0x10)
75 min_chn (NUMBER): 2 (2) (0x2)
76 max_chn (NUMBER): 2 (2) (0x2)
77 provider_info (NVLIST):
78 unit (NUMBER): 0 (0) (0x0)
79 bitperfect (BOOL): FALSE
80 pvchan (NUMBER): 1 (1) (0x1)
81 rvchan (NUMBER): 0 (0) (0x0)
82 provider (STRING): [sound(4)]
85 .Bl -tag -width ".Dv provider_info"
87 Whether the PCM audio device node is created by in-kernel audio subsystem or
90 The device identification in the form of subsystem plus a unit number.
92 The PCM audio device node relative path in devfs.
94 The descripton of the PCM audio device.
96 The number of playback channels supported by hardware.
97 This can be 0 if this PCM audio device does not support playback at all.
99 The number of recording channels supported by hardware.
100 This can be 0 if this PCM audio device does not support recording at all.
102 Supported configurations in playback direction.
103 This exists only if this PCM audio device supports playback.
104 There are a number of name/value pairs inside this field:
105 .Bl -tag -width ".Dv min_rate"
107 Minimum supported sampling rate.
109 Maximum supported sampling rate.
111 Supported sample formats.
113 Minimum supported number of channels in channel layout
115 Maximum supported number of channels in channel layout
118 Supported configurations in recording direction.
119 This exists only if this PCM audio device supports recording.
120 There are a number of name/value pairs inside this field:
121 .Bl -tag -width ".Dv min_rate"
123 Minimum supported sampling rate.
125 Maximum supported sampling rate.
127 Supported sample formats.
129 Minimum supported number of channels in channel layout
131 Maximum supported number of channels in channel layout
134 Provider-specific fields.
135 This field may not exist if the PCM audio device is not provided by in-kernel
137 This field will not exist if the provider field is an empty string.
139 A string specifying the provider of the PCm audio device.
142 The following ioctls are provided for use:
143 .Bl -tag -width ".Dv SNDSTIOC_FLUSH_USER_DEVS"
144 .It Dv SNDSTIOC_REFRESH_DEVS
145 Drop any previously fetched PCM audio devices list snapshots.
146 This ioctl takes no arguments.
147 .It Dv SNDSTIOC_GET_DEVS
148 Generate and/or return PCM audio devices list snapshots to callers.
149 This ioctl takes a pointer to
150 .Fa struct sndstioc_nv_arg
151 as the first and the only argument.
152 Callers need to provide a sufficiently large buffer to hold a serialized
154 If there is no existing PCM audio device list snapshot available in the
155 internal structure of the opened sndstat.
157 a new PCM audio device list snapshot will be automatically generated.
160 to either 0 or the size of buffer provided.
163 is 0, the buffer size required to hold a serialized nvlist
164 stream of current snapshot will be returned in
169 Otherwise, if the buffer is not sufficiently large,
170 the ioctl returns success, and
173 If the buffer provided is sufficiently large,
175 will be set to the size of the serialized nvlist written to the provided buffer.
176 Once a PCM audio device list snapshot is returned to user-space successfully,
177 the snapshot stored in the subsystem's internal structure of the given
180 .It Dv SNDSTIOC_ADD_USER_DEVS
181 Add a list of PCM audio devices provided by callers to
184 This ioctl takes a pointer to
185 .Fa struct sndstioc_nv_arg
186 as the first and the only argument.
187 Callers have to provide a buffer holding a serialized nvlist.
189 should be set to the length in bytes of the serialized nvlist.
191 should be pointed to a buffer storing the serialized nvlist.
192 Userspace-backed PCM audio device nodes should be listed inside the serialized
194 .It Dv SNDSTIOC_FLUSH_USER_DEVS
195 Flush any PCM audio devices previously added by callers.
196 This ioctl takes no arguments.
199 .Bl -tag -width ".Pa /dev/sndstat" -compact
203 The following code enumerates all available PCM audio devices:
204 .Bd -literal -offset indent
205 #include <sys/types.h>
211 #include <sys/sndstat.h>
212 #include <sysexits.h>
219 struct sndstioc_nv_arg arg;
220 const nvlist_t * const *di;
224 /* Open sndstat node in read-only first */
225 fd = open("/dev/sndstat", O_RDONLY);
227 if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL))
228 err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)");
230 /* Get the size of snapshot, when nbytes = 0 */
233 if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
234 err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
236 /* Get snapshot data */
237 arg.buf = malloc(arg.nbytes);
239 err(EX_OSERR, "malloc");
240 if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
241 err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
243 /* Deserialize the nvlist stream */
244 nvl = nvlist_unpack(arg.buf, arg.nbytes, 0);
248 di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems);
249 for (i = 0; i < nitems; i++) {
250 const char *nameunit, *devnode, *desc;
253 * Examine each device nvlist item
256 nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT);
257 devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE);
258 desc = nvlist_get_string(di[i], SNDST_DSPS_DESC);
259 printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n",
260 nameunit, devnode, desc);
271 The nvlist-based ioctls support for
273 device first appeared in
276 This manual page was written by
277 .An Ka Ho Ng Aq Mt khng@FreeBSD.org .