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@gmail.com 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