Page MenuHomeFreeBSD

D45501.diff
No OneTemporary

D45501.diff

diff --git a/share/man/man4/sndstat.4 b/share/man/man4/sndstat.4
--- a/share/man/man4/sndstat.4
+++ b/share/man/man4/sndstat.4
@@ -29,7 +29,7 @@
.\"
.\" Note: The date here should be updated whenever a non-trivial
.\" change is made to the manual page.
-.Dd April 15, 2021
+.Dd June 5, 2024
.Dt SNDSTAT 4
.Os
.Sh NAME
@@ -60,25 +60,55 @@
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 (1) (0x1)
- rchan (NUMBER): 0 (0) (0x0)
- info_play (NVLIST):
- min_rate (NUMBER): 48000 (48000) (0xbb80)
- max_rate (NUMBER): 48000 (48000) (0xbb80)
- formats (NUMBER): 16 (16) (0x10)
- min_chn (NUMBER): 2 (2) (0x2)
- max_chn (NUMBER): 2 (2) (0x2)
- provider_info (NVLIST):
- unit (NUMBER): 0 (0) (0x0)
- bitperfect (BOOL): FALSE
- pvchan (NUMBER): 1 (1) (0x1)
- rvchan (NUMBER): 0 (0) (0x0)
- provider (STRING): [sound(4)]
- ,
+ 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
+ bitperfect (BOOL): FALSE
+ pvchan (NUMBER): 1
+ rvchan (NUMBER): 0
+ channel_info (NVLIST_ARRAY): 1
+ name (STRING): pcm0:virtual_play:dsp0.vp0
+ parentchan (STRING): pcm0:play:dsp0.p0
+ unit (NUMBER): 1
+ 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_size (NUMBER): 0
+ hwbuf_blksz (NUMBER): 0
+ hwbuf_blkcnt (NUMBER): 0
+ hwbuf_free (NUMBER): 0
+ hwbuf_ready (NUMBER): 0
+ swbuf_fmt (NUMBER): 0x201000
+ 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
@@ -133,6 +163,76 @@
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 bitperfect
+Whether the sound card has bit-perfect mode enabled.
+.It Dv pvchan
+Number of playback virtual channels.
+.It Dv rvchan
+Number of recording virtual channels.
+.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 parenchan
+Parent channel name (e.g., in the case of virtual channels).
+.It Dv unit
+Channel unit.
+.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_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_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
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -392,9 +392,12 @@
static int
sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip)
{
+ struct pcm_channel *c;
+ struct pcm_feeder *f;
+ struct sbuf sb;
uint32_t maxrate, minrate, fmts, minchn, maxchn;
- nvlist_t *di = NULL, *sound4di = NULL, *diinfo = NULL;
- int err;
+ nvlist_t *di = NULL, *sound4di = NULL, *diinfo = NULL, *cdi = NULL;
+ int err, nchan;
di = nvlist_create(0);
if (di == NULL) {
@@ -451,8 +454,116 @@
sound4di, SNDST_DSPS_SOUND4_BITPERFECT, d->flags & SD_F_BITPERFECT);
nvlist_add_number(sound4di, SNDST_DSPS_SOUND4_PVCHAN, d->pvchancount);
nvlist_add_number(sound4di, SNDST_DSPS_SOUND4_RVCHAN, d->rvchancount);
+
+ nchan = 0;
+ CHN_FOREACH(c, d, channels.pcm) {
+ sbuf_new(&sb, NULL, 4096, SBUF_AUTOEXTEND);
+ cdi = nvlist_create(0);
+ if (cdi == NULL) {
+ sbuf_delete(&sb);
+ PCM_RELEASE_QUICK(d);
+ err = ENOMEM;
+ goto done;
+ }
+
+ nvlist_add_string(cdi, SNDST_DSPS_SOUND4_CHAN_NAME, c->name);
+ nvlist_add_string(cdi, SNDST_DSPS_SOUND4_CHAN_PARENTCHAN,
+ c->parentchannel != NULL ? c->parentchannel->name : "");
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_UNIT, nchan++);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_LATENCY,
+ c->latency);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_RATE, c->speed);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_FORMAT,
+ c->format);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_PID, c->pid);
+ nvlist_add_string(cdi, SNDST_DSPS_SOUND4_CHAN_COMM, c->comm);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_INTR,
+ c->interrupts);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_FEEDCNT,
+ c->feedcount);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_XRUNS, c->xruns);
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_LEFTVOL,
+ CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FL));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_RIGHTVOL,
+ CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FR));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_FORMAT,
+ sndbuf_getfmt(c->bufhard));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_SIZE,
+ sndbuf_getsize(c->bufhard));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKSZ,
+ sndbuf_getblksz(c->bufhard));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKCNT,
+ sndbuf_getblkcnt(c->bufhard));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_FREE,
+ sndbuf_getfree(c->bufhard));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_READY,
+ sndbuf_getready(c->bufhard));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_FORMAT,
+ sndbuf_getfmt(c->bufsoft));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_SIZE,
+ sndbuf_getsize(c->bufsoft));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKSZ,
+ sndbuf_getblksz(c->bufsoft));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKCNT,
+ sndbuf_getblkcnt(c->bufsoft));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_FREE,
+ sndbuf_getfree(c->bufsoft));
+ nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_READY,
+ sndbuf_getready(c->bufsoft));
+
+ sbuf_printf(&sb, "[%s",
+ (c->direction == PCMDIR_REC) ? "hardware" : "userland");
+ sbuf_printf(&sb, " -> ");
+ f = c->feeder;
+ while (f->source != NULL)
+ f = f->source;
+ while (f != NULL) {
+ sbuf_printf(&sb, "%s", f->class->name);
+ if (f->desc->type == FEEDER_FORMAT) {
+ sbuf_printf(&sb, "(0x%08x -> 0x%08x)",
+ f->desc->in, f->desc->out);
+ } else if (f->desc->type == FEEDER_MATRIX) {
+ sbuf_printf(&sb, "(%d.%d -> %d.%d)",
+ AFMT_CHANNEL(f->desc->in) -
+ AFMT_EXTCHANNEL(f->desc->in),
+ AFMT_EXTCHANNEL(f->desc->in),
+ AFMT_CHANNEL(f->desc->out) -
+ AFMT_EXTCHANNEL(f->desc->out),
+ AFMT_EXTCHANNEL(f->desc->out));
+ } else if (f->desc->type == FEEDER_RATE) {
+ sbuf_printf(&sb,
+ "(0x%08x q:%d %d -> %d)",
+ f->desc->out,
+ FEEDER_GET(f, FEEDRATE_QUALITY),
+ FEEDER_GET(f, FEEDRATE_SRC),
+ FEEDER_GET(f, FEEDRATE_DST));
+ } else {
+ sbuf_printf(&sb, "(0x%08x)",
+ f->desc->out);
+ }
+ sbuf_printf(&sb, " -> ");
+ f = f->parent;
+ }
+ sbuf_printf(&sb, "%s]",
+ (c->direction == PCMDIR_REC) ? "userland" : "hardware");
+
+ sbuf_finish(&sb);
+ nvlist_add_string(cdi, SNDST_DSPS_SOUND4_CHAN_FEEDERCHAIN,
+ sbuf_data(&sb));
+ sbuf_delete(&sb);
+
+ nvlist_append_nvlist_array(sound4di,
+ SNDST_DSPS_SOUND4_CHAN_INFO, cdi);
+ nvlist_destroy(cdi);
+ err = nvlist_error(sound4di);
+ if (err) {
+ PCM_RELEASE_QUICK(d);
+ goto done;
+ }
+ }
nvlist_move_nvlist(di, SNDST_DSPS_PROVIDER_INFO, sound4di);
sound4di = NULL;
+
PCM_RELEASE_QUICK(d);
nvlist_add_string(di, SNDST_DSPS_PROVIDER, SNDST_DSPS_SOUND4_PROVIDER);
diff --git a/sys/sys/sndstat.h b/sys/sys/sndstat.h
--- a/sys/sys/sndstat.h
+++ b/sys/sys/sndstat.h
@@ -68,11 +68,38 @@
/*
* sound(4)-specific name/value pair names
*/
-#define SNDST_DSPS_SOUND4_PROVIDER "sound(4)"
-#define SNDST_DSPS_SOUND4_UNIT "unit"
-#define SNDST_DSPS_SOUND4_BITPERFECT "bitperfect"
-#define SNDST_DSPS_SOUND4_PVCHAN "pvchan"
-#define SNDST_DSPS_SOUND4_RVCHAN "rvchan"
+#define SNDST_DSPS_SOUND4_PROVIDER "sound(4)"
+#define SNDST_DSPS_SOUND4_UNIT "unit"
+#define SNDST_DSPS_SOUND4_BITPERFECT "bitperfect"
+#define SNDST_DSPS_SOUND4_PVCHAN "pvchan"
+#define SNDST_DSPS_SOUND4_RVCHAN "rvchan"
+#define SNDST_DSPS_SOUND4_CHAN_INFO "channel_info"
+#define SNDST_DSPS_SOUND4_CHAN_NAME "name"
+#define SNDST_DSPS_SOUND4_CHAN_PARENTCHAN "parentchan"
+#define SNDST_DSPS_SOUND4_CHAN_UNIT "unit"
+#define SNDST_DSPS_SOUND4_CHAN_LATENCY "latency"
+#define SNDST_DSPS_SOUND4_CHAN_RATE "rate"
+#define SNDST_DSPS_SOUND4_CHAN_FORMAT "format"
+#define SNDST_DSPS_SOUND4_CHAN_PID "pid"
+#define SNDST_DSPS_SOUND4_CHAN_COMM "comm"
+#define SNDST_DSPS_SOUND4_CHAN_INTR "interrupts"
+#define SNDST_DSPS_SOUND4_CHAN_FEEDCNT "feedcount"
+#define SNDST_DSPS_SOUND4_CHAN_XRUNS "xruns"
+#define SNDST_DSPS_SOUND4_CHAN_LEFTVOL "left_volume"
+#define SNDST_DSPS_SOUND4_CHAN_RIGHTVOL "right_volume"
+#define SNDST_DSPS_SOUND4_CHAN_HWBUF_FORMAT "hwbuf_format"
+#define SNDST_DSPS_SOUND4_CHAN_HWBUF_SIZE "hwbuf_size"
+#define SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKSZ "hwbuf_blksz"
+#define SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKCNT "hwbuf_blkcnt"
+#define SNDST_DSPS_SOUND4_CHAN_HWBUF_FREE "hwbuf_free"
+#define SNDST_DSPS_SOUND4_CHAN_HWBUF_READY "hwbuf_ready"
+#define SNDST_DSPS_SOUND4_CHAN_SWBUF_FORMAT "swbuf_format"
+#define SNDST_DSPS_SOUND4_CHAN_SWBUF_SIZE "swbuf_size"
+#define SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKSZ "swbuf_blksz"
+#define SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKCNT "swbuf_blkcnt"
+#define SNDST_DSPS_SOUND4_CHAN_SWBUF_FREE "swbuf_free"
+#define SNDST_DSPS_SOUND4_CHAN_SWBUF_READY "swbuf_ready"
+#define SNDST_DSPS_SOUND4_CHAN_FEEDERCHAIN "feederchain"
/*
* Maximum user-specified nvlist buffer size

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 14, 11:48 AM (18 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15793848
Default Alt Text
D45501.diff (11 KB)

Event Timeline