From eb91f097d96084a220d2ae22c6c4f71c2a98e83c Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Thu, 16 Jan 2025 19:40:30 +0200 Subject: [PATCH] audioconvert: resampler: fix off-by-one issues Resampler without prefill was sometime outputting with different delay than with prefill. Adjust initial history by 1 which seems to bring it more in line. The resampler phase also appears to depend on how many samples remain in history which leads to possibly unexpected +-1 variation. Take this into account in reported phase. These changes make the resampler delay tests pass. Both changes are sort of empirical --- I don't fully understand why these would fix things but they seem to be needed to make the delay calculations agree with what the resampler outputs. --- spa/plugins/audioconvert/resample-native.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spa/plugins/audioconvert/resample-native.c b/spa/plugins/audioconvert/resample-native.c index bf8779cd8..85bdc4cf2 100644 --- a/spa/plugins/audioconvert/resample-native.c +++ b/spa/plugins/audioconvert/resample-native.c @@ -305,7 +305,7 @@ static void impl_native_reset (struct resample *r) if (r->options & RESAMPLE_OPTION_PREFILL) d->hist = d->n_taps - 1; else - d->hist = (d->n_taps / 2) - 1; + d->hist = d->n_taps / 2; d->phase = 0; } @@ -322,14 +322,18 @@ static int32_t impl_native_phase_ns(struct resample *r) if (d->func == d->info->process_full) { float pho = -(float)((int32_t)d->phase) / d->out_rate; - if (pho != 0.0f) + /* XXX: this is how it seems to behave, but not clear why */ + if (d->hist >= d->n_taps - 1) pho += 1.0f; + return (int32_t)(pho * SPA_NSEC_PER_SEC / r->i_rate); } else if (d->func == d->info->process_inter) { float pho = -d->phase / d->out_rate; - if (pho != 0.0f) + /* XXX: this is how it seems to behave, but not clear why */ + if (d->hist >= d->n_taps - 1) pho += 1.0f; + return (int32_t)(pho * SPA_NSEC_PER_SEC / r->i_rate); }