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