xref: /freebsd/share/man/man4/sndstat.4 (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 July 26, 2024
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
68	rchan (NUMBER): 0
69	info_play (NVLIST):
70		min_rate (NUMBER): 48000
71		max_rate (NUMBER): 48000
72		formats (NUMBER): 16
73		min_chn (NUMBER): 2
74		max_chn (NUMBER): 2
75	provider_info (NVLIST):
76		unit (NUMBER): 0
77		status (STRING): on hdaa0
78		bitperfect (BOOL): FALSE
79		pvchan (NUMBER): 1
80		pvchanrate (NUMBER): 48000
81		pvchanformat (NUMBER): 0x00000010
82		rvchan (NUMBER): 0
83		rvchanrate (NUMBER): 48000
84		rvchanformat (NUMBER): 0x00000010
85		channel_info (NVLIST_ARRAY): 1
86			name (STRING): pcm0:virtual_play:dsp0.vp0
87			parentchan (STRING): pcm0:play:dsp0.p0
88			unit (NUMBER): 1
89			caps (NUMBER): 0x073200
90			latency (NUMBER): 2
91			rate (NUMBER): 48000
92			format (NUMBER): 0x201000
93			pid (NUMBER): 1234
94			comm (STRING): mpv
95			interrupts (NUMBER): 0
96			feedcount (NUMBER): 0
97			xruns (NUMBER): 0
98			left_volume (NUMBER): 45
99			right_volume (NUMBER): 45
100			hwbuf_fmt (NUMBER): 0x200010
101			hwbuf_size (NUMBER): 0
102			hwbuf_blksz (NUMBER): 0
103			hwbuf_blkcnt (NUMBER): 0
104			hwbuf_free (NUMBER): 0
105			hwbuf_ready (NUMBER): 0
106			swbuf_fmt (NUMBER): 0x201000
107			swbuf_size (NUMBER): 16384
108			swbuf_blksz (NUMBER): 2048
109			swbuf_blkcnt (NUMBER): 8
110			swbuf_free (NUMBER): 16384
111			swbuf_ready (NUMBER): 0
112			feederchain (STRING):
113				[userland ->
114				feeder_root(0x00201000) ->
115				feeder_format(0x00201000 -> 0x00200010) ->
116				feeder_volume(0x00200010) -> hardware]
117	provider (STRING): [sound(4)]
118.Ed
119.Bl -tag -width ".Dv provider_info"
120.It Dv from_user
121Whether the PCM audio device node is created by in-kernel audio subsystem or
122userspace providers.
123.It Dv nameunit
124The device identification in the form of subsystem plus a unit number.
125.It Dv devnode
126The PCM audio device node relative path in devfs.
127.It Dv desc
128The description of the PCM audio device.
129.It Dv pchan
130The number of playback channels supported by hardware.
131This can be 0 if this PCM audio device does not support playback at all.
132.It Dv rchan
133The number of recording channels supported by hardware.
134This can be 0 if this PCM audio device does not support recording at all.
135.It Dv info_play
136Supported configurations in playback direction.
137This exists only if this PCM audio device supports playback.
138There are a number of name/value pairs inside this field:
139.Bl -tag -width ".Dv min_rate"
140.It Dv min_rate
141Minimum supported sampling rate.
142.It Dv max_rate
143Maximum supported sampling rate.
144.It Dv formats
145Supported sample formats.
146.It Dv min_chn
147Minimum supported number of channels in channel layout
148.It Dv max_chn
149Maximum supported number of channels in channel layout
150.El
151.It Dv info_rec
152Supported configurations in recording direction.
153This exists only if this PCM audio device supports recording.
154There are a number of name/value pairs inside this field:
155.Bl -tag -width ".Dv min_rate"
156.It Dv min_rate
157Minimum supported sampling rate.
158.It Dv max_rate
159Maximum supported sampling rate.
160.It Dv formats
161Supported sample formats.
162.It Dv min_chn
163Minimum supported number of channels in channel layout
164.It Dv max_chn
165Maximum supported number of channels in channel layout
166.El
167.It Dv provider_info
168Provider-specific fields.
169This field may not exist if the PCM audio device is not provided by in-kernel
170interface.
171This field will not exist if the provider field is an empty string.
172For the
173.Xr sound 4
174provider, there are a number of name/value pairs inside this field:
175.Bl -tag -width ".Dv channel_info"
176.It Dv unit
177Sound card unit.
178.It Dv status
179Status string.
180Usually reports the driver the device is attached on.
181.It Dv bitperfect
182Whether the sound card has bit-perfect mode enabled.
183.It Dv pvchan
184Number of playback virtual channels.
185.It Dv pvchanrate
186Playback virtual channel sample rate.
187.It Dv pvchanformat
188Playback virtual channel format.
189.It Dv rvchan
190Number of recording virtual channels.
191.It Dv rvchanrate
192Recording virtual channel sample rate.
193.It Dv rvchanformat
194Recording virtual channel format.
195.It Dv channel_info
196Channel information.
197There are a number of name/value pairs inside this field:
198.Bl -tag -width ".Dv hwbuf_blkcnt"
199.It Dv name
200Channel name.
201.It Dv parentchan
202Parent channel name (e.g., in the case of virtual channels).
203.It Dv unit
204Channel unit.
205.It Dv caps
206OSS capabilities.
207.It Dv latency
208Latency.
209.It Dv rate
210Sampling rate.
211.It Dv format
212Sampling format.
213.It Dv pid
214PID of the process consuming the channel.
215.It Dv comm
216Name of the process consuming the channel.
217.It Dv interrupts
218Number of interrupts since the channel has been opened.
219.It Dv xruns
220Number of overruns/underruns, depending on channel direction.
221.It Dv feedcount
222Number of read/written bytes since the channel has been opened.
223.It Dv left_volume
224Left volume.
225.It Dv right_volume
226Right volume.
227.It Dv hwbuf_format
228Hardware buffer format.
229.It Dv hwbuf_size
230Hardware buffer size.
231.It Dv hwbuf_blksz
232Hardware buffer block size.
233.It Dv hwbuf_blkcnt
234Hardware buffer block count.
235.It Dv hwbuf_free
236Free space in hardware buffer (in bytes).
237.It Dv hwbuf_ready
238Number of bytes ready to be read/written from hardware buffer.
239.It Dv swbuf_format
240Software buffer format.
241.It Dv swbuf_size
242Software buffer size.
243.It Dv swbuf_blksz
244Software buffer block size.
245.It Dv swbuf_blkcnt
246Software buffer block count.
247.It Dv swbuf_free
248Free space in software buffer (in bytes).
249.It Dv swbuf_ready
250Number of bytes ready to be read/written from software buffer.
251.It Dv feederchain
252Channel feeder chain.
253.El
254.El
255.It Dv provider
256A string specifying the provider of the PCm audio device.
257.El
258.Pp
259The following ioctls are provided for use:
260.Bl -tag -width ".Dv SNDSTIOC_FLUSH_USER_DEVS"
261.It Dv SNDSTIOC_REFRESH_DEVS
262Drop any previously fetched PCM audio devices list snapshots.
263This ioctl takes no arguments.
264.It Dv SNDSTIOC_GET_DEVS
265Generate and/or return PCM audio devices list snapshots to callers.
266This ioctl takes a pointer to
267.Fa struct sndstioc_nv_arg
268as the first and the only argument.
269Callers need to provide a sufficiently large buffer to hold a serialized
270nvlist.
271If there is no existing PCM audio device list snapshot available in the
272internal structure of the opened sndstat.
273.Fa fd ,
274a new PCM audio device list snapshot will be automatically generated.
275Callers have to set
276.Fa nbytes
277to either 0 or the size of buffer provided.
278In case
279.Fa nbytes
280is 0, the buffer size required to hold a serialized nvlist
281stream of current snapshot will be returned in
282.Fa nbytes ,
283and
284.Fa buf
285will be ignored.
286Otherwise, if the buffer is not sufficiently large,
287the ioctl returns success, and
288.Fa nbytes
289will be set to 0.
290If the buffer provided is sufficiently large,
291.Fa nbytes
292will be set to the size of the serialized nvlist written to the provided buffer.
293Once a PCM audio device list snapshot is returned to user-space successfully,
294the snapshot stored in the subsystem's internal structure of the given
295.Fa fd
296will be freed.
297.It Dv SNDSTIOC_ADD_USER_DEVS
298Add a list of PCM audio devices provided by callers to
299.Pa /dev/sndstat
300device.
301This ioctl takes a pointer to
302.Fa struct sndstioc_nv_arg
303as the first and the only argument.
304Callers have to provide a buffer holding a serialized nvlist.
305.Fa nbytes
306should be set to the length in bytes of the serialized nvlist.
307.Fa buf
308should be pointed to a buffer storing the serialized nvlist.
309Userspace-backed PCM audio device nodes should be listed inside the serialized
310nvlist.
311.It Dv SNDSTIOC_FLUSH_USER_DEVS
312Flush any PCM audio devices previously added by callers.
313This ioctl takes no arguments.
314.El
315.Sh FILES
316.Bl -tag -width ".Pa /dev/sndstat" -compact
317.It Pa /dev/sndstat
318.El
319.Sh EXAMPLES
320The following code enumerates all available PCM audio devices:
321.Bd -literal -offset indent
322#include <sys/types.h>
323#include <err.h>
324#include <fcntl.h>
325#include <stdio.h>
326#include <stdlib.h>
327#include <sys/nv.h>
328#include <sys/sndstat.h>
329#include <sysexits.h>
330#include <unistd.h>
331
332int
333main()
334{
335	int fd;
336	struct sndstioc_nv_arg arg;
337	const nvlist_t * const *di;
338	size_t i, nitems;
339	nvlist_t *nvl;
340
341	/* Open sndstat node in read-only first */
342	fd = open("/dev/sndstat", O_RDONLY);
343
344	if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL))
345		err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)");
346
347	/* Get the size of snapshot, when nbytes = 0 */
348	arg.nbytes = 0;
349	arg.buf = NULL;
350	if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
351		err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
352
353	/* Get snapshot data */
354	arg.buf = malloc(arg.nbytes);
355	if (arg.buf == NULL)
356		err(EX_OSERR, "malloc");
357	if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
358		err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
359
360	/* Deserialize the nvlist stream */
361	nvl = nvlist_unpack(arg.buf, arg.nbytes, 0);
362	free(arg.buf);
363
364	/* Get DSPs array */
365	di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems);
366	for (i = 0; i < nitems; i++) {
367		const char *nameunit, *devnode, *desc;
368
369		/*
370		 * Examine each device nvlist item
371		 */
372
373		nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT);
374		devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE);
375		desc = nvlist_get_string(di[i], SNDST_DSPS_DESC);
376		printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n",
377		    nameunit, devnode, desc);
378	}
379
380	nvlist_destroy(nvl);
381	return (0);
382}
383.Ed
384.Sh SEE ALSO
385.Xr sound 4 ,
386.Xr nv 9
387.Sh HISTORY
388The nvlist-based ioctls support for
389.Nm
390device first appeared in
391.Fx 13.0 .
392.Sh AUTHORS
393This manual page was written by
394.An Ka Ho Ng Aq Mt khng@FreeBSD.org .
395