mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05: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
							
								
									4a22b53b74
								
							
						
					
					
						commit
						f04e8164a6
					
				
					 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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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*);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue