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