mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	resample: fix start position of new samples
When we finished processing the history it might be possible that we need to skip some samples from the input. Implement this by adding a start offset for the samples in the buffer.
This commit is contained in:
		
							parent
							
								
									0a26c478f7
								
							
						
					
					
						commit
						761119f640
					
				
					 2 changed files with 19 additions and 17 deletions
				
			
		| 
						 | 
					@ -29,8 +29,8 @@
 | 
				
			||||||
#include "resample.h"
 | 
					#include "resample.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*resample_func_t)(struct resample *r,
 | 
					typedef void (*resample_func_t)(struct resample *r,
 | 
				
			||||||
        const void * SPA_RESTRICT src[], uint32_t *in_len,
 | 
					        const void * SPA_RESTRICT src[], uint32_t ioffs, uint32_t *in_len,
 | 
				
			||||||
        void * SPA_RESTRICT dst[], uint32_t offs, uint32_t *out_len);
 | 
					        void * SPA_RESTRICT dst[], uint32_t ooffs, uint32_t *out_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct native_data {
 | 
					struct native_data {
 | 
				
			||||||
	double rate;
 | 
						double rate;
 | 
				
			||||||
| 
						 | 
					@ -52,8 +52,8 @@ struct native_data {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEFINE_RESAMPLER(type,arch)						\
 | 
					#define DEFINE_RESAMPLER(type,arch)						\
 | 
				
			||||||
void do_resample_##type##_##arch(struct resample *r,				\
 | 
					void do_resample_##type##_##arch(struct resample *r,				\
 | 
				
			||||||
	const void * SPA_RESTRICT src[], uint32_t *in_len,			\
 | 
						const void * SPA_RESTRICT src[], uint32_t ioffs, uint32_t *in_len,	\
 | 
				
			||||||
	void * SPA_RESTRICT dst[], uint32_t offs, uint32_t *out_len)
 | 
						void * SPA_RESTRICT dst[], uint32_t ooffs, uint32_t *out_len)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAKE_RESAMPLER_COPY(arch)						\
 | 
					#define MAKE_RESAMPLER_COPY(arch)						\
 | 
				
			||||||
DEFINE_RESAMPLER(copy,arch)							\
 | 
					DEFINE_RESAMPLER(copy,arch)							\
 | 
				
			||||||
| 
						 | 
					@ -65,21 +65,21 @@ DEFINE_RESAMPLER(copy,arch)							\
 | 
				
			||||||
	if (r->channels == 0)							\
 | 
						if (r->channels == 0)							\
 | 
				
			||||||
		return;								\
 | 
							return;								\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
	index = 0;								\
 | 
						index = ioffs;								\
 | 
				
			||||||
	if (offs < olen && index + n_taps <= ilen) {				\
 | 
						if (ooffs < olen && index + n_taps <= ilen) {				\
 | 
				
			||||||
		uint32_t to_copy = SPA_MIN(olen - offs,				\
 | 
							uint32_t to_copy = SPA_MIN(olen - ooffs,			\
 | 
				
			||||||
				ilen - (index + n_taps) + 1);			\
 | 
									ilen - (index + n_taps) + 1);			\
 | 
				
			||||||
		for (c = 0; c < r->channels; c++) {				\
 | 
							for (c = 0; c < r->channels; c++) {				\
 | 
				
			||||||
			const float *s = src[c];				\
 | 
								const float *s = src[c];				\
 | 
				
			||||||
			float *d = dst[c];					\
 | 
								float *d = dst[c];					\
 | 
				
			||||||
			spa_memcpy(&d[offs], &s[index + n_taps2],		\
 | 
								spa_memcpy(&d[ooffs], &s[index + n_taps2],		\
 | 
				
			||||||
					to_copy * sizeof(float));		\
 | 
										to_copy * sizeof(float));		\
 | 
				
			||||||
		}								\
 | 
							}								\
 | 
				
			||||||
		index += to_copy;						\
 | 
							index += to_copy;						\
 | 
				
			||||||
		offs += to_copy;						\
 | 
							ooffs += to_copy;						\
 | 
				
			||||||
	}									\
 | 
						}									\
 | 
				
			||||||
	*in_len = index;							\
 | 
						*in_len = index;							\
 | 
				
			||||||
	*out_len = offs;							\
 | 
						*out_len = ooffs;							\
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAKE_RESAMPLER_FULL(arch)						\
 | 
					#define MAKE_RESAMPLER_FULL(arch)						\
 | 
				
			||||||
| 
						 | 
					@ -90,6 +90,7 @@ DEFINE_RESAMPLER(full,arch)							\
 | 
				
			||||||
	uint32_t index, phase, n_phases = data->out_rate;			\
 | 
						uint32_t index, phase, n_phases = data->out_rate;			\
 | 
				
			||||||
	uint32_t c, o, olen = *out_len, ilen = *in_len;				\
 | 
						uint32_t c, o, olen = *out_len, ilen = *in_len;				\
 | 
				
			||||||
	uint32_t inc = data->inc, frac = data->frac;				\
 | 
						uint32_t inc = data->inc, frac = data->frac;				\
 | 
				
			||||||
 | 
						static int cnt = 0;				\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
	if (r->channels == 0)							\
 | 
						if (r->channels == 0)							\
 | 
				
			||||||
		return;								\
 | 
							return;								\
 | 
				
			||||||
| 
						 | 
					@ -98,10 +99,10 @@ DEFINE_RESAMPLER(full,arch)							\
 | 
				
			||||||
		const float *s = src[c];					\
 | 
							const float *s = src[c];					\
 | 
				
			||||||
		float *d = dst[c];						\
 | 
							float *d = dst[c];						\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
		index = 0;							\
 | 
							index = ioffs;							\
 | 
				
			||||||
		phase = data->phase;						\
 | 
							phase = data->phase;						\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
		for (o = offs; o < olen && index + n_taps <= ilen; o++) {	\
 | 
							for (o = ooffs; o < olen && index + n_taps <= ilen; o++) {	\
 | 
				
			||||||
			const float *ip, *taps;					\
 | 
								const float *ip, *taps;					\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
			ip = &s[index];						\
 | 
								ip = &s[index];						\
 | 
				
			||||||
| 
						 | 
					@ -137,10 +138,10 @@ DEFINE_RESAMPLER(inter,arch)							\
 | 
				
			||||||
		const float *s = src[c];					\
 | 
							const float *s = src[c];					\
 | 
				
			||||||
		float *d = dst[c];						\
 | 
							float *d = dst[c];						\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
		index = 0;							\
 | 
							index = ioffs;							\
 | 
				
			||||||
		phase = data->phase;						\
 | 
							phase = data->phase;						\
 | 
				
			||||||
										\
 | 
															\
 | 
				
			||||||
		for (o = offs; o < olen && index + n_taps <= ilen; o++) {	\
 | 
							for (o = ooffs; o < olen && index + n_taps <= ilen; o++) {	\
 | 
				
			||||||
			const float *ip, *t0, *t1;				\
 | 
								const float *ip, *t0, *t1;				\
 | 
				
			||||||
			float ph, x;						\
 | 
								float ph, x;						\
 | 
				
			||||||
			uint32_t offset;					\
 | 
								uint32_t offset;					\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,7 +184,7 @@ static void impl_native_process(struct resample *r,
 | 
				
			||||||
		 * and we try to process it */
 | 
							 * and we try to process it */
 | 
				
			||||||
		in = hist + refill;
 | 
							in = hist + refill;
 | 
				
			||||||
		out = *out_len;
 | 
							out = *out_len;
 | 
				
			||||||
		data->func(r, (const void**)history, &in, dst, 0, &out);
 | 
							data->func(r, (const void**)history, 0, &in, dst, 0, &out);
 | 
				
			||||||
		spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d hist:%d",
 | 
							spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d hist:%d",
 | 
				
			||||||
				r, hist + refill, in, *out_len, out, hist);
 | 
									r, hist + refill, in, *out_len, out, hist);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -192,10 +192,11 @@ static void impl_native_process(struct resample *r,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (in >= hist) {
 | 
						if (in >= hist) {
 | 
				
			||||||
 | 
							int skip = in - hist;
 | 
				
			||||||
		/* we are past the history and can now work on the new
 | 
							/* we are past the history and can now work on the new
 | 
				
			||||||
		 * input data */
 | 
							 * input data */
 | 
				
			||||||
		in = *in_len;
 | 
							in = *in_len - skip;
 | 
				
			||||||
		data->func(r, src, &in, dst, out, out_len);
 | 
							data->func(r, src, skip, &in, dst, out, out_len);
 | 
				
			||||||
		spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d",
 | 
							spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d",
 | 
				
			||||||
				r, *in_len, in, *out_len, out);
 | 
									r, *in_len, in, *out_len, out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue