mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
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:
parent
f31504fdc9
commit
aef595b5bf
2 changed files with 17 additions and 18 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -134,39 +134,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);
|
||||
|
||||
|
|
@ -364,6 +361,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*);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue