Page MenuHomeFreeBSD

audio(8): Initial revision
Needs ReviewPublic

Authored by christos on Aug 5 2024, 11:04 AM.
Tags
None
Referenced Files
F102050162: D46227.diff
Wed, Nov 6, 11:59 PM
Unknown Object (File)
Thu, Oct 17, 2:51 PM
Unknown Object (File)
Wed, Oct 16, 5:31 AM
Unknown Object (File)
Tue, Oct 15, 6:14 AM
Unknown Object (File)
Mon, Oct 14, 6:53 AM
Unknown Object (File)
Sun, Oct 13, 12:33 AM
Unknown Object (File)
Fri, Oct 11, 3:37 PM
Unknown Object (File)
Thu, Oct 10, 2:30 PM
Subscribers

Details

Summary

audio(8) is a new program that lists and modifies audio device
properties, in similar fashion to mixer(8).

It works using a control/variable-driven interface; these controls are
defined in dev_ctls and chan_ctls. Most of them are read-only, but
some of them can also be modified, see which ones have a non-NULL mod
field.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 59157
Build 56044: arc lint + arc unit

Event Timeline

  • The program works with a control/variable-driven interface. These variables are defined in dev_ctls and chan_ctls. Most of them are read-only, but some of them can also be modified (e.g audio rec.vchans=1), see which ones have a non-NULL mod field. The -v option will print all of the device’s channel properties as well. The -o option will print the same things but in a more parser-friendly format, similar to mixer(8)’s -o option.
  • I am open to suggestions regarding the output format/style. For now I followed mixer(8)’s style, but it gets quite cluttered since we print way more things here, especially with the -v option.
  • We could make use of driver-specific sysctls, but we need to hardcode the fields we care about in audio(8), and do this for every driver that provides sysctl tunables. Is this worth the effort?
  • The channel properties are all read-only. Using the OSS API won’t really make much sense here (e.g to modify the sample rate, format, volume, …), as the changes affect only the channels the process has opened. What we would need is a new IOCTL that can set parameters for all channels, but we do not currently have this.
  • I would like to have a VPC interface in the future, but it is not possible right now (see previous bullet above).
  • Is there something we could omit from printing? I am currently printing all info available, so that we can select what we want to keep.
  • There is no reliable way to fetch and handle userland devices’ properties. virtual_oss could could be handled with some minor patches to it, but I cannot do this for every other current (or future) application that will register devices to sndstat(4). For this reason, the output for userland devices might not be complete, and the modification functions will be NOPs.
  • The hardware and software buffers’ sizes are expressed in both bytes and frames.
  • audio $(audio -o) does not work for strings with spaces (e.g name=Dummy Audio Device). I tried adding quotes around strings when printing with -o, but the command still does not work, although writing the string manually in the command line does. Any ideas what the problem is?
  • Do we want to provide a default_unit change control like in mixer(8), or is it redundant?
  • Any objections with the control names? I tried to make them short but not too cryptic.
  • I will update the diff with 1) an -a option similar to mixer(8), 2) a man page and 3) a test program ASAP. I just wanted to get the bulk of the code up for review soon.
christos retitled this revision from WIP: audio(8): Initial revision to [WIP] audio(8): Initial revision.Aug 5 2024, 11:05 AM

I'll take the high level, utilitarian perspective here again - sorry for the déjà vu ;-)

While audio(8) doesn't introduce strong dependencies like the audio(3) library proposed in D45951, we still want some convincing use cases for it. As a utility it would compete with sysctl(8) and mixer(8), as an information tool with /dev/sndstat, and in general with what applications can access through the kernel API.

I'm fully aware that this is WIP. But before I can discuss implementation and design of the user interface here, I need some idea where this is going. Just a secondary interface to sysctl(8) doesn't cut it.

I tried to come up with features I'd find helpful in such a utility:

  • Set the vchan and latency settings as non-root user (having access rights for the pcm device).
  • Apply settings by device name, instead of unit number (which may change).
  • Change all necessary sysctls to switch from shared mode to bitperfect exclusive, in one go.
  • Print a self-explanatory view of the in-kernel channel stack, with mixdown and formats.
  • Show current use of devices and channels, something like top(1) for audio.
  • Info to help troubleshoot underruns and latencies.

Not all of these features are feasible, some are better implemented outside of a utility, and I'm not totally sold on anything yet. Maybe the other reviewers have some ideas? @meka_tilda.center?

  • We could make use of driver-specific sysctls, but we need to hardcode the fields we care about in audio(8), and do this for every driver that provides sysctl tunables. Is this worth the effort?

We'd have to match both driver and specific hardware models, and maintain this in the future. I'd say maybe on a best effort basis, but not as a priority.

  • The channel properties are all read-only. Using the OSS API won’t really make much sense here (e.g to modify the sample rate, format, volume, …), as the changes affect only the channels the process has opened. What we would need is a new IOCTL that can set parameters for all channels, but we do not currently have this.

I don't see anything about virtual channels that makes sense to be manipulated here. Mixdown format of the primary channel we already have, general volume is in mixer.

  • I would like to have a VPC interface in the future, but it is not possible right now (see previous bullet above).

Wouldn't that be the domain of mixer(8)?

  • There is no reliable way to fetch and handle userland devices’ properties. virtual_oss could could be handled with some minor patches to it, but I cannot do this for every other current (or future) application that will register devices to sndstat(4). For this reason, the output for userland devices might not be complete, and the modification functions will be NOPs.

Is there any provider of userland devices apart from virtual_oss?

I also wonder about the name for this utility - ISTM audio(8) is too generic. If it has (will grow to have) features like @dev_submerge.ch mentions maybe audioctl(8)?

I'll take the high level, utilitarian perspective here again - sorry for the déjà vu ;-)

While audio(8) doesn't introduce strong dependencies like the audio(3) library proposed in D45951, we still want some convincing use cases for it. As a utility it would compete with sysctl(8) and mixer(8), as an information tool with /dev/sndstat, and in general with what applications can access through the kernel API.

I'm fully aware that this is WIP. But before I can discuss implementation and design of the user interface here, I need some idea where this is going. Just a secondary interface to sysctl(8) doesn't cut it.

In this case I will be on the disagreeing side however. We currently have at least 4 different ways to manipulate the sound card and/or list properties: 1) cat /dev/sndstat, 2) sndstat(4) nvlist API, 3) sysctl(8), 4) OSS API. In my opinion it is great to have a single tool that concatenates the most useful information of each of these utilities/APIs into a single place, with a unified interface. My question would be, what is a reason for not wanting a simpler/unified tool, and instead keep having all this information and controls scattered? For me even the fact that we won't have to use multiple different programs to make changes (at least the common ones) is already an improvement. I do not think it has to be a do-it-all program in order for it to be valuable.

Also the program will grow and mature with time once we have more feedback and better sound(4) support for certain features, but I insist that even in its current form, it's better than what we have.

I tried to come up with features I'd find helpful in such a utility:

  • Set the vchan and latency settings as non-root user (having access rights for the pcm device).

Good idea. I'll have to look into this, but definitely as a future endeavor.

  • Apply settings by device name, instead of unit number (which may change).

What do you mean by device name? The name assigned to the device by the driver is dependent on the unit (e.g pcm0). And if we used the actual name of the device (e.g "Focusrite Scarlett Solo"), we could end up in a conflict if we happen to have more than one of the same device attached. We currently choose device by passing the /dev/foo file (-f option), which I think is the simplest and most straight-forward way to do it, and also what mixer(8) does, so it's familiar.

  • Change all necessary sysctls to switch from shared mode to bitperfect exclusive, in one go.

You can do it now in a single command: audio play.vchans=0 rec.vchans=0 bitperfect=1.
And if want to open the device in exclusive mode and avoid the conversions (i.e have the same rate and format between VCHANs and the application): audio play.vchanformat=s32le rec.vchanformat=s32le play.vchanrate=48000 rec.vchanrate=48000.

  • Print a self-explanatory view of the in-kernel channel stack, with mixdown and formats.

Can you elaborate on this?

  • Show current use of devices and channels, something like top(1) for audio.

If you use the -v option to print the channel information, you do get the PID and name of the processes using them. You can filter just the PID and process names if you want: audio -v pid proc.

  • Info to help troubleshoot underruns and latencies.

Can you elaborate?

  • I would like to have a VPC interface in the future, but it is not possible right now (see previous bullet above).

Wouldn't that be the domain of mixer(8)?

It would. I wouldn't mind including that feature in mixer(8), but it'd still be nice to have. Something like a mixer which lists the application and its volume (kind of like the Windows mixer). This requires perhaps a new IOCTL that can modify specific channel volumes -- the OSS API currently restricts us to being able to modify only the volume of our process' channel(s).

  • There is no reliable way to fetch and handle userland devices’ properties. virtual_oss could could be handled with some minor patches to it, but I cannot do this for every other current (or future) application that will register devices to sndstat(4). For this reason, the output for userland devices might not be complete, and the modification functions will be NOPs.

Is there any provider of userland devices apart from virtual_oss?

I don't think so, but in any case I think we'd rather be conservative than break something in the future with this, or we'd have to start hard-coding provider-specific parts.

I also wonder about the name for this utility - ISTM audio(8) is too generic. If it has (will grow to have) features like @dev_submerge.ch mentions maybe audioctl(8)?

I also wanted to go with audioctl(8), but I am not sure whether it's a good idea since this might conflict with OpenBSD's audioctl(8). I am open to suggestions regarding the name of the program as long as it's something simple and relatively short.

I'll take the high level, utilitarian perspective here again - sorry for the déjà vu ;-)

While audio(8) doesn't introduce strong dependencies like the audio(3) library proposed in D45951, we still want some convincing use cases for it. As a utility it would compete with sysctl(8) and mixer(8), as an information tool with /dev/sndstat, and in general with what applications can access through the kernel API.

I'm fully aware that this is WIP. But before I can discuss implementation and design of the user interface here, I need some idea where this is going. Just a secondary interface to sysctl(8) doesn't cut it.

In this case I will be on the disagreeing side however. We currently have at least 4 different ways to manipulate the sound card and/or list properties: 1) cat /dev/sndstat, 2) sndstat(4) nvlist API, 3) sysctl(8), 4) OSS API. In my opinion it is great to have a single tool that concatenates the most useful information of each of these utilities/APIs into a single place, with a unified interface. My question would be, what is a reason for not wanting a simpler/unified tool, and instead keep having all this information and controls scattered? For me even the fact that we won't have to use multiple different programs to make changes (at least the common ones) is already an improvement. I do not think it has to be a do-it-all program in order for it to be valuable.

Also the program will grow and mature with time once we have more feedback and better sound(4) support for certain features, but I insist that even in its current form, it's better than what we have.

Appreciated. That's the kind of discussion I'd like to have :-)

My main point is this: In the form this utility is sketched out now, it does collect all the scattered values and settings, but it does not simplify anything. Having the same abstraction level as the underlying sysctl structure, a user gets two redundant ways to change the same settings, which are neither very intuitive nor user-friendly. Given that some settings have to be done in sysctl anyway (boot persistent or device specific), and all existing documentation pointing to sysctl.

I'd recommend to focus on the interaction with the user, on a higher abstraction level where appropriate, making the settings more approachable and intuitive. Think of a moderately savvy user who didn't read the sound(4) man page and doesn't know about vchans.

  • Apply settings by device name, instead of unit number (which may change).

What do you mean by device name? The name assigned to the device by the driver is dependent on the unit (e.g pcm0). And if we used the actual name of the device (e.g "Focusrite Scarlett Solo"), we could end up in a conflict if we happen to have more than one of the same device attached. We currently choose device by passing the /dev/foo file (-f option), which I think is the simplest and most straight-forward way to do it, and also what mixer(8) does, so it's familiar.

Problem is you have to look up the pcm unit number first, and persistent settings are brittle because the numbers may change. But that was just an idea, I think this is better handled by some scheme for reproducible and unique pcm device paths.

  • Change all necessary sysctls to switch from shared mode to bitperfect exclusive, in one go.

You can do it now in a single command: audio play.vchans=0 rec.vchans=0 bitperfect=1.
And if want to open the device in exclusive mode and avoid the conversions (i.e have the same rate and format between VCHANs and the application): audio play.vchanformat=s32le rec.vchanformat=s32le play.vchanrate=48000 rec.vchanrate=48000.

That's what I meant by not simplifying things. You have to know all these knobs, and you can do all that in sysctl(8) too.

  • Print a self-explanatory view of the in-kernel channel stack, with mixdown and formats.

Can you elaborate on this?

Print some simplified info about virtual, primary channels, and the feeder chain - in a way such that the user intuitively grasps what goes where, and what is affected by settings.

  • Show current use of devices and channels, something like top(1) for audio.

If you use the -v option to print the channel information, you do get the PID and name of the processes using them. You can filter just the PID and process names if you want: audio -v pid proc.

Think more of how you use top(1) - show which channels are opened or running, without prior knowledge. Just an idea to help troubleshooting.

  • Info to help troubleshoot underruns and latencies.

Can you elaborate?

Not yet, we'd have to think about how to make that info accessible and useful.

I also wonder about the name for this utility - ISTM audio(8) is too generic. If it has (will grow to have) features like @dev_submerge.ch mentions maybe audioctl(8)?

I also wanted to go with audioctl(8), but I am not sure whether it's a good idea since this might conflict with OpenBSD's audioctl(8). I am open to suggestions regarding the name of the program as long as it's something simple and relatively short.

Well, the audioctl(8) name clash would be only in branding and web search, as the OpenBSD audioctl(8) cannot run on FreeBSD. Thus a different name would be preferable, but not mandatory.

Appreciated. That's the kind of discussion I'd like to have :-)

My main point is this: In the form this utility is sketched out now, it does collect all the scattered values and settings, but it does not simplify anything. Having the same abstraction level as the underlying sysctl structure, a user gets two redundant ways to change the same settings, which are neither very intuitive nor user-friendly. Given that some settings have to be done in sysctl anyway (boot persistent or device specific), and all existing documentation pointing to sysctl.

I'd recommend to focus on the interaction with the user, on a higher abstraction level where appropriate, making the settings more approachable and intuitive. Think of a moderately savvy user who didn't read the sound(4) man page and doesn't know about vchans.

I agree with improving the user-friendliness and making some of the names and functionality less cryptic. It's what I also mentioned in my initial comment. I just put the patch as is as a base to work on. I am working on it, but am of course open to suggestions. :-)

That being said, what interface would you recommend instead of the sysctl-like one? In my opinion audio foo=bar ... is pretty straight-forward and also easy to implement. I do agree that we could "hide" some of the terminology (i.e VCHANs) that a novice user would not know, or care to know about.

  • Apply settings by device name, instead of unit number (which may change).

What do you mean by device name? The name assigned to the device by the driver is dependent on the unit (e.g pcm0). And if we used the actual name of the device (e.g "Focusrite Scarlett Solo"), we could end up in a conflict if we happen to have more than one of the same device attached. We currently choose device by passing the /dev/foo file (-f option), which I think is the simplest and most straight-forward way to do it, and also what mixer(8) does, so it's familiar.

Problem is you have to look up the pcm unit number first, and persistent settings are brittle because the numbers may change. But that was just an idea, I think this is better handled by some scheme for reproducible and unique pcm device paths.

This I guess is a problem with all device drivers that work this way, so for now we cannot do much about it unfortunately. I would like to look into this as a future endeavor however, because we do need a way to have consistent configurations.

  • Change all necessary sysctls to switch from shared mode to bitperfect exclusive, in one go.

You can do it now in a single command: audio play.vchans=0 rec.vchans=0 bitperfect=1.
And if want to open the device in exclusive mode and avoid the conversions (i.e have the same rate and format between VCHANs and the application): audio play.vchanformat=s32le rec.vchanformat=s32le play.vchanrate=48000 rec.vchanrate=48000.

That's what I meant by not simplifying things. You have to know all these knobs, and you can do all that in sysctl(8) too.

One thing we could do is hide *vchanrate and *vchanformat behind a generic play.rate and rec.rate layer, which will call the appropriate sysctl if VCHANs are enabled, or do nothing (for now) if they are disabled, since we cannot handle rate/format changes for primary channels globally yet.

  • Print a self-explanatory view of the in-kernel channel stack, with mixdown and formats.

Can you elaborate on this?

Print some simplified info about virtual, primary channels, and the feeder chain - in a way such that the user intuitively grasps what goes where, and what is affected by settings.

We could provide a more verbose version of the feeder chain through the sndstat(4) nvlist API for sure. I will experiment with a few different output structures that can make this info easily understandable.

  • Show current use of devices and channels, something like top(1) for audio.

If you use the -v option to print the channel information, you do get the PID and name of the processes using them. You can filter just the PID and process names if you want: audio -v pid proc.

Think more of how you use top(1) - show which channels are opened or running, without prior knowledge. Just an idea to help troubleshooting.

This is what this command would print, but I can just as well add an option/control that prints this info in an even more intuitive format, something like:

CHANNEL				MODE	PID	PROCESS		RATE	FORMAT		XRUNS	FEEDCOUNT
pcm0:virtual_play:dsp0.vp0	Play	1234	mpv		48000	s24le:2.0	10	12345
pcm0:virtual_play:dsp0.vp1	Play	2234	mplayer		48000	s32le:2.0	123	123
pcm0:virtual_record:dsp0.vr0	Rec	3234	firefox		48000	s16le:2.0	32	1234
pcm0:virtual_record:dsp0.vr1	Rec	-1	<UNUSED>	48000	s16le:2.0	0	0

Or something more concise to include more information, because this format will end up with too big lines if we want to include most info we can have about a channel. What would be nice is if this could run in a top(1)-like loop, but this would require us to call read_dev() constantly so that variable info like xruns, feedcount etc are updated. If you mean something like this then it could be a useful feature to troubleshoot problems.

I also wonder about the name for this utility - ISTM audio(8) is too generic. If it has (will grow to have) features like @dev_submerge.ch mentions maybe audioctl(8)?

I also wanted to go with audioctl(8), but I am not sure whether it's a good idea since this might conflict with OpenBSD's audioctl(8). I am open to suggestions regarding the name of the program as long as it's something simple and relatively short.

Well, the audioctl(8) name clash would be only in branding and web search, as the OpenBSD audioctl(8) cannot run on FreeBSD. Thus a different name would be preferable, but not mandatory.

I wouldn't really stress about the name honestly. This program is probably going to end up generic enough so a name like "audio" is not really that bad IMHO.

@dev_submerge.ch What do you think about the comment above? The only thing I'd add is, regarding the generic play|rec.rate and play|rec.format controls I proposed, it might be tricky to figure out what rate/format to report when VCHANs are disabled (in which case we can just report vchanrate and vchanformat).

That being said, what interface would you recommend instead of the sysctl-like one? In my opinion audio foo=bar ... is pretty straight-forward and also easy to implement. I do agree that we could "hide" some of the terminology (i.e VCHANs) that a novice user would not know, or care to know about.

It's not about the setting=value approach per se, it's the semantics and granularity of the settings / properties. If we just replicate what sysctl offers, we get the same user-unfriendly interface, and no way to change the implementation details in the future without changing the interface.

  • Change all necessary sysctls to switch from shared mode to bitperfect exclusive, in one go.

You can do it now in a single command: audio play.vchans=0 rec.vchans=0 bitperfect=1.
And if want to open the device in exclusive mode and avoid the conversions (i.e have the same rate and format between VCHANs and the application): audio play.vchanformat=s32le rec.vchanformat=s32le play.vchanrate=48000 rec.vchanrate=48000.

That's what I meant by not simplifying things. You have to know all these knobs, and you can do all that in sysctl(8) too.

One thing we could do is hide *vchanrate and *vchanformat behind a generic play.rate and rec.rate layer, which will call the appropriate sysctl if VCHANs are enabled, or do nothing (for now) if they are disabled, since we cannot handle rate/format changes for primary channels globally yet.

Yes, that's the direction I had in mind.

  • Print a self-explanatory view of the in-kernel channel stack, with mixdown and formats.

Can you elaborate on this?

Print some simplified info about virtual, primary channels, and the feeder chain - in a way such that the user intuitively grasps what goes where, and what is affected by settings.

We could provide a more verbose version of the feeder chain through the sndstat(4) nvlist API for sure. I will experiment with a few different output structures that can make this info easily understandable.

Sounds good, I think there's definitely value in making the vchan / feeder chain structure visible.

  • Show current use of devices and channels, something like top(1) for audio.

If you use the -v option to print the channel information, you do get the PID and name of the processes using them. You can filter just the PID and process names if you want: audio -v pid proc.

Think more of how you use top(1) - show which channels are opened or running, without prior knowledge. Just an idea to help troubleshooting.

This is what this command would print, but I can just as well add an option/control that prints this info in an even more intuitive format, something like:

CHANNEL				MODE	PID	PROCESS		RATE	FORMAT		XRUNS	FEEDCOUNT
pcm0:virtual_play:dsp0.vp0	Play	1234	mpv		48000	s24le:2.0	10	12345
pcm0:virtual_play:dsp0.vp1	Play	2234	mplayer		48000	s32le:2.0	123	123
pcm0:virtual_record:dsp0.vr0	Rec	3234	firefox		48000	s16le:2.0	32	1234
pcm0:virtual_record:dsp0.vr1	Rec	-1	<UNUSED>	48000	s16le:2.0	0	0

At the moment it prints all channels of the current default device. It would help to print just the ones in use, and show the open / running state. Maybe as a summary for the current default device when no extra flags are given, or a separate flag to show the open / running channels of all devices?

Or something more concise to include more information, because this format will end up with too big lines if we want to include most info we can have about a channel. What would be nice is if this could run in a top(1)-like loop, but this would require us to call read_dev() constantly so that variable info like xruns, feedcount etc are updated. If you mean something like this then it could be a useful feature to troubleshoot problems.

Something like the -w or interval parameter of iostat(8) / zpool-iostat(8)?

@dev_submerge.ch What do you think about the comment above? The only thing I'd add is, regarding the generic play|rec.rate and play|rec.format controls I proposed, it might be tricky to figure out what rate/format to report when VCHANs are disabled (in which case we can just report vchanrate and vchanformat).

Is there a vchanrate and vchanformat with vchans disabled? Because in sysctl(8) they just disappear. IIRC cat /dev/sndstat reports these parameters for the primary channel, so they should be accessible somehow. From a user's perspective there's actually two interesting infos to know, the mixdown format and rate, and the hardware format and rate.

@dev_submerge.ch What do you think about the comment above? The only thing I'd add is, regarding the generic play|rec.rate and play|rec.format controls I proposed, it might be tricky to figure out what rate/format to report when VCHANs are disabled (in which case we can just report vchanrate and vchanformat).

Is there a vchanrate and vchanformat with vchans disabled? Because in sysctl(8) they just disappear. IIRC cat /dev/sndstat reports these parameters for the primary channel, so they should be accessible somehow. From a user's perspective there's actually two interesting infos to know, the mixdown format and rate, and the hardware format and rate.

The setting does not exist but we can still fetch the values of vchanrate and vchanformat from the nvlist even with VCHANs disabled. What we can do is report these rates and formats in play|rec.rate|format. Essentially rename "vchanrate" and "vchanformat" to just "rate" and "format". The problem with this though is that, if VCHANs are disabled, we cannot modify these values (since the sysctls now disappear), so if the primary channels' rate/formats change, we will still report vchanrate and vchanformat. If we have 1 primary playback and 1 primary recording channel, then it's easy, just report the rate/format of these channels, but if we have multiple primary channels in each direction, with different rates/formats, then what exactly are we supposed to report?

Or something more concise to include more information, because this format will end up with too big lines if we want to include most info we can have about a channel. What would be nice is if this could run in a top(1)-like loop, but this would require us to call read_dev() constantly so that variable info like xruns, feedcount etc are updated. If you mean something like this then it could be a useful feature to troubleshoot problems.

Something like the -w or interval parameter of iostat(8) / zpool-iostat(8)?

I am thinking either this, or a curses top(1)-like interface. The former is easier for use inside script, but the latter more user friendly.

@dev_submerge.ch What do you think about the comment above? The only thing I'd add is, regarding the generic play|rec.rate and play|rec.format controls I proposed, it might be tricky to figure out what rate/format to report when VCHANs are disabled (in which case we can just report vchanrate and vchanformat).

Is there a vchanrate and vchanformat with vchans disabled? Because in sysctl(8) they just disappear. IIRC cat /dev/sndstat reports these parameters for the primary channel, so they should be accessible somehow. From a user's perspective there's actually two interesting infos to know, the mixdown format and rate, and the hardware format and rate.

The setting does not exist but we can still fetch the values of vchanrate and vchanformat from the nvlist even with VCHANs disabled. What we can do is report these rates and formats in play|rec.rate|format. Essentially rename "vchanrate" and "vchanformat" to just "rate" and "format". The problem with this though is that, if VCHANs are disabled, we cannot modify these values (since the sysctls now disappear), so if the primary channels' rate/formats change, we will still report vchanrate and vchanformat.

Why not omit them when there's no VCHANs? I think we just have to structure the audio(8) output in a way that makes it clear what is concerned. We have hardware properties, primary channel properties, VCHAN mixdown properties, and virtual channel properties. On top there are also some global settings. We can still show the hardware rate / format, but we don't have to show mixdown or virtual channel properties when VCHANs are disabled, nor do we have to show different formats when bitperfect is set. Part of the simplification is to hide what is not relevant in a situation.

Another idea would be to combine play / rec settings on a pcm level when possible, most audio hardware does not handle different formats / rate for playback / recording.

If we have 1 primary playback and 1 primary recording channel, then it's easy, just report the rate/format of these channels, but if we have multiple primary channels in each direction, with different rates/formats, then what exactly are we supposed to report?

Never encountered multiple primary channels. Under what circumstances / hardware does that happen?

Something like the -w or interval parameter of iostat(8) / zpool-iostat(8)?

I am thinking either this, or a curses top(1)-like interface. The former is easier for use inside script, but the latter more user friendly.

I would just start with a simple one-time info header when running audio(8) by default. We can improve on that later.

christos retitled this revision from [WIP] audio(8): Initial revision to audio(8): Initial revision.Aug 23 2024, 1:59 PM
  • Introduce play|rec.autoconv and realtime controls.
    • Maybe the names could be improved
    • See XXXs in mod functions
    • In mod_realtime() the values are hard-coded to the defaults for when realtime=0, but I am not sure if that’s right.
  • play|rec.rate and play|rec.format: Report vchanrate/format but made it read-only when VCHANs are disabled.
  • Is OSS caps useful info?
  • Future goals:
    • Implement iostat -w <n>-like option as a future goal. I would like to think some more about a concise, yet useful/user-friendly output format, consider how many properties each channel has.
    • Think about Florian's comment: “We can still show the hardware rate / format, but we don't have to show mixdown or virtual channel properties when VCHANs are disabled, nor do we have to show different formats when bitperfect is set. Part of the simplification is to hide what is not relevant in a situation.”.
    • Improve the -v option in the future.
    • Write a test script