Re: RFC - Work on FreeBSD's Audio Stack

From: Florian Walpen <dev_at_submerge.ch>
Date: Mon, 25 Dec 2023 14:18:13 UTC
On Sunday, December 17, 2023 7:30:53 PM CET Florian Walpen wrote:
> The latency / OSS buffer fragment / blocksize stuff is one of the bigger
> blunders I know in our audio stack, and one that can be fixed without
> compromising OSS API compatibility too much.
> 
> There's an abstract latency setting through SNDCTL_DSP_POLICY ioctl, the
> hw.snd.latency_profile and hw.snd.latency sysctl. It translates to a certain
> buffer and fragment size, at 48kHz 16bit stereo. Different ones for
> recording and playback. These sizes are then scaled according to the actual
> sample rate and frame size, and rounded to a power of two. Which can be
> already far off from the intended latency per fragment.
> 
> These buffer and fragment sizes are then further processed, limited and
> rounded (power of two) again. They end up as the fragment size of the
> internal buffers. Funny enough, the fragment size is almost meaningless,
> apart from defining the default low water mark. Less funny that it is also
> communicated as blocksize to the driver, to set a certain latency. At this
> point it's a bit of a lottery because the driver has its own rounding
> requirements (e.g. milliseconds), and it depends on whether recording or
> playback blocksize has the final say. Because drivers typically need the
> same blocksize for recording and playback.
> 
> Some of the drivers have dedicated tunables to get predictable blocksizes.
> Yes, that's what hw.usb.uaudio.buffer_ms is for.
> 
> So at least it would be nice to get a consistent latency hint at the driver
> level. The effective fragment size for the front side buffers should be set
> according to what the driver uses, not the other way round.
> Bonus points if we find a way to set the buffer size from an application,
> without the obsessive power-of-two-rounding.

Addendum: From my work on the snd_hdspe(4) driver I can say that the issue of 
inconsistent buffer size / fragment / blocksize is not only a problem for 
developers (application and drivers), but also causes playback stuttering for 
some configurations. AFAICT this is due to vchan feeders not adapting to what 
the driver reports as blocksize.

I also remember that snd_hda(4) playback began to stutter when I tried to 
adjust its buffer size from an application. In hindsight it's plausible that 
this is the same issue. It made me give up completely on doing OSS API buffer 
size adjustments in applications.

Florian