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