xref: /freebsd/share/man/man4/sndstat.4 (revision f5463265955b829775bbb32e1fd0bc11dafc36ce)
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