resample: avoid calculating GCD in rate updates

We don't actually need to calculate the GCD for each resampler rate
update. The GCD is only used to scale the in/out rates when using the
full resampler and this we can cache and reuse when we did the setup.

The interpolating resampler can work perfectly fine with a GCD of 1 and
so we can just assume that.
This commit is contained in:
Wim Taymans 2025-07-23 12:23:20 +02:00
parent fcc49ad517
commit d2a9141913
2 changed files with 17 additions and 18 deletions

View file

@ -34,6 +34,7 @@ struct native_data {
uint32_t frac;
uint32_t filter_stride;
uint32_t filter_stride_os;
uint32_t gcd;
uint32_t hist;
float **history;
resample_func_t func;

View file

@ -137,39 +137,36 @@ static inline uint32_t calc_gcd(uint32_t a, uint32_t b)
static void impl_native_update_rate(struct resample *r, double rate)
{
struct native_data *data = r->data;
uint32_t in_rate, out_rate, gcd, old_out_rate;
float phase;
uint32_t in_rate, out_rate;
if (SPA_LIKELY(data->rate == rate))
return;
old_out_rate = data->out_rate;
in_rate = (uint32_t)(r->i_rate / rate);
out_rate = r->o_rate;
phase = data->phase;
gcd = calc_gcd(in_rate, out_rate);
in_rate /= gcd;
out_rate /= gcd;
data->rate = rate;
data->phase = phase * out_rate / (float)old_out_rate;
data->in_rate = in_rate;
data->out_rate = out_rate;
data->inc = data->in_rate / data->out_rate;
data->frac = data->in_rate % data->out_rate;
in_rate = r->i_rate;
out_rate = r->o_rate;
if (rate != 1.0) {
in_rate = (uint32_t)(in_rate / rate);
data->func = data->info->process_inter;
}
else if (data->in_rate == data->out_rate) {
else if (in_rate == out_rate) {
data->func = data->info->process_copy;
}
else {
in_rate /= data->gcd;
out_rate /= data->gcd;
data->func = data->info->process_full;
}
data->in_rate = in_rate;
if (data->out_rate != out_rate) {
data->phase = data->phase * out_rate / (float)data->out_rate;
data->out_rate = out_rate;
}
data->inc = data->in_rate / data->out_rate;
data->frac = data->in_rate % data->out_rate;
spa_log_trace_fp(r->log, "native %p: rate:%f in:%d out:%d gcd:%d phase:%f inc:%d frac:%d", r,
rate, r->i_rate, r->o_rate, gcd, data->phase, data->inc, data->frac);
@ -390,6 +387,7 @@ int resample_native_init(struct resample *r)
d->n_phases = n_phases;
d->in_rate = in_rate;
d->out_rate = out_rate;
d->gcd = gcd;
d->filter = SPA_PTROFF_ALIGN(d, sizeof(struct native_data), 64, float);
d->hist_mem = SPA_PTROFF_ALIGN(d->filter, filter_size, 64, float);
d->history = SPA_PTROFF(d->hist_mem, history_size, float*);