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