mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	resample: keep fractional part of in_rate when interpolating
When interpolating with rate correction != 1.0, don't floor the resulting input rate to the nearest smallest integer. This allows rate corrections < 1/in_rate to have some effect, and reduces jumps in the response. One of the jumps is inconveniently between rate=1.0 and rate=1.0+eps and will cause rate corrections to oscillate if target rate varies close to 1.0.
This commit is contained in:
		
							parent
							
								
									244d5a1cc1
								
							
						
					
					
						commit
						847982eb0e
					
				
					 2 changed files with 11 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -39,7 +39,7 @@ struct native_data {
 | 
			
		|||
	double rate;
 | 
			
		||||
	uint32_t n_taps;
 | 
			
		||||
	uint32_t n_phases;
 | 
			
		||||
	uint32_t in_rate;
 | 
			
		||||
	struct fixp in_rate;
 | 
			
		||||
	uint32_t out_rate;
 | 
			
		||||
	struct fixp phase;
 | 
			
		||||
	float pm;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,24 +137,25 @@ 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;
 | 
			
		||||
	struct fixp in_rate;
 | 
			
		||||
	uint32_t out_rate;
 | 
			
		||||
 | 
			
		||||
	if (SPA_LIKELY(data->rate == rate))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	data->rate = rate;
 | 
			
		||||
	in_rate = r->i_rate;
 | 
			
		||||
	in_rate = UINT32_TO_FIXP(r->i_rate);
 | 
			
		||||
	out_rate = r->o_rate;
 | 
			
		||||
 | 
			
		||||
	if (rate != 1.0) {
 | 
			
		||||
		in_rate = (uint32_t)(in_rate / rate);
 | 
			
		||||
		in_rate.value = (uint64_t)round(in_rate.value / rate);
 | 
			
		||||
		data->func = data->info->process_inter;
 | 
			
		||||
	}
 | 
			
		||||
	else if (in_rate == out_rate) {
 | 
			
		||||
	else if (in_rate.value == UINT32_TO_FIXP(out_rate).value) {
 | 
			
		||||
		data->func = data->info->process_copy;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		in_rate /= data->gcd;
 | 
			
		||||
		in_rate.value /= data->gcd;
 | 
			
		||||
		out_rate /= data->gcd;
 | 
			
		||||
		data->func = data->info->process_full;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -169,8 +170,8 @@ static void impl_native_update_rate(struct resample *r, double rate)
 | 
			
		|||
	data->in_rate = in_rate;
 | 
			
		||||
	data->out_rate = out_rate;
 | 
			
		||||
 | 
			
		||||
	data->inc = in_rate / out_rate;
 | 
			
		||||
	data->frac = UINT32_TO_FIXP(in_rate % out_rate);
 | 
			
		||||
	data->inc = in_rate.value / UINT32_TO_FIXP(out_rate).value;
 | 
			
		||||
	data->frac.value = in_rate.value % UINT32_TO_FIXP(out_rate).value;
 | 
			
		||||
 | 
			
		||||
	spa_log_trace_fp(r->log, "native %p: rate:%f in:%d out:%d phase:%f inc:%d frac:%f", r,
 | 
			
		||||
			rate, r->i_rate, r->o_rate, FIXP_TO_FLOAT(data->phase),
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +207,7 @@ static uint32_t impl_native_out_len(struct resample *r, uint32_t in_len)
 | 
			
		|||
 | 
			
		||||
	in_len = in_len - SPA_MIN(in_len, data->n_taps - data->hist);
 | 
			
		||||
	out_len = in_len * data->out_rate - FIXP_TO_UINT32(data->phase);
 | 
			
		||||
	out_len = (out_len + data->in_rate - 1) / data->in_rate;
 | 
			
		||||
	out_len = (UINT32_TO_FIXP(out_len).value + data->in_rate.value - 1) / data->in_rate.value;
 | 
			
		||||
 | 
			
		||||
	spa_log_trace_fp(r->log, "native %p: hist:%d %d->%d", r, data->hist, in_len, out_len);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +400,7 @@ int resample_native_init(struct resample *r)
 | 
			
		|||
	r->data = d;
 | 
			
		||||
	d->n_taps = n_taps;
 | 
			
		||||
	d->n_phases = n_phases;
 | 
			
		||||
	d->in_rate = in_rate;
 | 
			
		||||
	d->in_rate = UINT32_TO_FIXP(in_rate);
 | 
			
		||||
	d->out_rate = out_rate;
 | 
			
		||||
	d->gcd = gcd;
 | 
			
		||||
	d->pm = (float)n_phases / r->o_rate / FIXP_SCALE;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue