1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
.\" This software was developed by Ka Ho Ng
.\" under sponsorship from the FreeBSD Foundation.
.\"
.\" Copyright (c) 2020 The FreeBSD Foundation
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" Note: The date here should be updated whenever a non-trivial
.\" change is made to the manual page.
.Dd July 26, 2024
.Dt SNDSTAT 4
.Os
.Sh NAME
.Nm sndstat
.Nd "nvlist-based PCM audio device enumeration interface"
.Sh SYNOPSIS
To compile the driver into the kernel,
place the following lines in the
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device sound"
.Ed
.Sh DESCRIPTION
The ioctl interface provided by
.Pa /dev/sndstat
device allows callers to enumerate PCM audio devices available for use.
In other words, it provides means to get the list of all audio devices
available to the system.
.Sh IOCTLS
For ioctl calls that take an argument, the following structure is used:
.Bd -literal -offset indent
struct sndstioc_nv_arg {
size_t nbytes;
void *buf;
};
.Ed
.Pp
Here is an example of an nvlist object with explanations of the common fields:
.Bd -literal -offset indent
dsps (NVLIST ARRAY): 1
from_user (BOOL): FALSE
nameunit (STRING): [pcm0]
devnode (STRING): [dsp0]
desc (STRING): [Generic (0x8086) (Analog Line-out)]
pchan (NUMBER): 1
rchan (NUMBER): 0
info_play (NVLIST):
min_rate (NUMBER): 48000
max_rate (NUMBER): 48000
formats (NUMBER): 16
min_chn (NUMBER): 2
max_chn (NUMBER): 2
provider_info (NVLIST):
unit (NUMBER): 0
status (STRING): on hdaa0
bitperfect (BOOL): FALSE
pvchan (BOOL): TRUE
pvchanrate (NUMBER): 48000
pvchanformat (NUMBER): 0x00000010
rvchan (BOOL): TRUE
rvchanrate (NUMBER): 48000
rvchanformat (NUMBER): 0x00000010
channel_info (NVLIST_ARRAY): 1
name (STRING): dsp0.virtual_play.0
parentchan (STRING): dsp0.play.0
unit (NUMBER): 1
caps (NUMBER): 0x073200
latency (NUMBER): 2
rate (NUMBER): 48000
format (NUMBER): 0x201000
pid (NUMBER): 1234
comm (STRING): mpv
interrupts (NUMBER): 0
feedcount (NUMBER): 0
xruns (NUMBER): 0
left_volume (NUMBER): 45
right_volume (NUMBER): 45
hwbuf_fmt (NUMBER): 0x200010
hwbuf_rate (NUMBER): 48000
hwbuf_size (NUMBER): 0
hwbuf_blksz (NUMBER): 0
hwbuf_blkcnt (NUMBER): 0
hwbuf_free (NUMBER): 0
hwbuf_ready (NUMBER): 0
swbuf_fmt (NUMBER): 0x201000
swbuf_rate (NUMBER): 48000
swbuf_size (NUMBER): 16384
swbuf_blksz (NUMBER): 2048
swbuf_blkcnt (NUMBER): 8
swbuf_free (NUMBER): 16384
swbuf_ready (NUMBER): 0
feederchain (STRING):
[userland ->
feeder_root(0x00201000) ->
feeder_format(0x00201000 -> 0x00200010) ->
feeder_volume(0x00200010) -> hardware]
provider (STRING): [sound(4)]
.Ed
.Bl -tag -width ".Dv provider_info"
.It Dv from_user
Whether the PCM audio device node is created by in-kernel audio subsystem or
userspace providers.
.It Dv nameunit
The device identification in the form of subsystem plus a unit number.
.It Dv devnode
The PCM audio device node relative path in devfs.
.It Dv desc
The description of the PCM audio device.
.It Dv pchan
The number of playback channels supported by hardware.
This can be 0 if this PCM audio device does not support playback at all.
.It Dv rchan
The number of recording channels supported by hardware.
This can be 0 if this PCM audio device does not support recording at all.
.It Dv info_play
Supported configurations in playback direction.
This exists only if this PCM audio device supports playback.
There are a number of name/value pairs inside this field:
.Bl -tag -width ".Dv min_rate"
.It Dv min_rate
Minimum supported sampling rate.
.It Dv max_rate
Maximum supported sampling rate.
.It Dv formats
Supported sample formats.
.It Dv min_chn
Minimum supported number of channels in channel layout
.It Dv max_chn
Maximum supported number of channels in channel layout
.El
.It Dv info_rec
Supported configurations in recording direction.
This exists only if this PCM audio device supports recording.
There are a number of name/value pairs inside this field:
.Bl -tag -width ".Dv min_rate"
.It Dv min_rate
Minimum supported sampling rate.
.It Dv max_rate
Maximum supported sampling rate.
.It Dv formats
Supported sample formats.
.It Dv min_chn
Minimum supported number of channels in channel layout
.It Dv max_chn
Maximum supported number of channels in channel layout
.El
.It Dv provider_info
Provider-specific fields.
This field may not exist if the PCM audio device is not provided by in-kernel
interface.
This field will not exist if the provider field is an empty string.
For the
.Xr sound 4
provider, there are a number of name/value pairs inside this field:
.Bl -tag -width ".Dv channel_info"
.It Dv unit
Sound card unit.
.It Dv status
Status string.
Usually reports the driver the device is attached on.
.It Dv bitperfect
Whether the sound card has bit-perfect mode enabled.
.It Dv pvchan
Playback virtual channels enabled.
.It Dv pvchanrate
Playback virtual channel sample rate.
.It Dv pvchanformat
Playback virtual channel format.
.It Dv rvchan
Recording virtual channels enabled.
.It Dv rvchanrate
Recording virtual channel sample rate.
.It Dv rvchanformat
Recording virtual channel format.
.It Dv channel_info
Channel information.
There are a number of name/value pairs inside this field:
.Bl -tag -width ".Dv hwbuf_blkcnt"
.It Dv name
Channel name.
.It Dv parentchan
Parent channel name (e.g., in the case of virtual channels).
.It Dv unit
Channel unit.
.It Dv caps
OSS capabilities.
.It Dv latency
Latency.
.It Dv rate
Sampling rate.
.It Dv format
Sampling format.
.It Dv pid
PID of the process consuming the channel.
.It Dv comm
Name of the process consuming the channel.
.It Dv interrupts
Number of interrupts since the channel has been opened.
.It Dv xruns
Number of overruns/underruns, depending on channel direction.
.It Dv feedcount
Number of read/written bytes since the channel has been opened.
.It Dv left_volume
Left volume.
.It Dv right_volume
Right volume.
.It Dv hwbuf_format
Hardware buffer format.
.It Dv hwbuf_rate
Hardware buffer sample rate;
.It Dv hwbuf_size
Hardware buffer size.
.It Dv hwbuf_blksz
Hardware buffer block size.
.It Dv hwbuf_blkcnt
Hardware buffer block count.
.It Dv hwbuf_free
Free space in hardware buffer (in bytes).
.It Dv hwbuf_ready
Number of bytes ready to be read/written from hardware buffer.
.It Dv swbuf_format
Software buffer format.
.It Dv swbuf_rate
Software buffer sample rate;
.It Dv swbuf_size
Software buffer size.
.It Dv swbuf_blksz
Software buffer block size.
.It Dv swbuf_blkcnt
Software buffer block count.
.It Dv swbuf_free
Free space in software buffer (in bytes).
.It Dv swbuf_ready
Number of bytes ready to be read/written from software buffer.
.It Dv feederchain
Channel feeder chain.
.El
.El
.It Dv provider
A string specifying the provider of the PCm audio device.
.El
.Pp
The following ioctls are provided for use:
.Bl -tag -width ".Dv SNDSTIOC_FLUSH_USER_DEVS"
.It Dv SNDSTIOC_REFRESH_DEVS
Drop any previously fetched PCM audio devices list snapshots.
This ioctl takes no arguments.
.It Dv SNDSTIOC_GET_DEVS
Generate and/or return PCM audio devices list snapshots to callers.
This ioctl takes a pointer to
.Fa struct sndstioc_nv_arg
as the first and the only argument.
Callers need to provide a sufficiently large buffer to hold a serialized
nvlist.
If there is no existing PCM audio device list snapshot available in the
internal structure of the opened sndstat.
.Fa fd ,
a new PCM audio device list snapshot will be automatically generated.
Callers have to set
.Fa nbytes
to either 0 or the size of buffer provided.
In case
.Fa nbytes
is 0, the buffer size required to hold a serialized nvlist
stream of current snapshot will be returned in
.Fa nbytes ,
and
.Fa buf
will be ignored.
Otherwise, if the buffer is not sufficiently large,
the ioctl returns success, and
.Fa nbytes
will be set to 0.
If the buffer provided is sufficiently large,
.Fa nbytes
will be set to the size of the serialized nvlist written to the provided buffer.
Once a PCM audio device list snapshot is returned to user-space successfully,
the snapshot stored in the subsystem's internal structure of the given
.Fa fd
will be freed.
.It Dv SNDSTIOC_ADD_USER_DEVS
Add a list of PCM audio devices provided by callers to
.Pa /dev/sndstat
device.
This ioctl takes a pointer to
.Fa struct sndstioc_nv_arg
as the first and the only argument.
Callers have to provide a buffer holding a serialized nvlist.
.Fa nbytes
should be set to the length in bytes of the serialized nvlist.
.Fa buf
should be pointed to a buffer storing the serialized nvlist.
Userspace-backed PCM audio device nodes should be listed inside the serialized
nvlist.
.It Dv SNDSTIOC_FLUSH_USER_DEVS
Flush any PCM audio devices previously added by callers.
This ioctl takes no arguments.
.El
.Sh FILES
.Bl -tag -width ".Pa /dev/sndstat" -compact
.It Pa /dev/sndstat
.El
.Sh EXAMPLES
The following code enumerates all available PCM audio devices:
.Bd -literal -offset indent
#include <sys/types.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/nv.h>
#include <sys/sndstat.h>
#include <sysexits.h>
#include <unistd.h>
int
main()
{
int fd;
struct sndstioc_nv_arg arg;
const nvlist_t * const *di;
size_t i, nitems;
nvlist_t *nvl;
/* Open sndstat node in read-only first */
fd = open("/dev/sndstat", O_RDONLY);
if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL))
err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)");
/* Get the size of snapshot, when nbytes = 0 */
arg.nbytes = 0;
arg.buf = NULL;
if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
/* Get snapshot data */
arg.buf = malloc(arg.nbytes);
if (arg.buf == NULL)
err(EX_OSERR, "malloc");
if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
/* Deserialize the nvlist stream */
nvl = nvlist_unpack(arg.buf, arg.nbytes, 0);
free(arg.buf);
/* Get DSPs array */
di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems);
for (i = 0; i < nitems; i++) {
const char *nameunit, *devnode, *desc;
/*
* Examine each device nvlist item
*/
nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT);
devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE);
desc = nvlist_get_string(di[i], SNDST_DSPS_DESC);
printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n",
nameunit, devnode, desc);
}
nvlist_destroy(nvl);
return (0);
}
.Ed
.Sh SEE ALSO
.Xr sound 4 ,
.Xr nv 9
.Sh HISTORY
The nvlist-based ioctls support for
.Nm
device first appeared in
.Fx 13.0 .
.Sh AUTHORS
This manual page was written by
.An Ka Ho Ng Aq Mt khng@FreeBSD.org .
|