Re: (re)use and (re)definition of snd_pcm_hw_params->fifo_size for 'jumpy DMA'

Péter Ujfalusi
2026-03-25T13:29:40Z

On 24/03/2026 17:48, Jaroslav Kysela wrote:
> On 3/24/26 11:51, Péter Ujfalusi wrote:
>
>>> But if we agree on other name like 'burst_size' or 'batch_size', I'll be
>>> fine with it, too.
>>
>> I think neither of these are right, unless we substitute them with a
>> variable which tells the size of the FIFO in hardware that is going to
>> be filled.
>> max_hw_ptr_burst_size or max_dma_burst_size or max_burst_size - in
>> frames?
>
> I missed the 100ms + 1ms case (it was a bit hidden in the examples).

Sorry about that, too much sometimes result less ;)

> Looking to this again, I think that the terminology should be more
> abstracted. The DMA word is not appropriate in this contents. Even the
> burst word is not so good. Also, applications do not work with hw_ptr,
> but with the avail / delay values (calculated from the head [hw_ptr] /
> tail [appl_ptr] - playback).
>
> I think that we both mean similar thing, but the question is how to
> define the right API for it.

Yes, I agree.

> Basically, for playback this value should be the "minimal fill"
> recommendation to avoid underruns. So for your examples, it should be
> 101ms or 196ms (but in samples) right ?
>
> If we look to other direction (capture), it may describe the "maximal
> sample block" which will be put to the audio buffer (hw_ptr change).
>
> So, perhaps, the xfer_latency name may be used (value should be in
> samples)? Applications should not go bellow this value.

Looking at the PW code (spa/plugins/alsa/alsa-pcm.c) and I sort of
started to appreciate the 'headroom' term.

I disagree that this is not about DMA or about burst since it is
precisely about that. It can be viewed as 'latency' but the latency is
reported via the delay and the delay fluctuates over time based on how
the DSP FIFO drains and fills.

What we want to tell applications is to be careful as the hw_ptr is not
running in steady pace, but it is jumping, bursting, uses bigger steps.
If we really want to be precise, we would want to expose two numbers:
A: the size of the FIFO will will be filled initially
B: the size of the steps which the hw_ptr will move after the initial
burst. This is also the 'distance' of these steps

So, again the 100ms FIFO:
A=100ms
B=96ms

start: hw_ptr moves to 100ms and will stay there for 96ms
50ms: hw_ptr is still at 100ms
96ms: hw_ptr jumps to 196ms and will stay there for 96ms
...
if you want to predict where the hw_ptr will be at any given time of
Xms hw_ptr: 100 + roundown(X - 100, 96) // if I'm right

A=100ms
B=1ms

start: hw_ptr moves to 100ms and will stay there for 1ms
50ms: hw_ptr is at 150ms
96ms: hw_ptr is at 196ms
...
if you want to predict where the hw_ptr will be at any given time of
Xms hw_ptr: 100 + roundown(X - 100, 1) // if I'm right

The kernel cannot predict how application is planning to manage the
buffer, but if it knows when it will wake up then it can pre-calculate
the amount of data it must provide to avoid xrun.

If B is not provided they can use B=A a rughstimate ;)

On capture side the hw_ptr will jump by B, A have no relevance.

A: hw_buffer_size
B: hw_buffer_refill_step_size

s/hw_buffer/offload ?

PW then probably can use these:
state->start_delay = hw_buffer_size;
state->headroom = hw_buffer_refill_step_size

and on start/xrun it might need to provide
state->start_delay + max(state->start_delay, state->headroom)
or to the distance that it is planning to wake up.

Likely applications can work this out even with A to keep things simple.

--
Péter