On 05. 01. 23 16:35, Alan Young wrote:
Wrap the hw_ptr using the total position of the slave hw_ptr, including boundary wraps. Otherwise, small errors can creep in due to residuals (when boundary is not a multiple of period size) and which can accumulate. Signed-off-by: Alan Young <consult.awy@xxxxxxxxx> Fixes: 7570e5d7 ("pcm: rate: fix the hw_ptr update until the boundary available") --- src/pcm/pcm_rate.c | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index c8076859..a29fc5a9 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c
...
+ if (rate->slave_hw_ptr_wrap) { + /* + * Restrict explicit 64-bit calculations to case where rate->slave_hw_ptr_wrap + * is non-zero, which will only happen in 32-bit environments. + */ + u_int64_t wrapped_slave_hw_ptr = slave_hw_ptr + rate->slave_hw_ptr_wrap; + new_hw_ptr = ((wrapped_slave_hw_ptr / rate->gen.slave->period_size) * pcm->period_size) % pcm->boundary; + slave_residual = wrapped_slave_hw_ptr % rate->gen.slave->period_size;
I don't think that this calculation is correct. If the boundary differs by more than buffer_size, the new_hw_ptr will be cropped (downsampling).
It will be probably much better to track only pointer diffs and let hw/appl ptrs updating independently like we do in other plugins.
Jaroslav -- Jaroslav Kysela <perex@xxxxxxxx> Linux Sound Maintainer; ALSA Project; Red Hat, Inc.