mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	audioconvert: add dither noise setting in dither struct
Move the noise setting in the dither struct so that it can be handled separately. Setup dither separately. Set used cpu_flags in structures after setup.
This commit is contained in:
		
							parent
							
								
									b7e26002be
								
							
						
					
					
						commit
						b5e0151cc0
					
				
					 5 changed files with 33 additions and 20 deletions
				
			
		| 
						 | 
					@ -93,7 +93,6 @@ struct props {
 | 
				
			||||||
	unsigned int resample_quality;
 | 
						unsigned int resample_quality;
 | 
				
			||||||
	unsigned int resample_disabled:1;
 | 
						unsigned int resample_disabled:1;
 | 
				
			||||||
	double rate;
 | 
						double rate;
 | 
				
			||||||
	uint32_t dither_noise;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void props_reset(struct props *props)
 | 
					static void props_reset(struct props *props)
 | 
				
			||||||
| 
						 | 
					@ -110,7 +109,6 @@ static void props_reset(struct props *props)
 | 
				
			||||||
	props->rate = 1.0;
 | 
						props->rate = 1.0;
 | 
				
			||||||
	props->resample_quality = RESAMPLE_DEFAULT_QUALITY;
 | 
						props->resample_quality = RESAMPLE_DEFAULT_QUALITY;
 | 
				
			||||||
	props->resample_disabled = false;
 | 
						props->resample_disabled = false;
 | 
				
			||||||
	props->dither_noise = 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct buffer {
 | 
					struct buffer {
 | 
				
			||||||
| 
						 | 
					@ -614,7 +612,7 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
				SPA_TYPE_OBJECT_PropInfo, id,
 | 
									SPA_TYPE_OBJECT_PropInfo, id,
 | 
				
			||||||
				SPA_PROP_INFO_name, SPA_POD_String("dither.noise"),
 | 
									SPA_PROP_INFO_name, SPA_POD_String("dither.noise"),
 | 
				
			||||||
				SPA_PROP_INFO_description, SPA_POD_String("Add dithering noise"),
 | 
									SPA_PROP_INFO_description, SPA_POD_String("Add dithering noise"),
 | 
				
			||||||
				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->dither_noise, 0, 16),
 | 
									SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(this->dither.noise, 0, 16),
 | 
				
			||||||
				SPA_PROP_INFO_params, SPA_POD_Bool(true));
 | 
									SPA_PROP_INFO_params, SPA_POD_Bool(true));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
| 
						 | 
					@ -684,7 +682,7 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
			spa_pod_builder_string(&b, "resample.disable");
 | 
								spa_pod_builder_string(&b, "resample.disable");
 | 
				
			||||||
			spa_pod_builder_bool(&b, p->resample_disabled);
 | 
								spa_pod_builder_bool(&b, p->resample_disabled);
 | 
				
			||||||
			spa_pod_builder_string(&b, "dither.noise");
 | 
								spa_pod_builder_string(&b, "dither.noise");
 | 
				
			||||||
			spa_pod_builder_int(&b, p->dither_noise);
 | 
								spa_pod_builder_int(&b, this->dither.noise);
 | 
				
			||||||
			spa_pod_builder_pop(&b, &f[1]);
 | 
								spa_pod_builder_pop(&b, &f[1]);
 | 
				
			||||||
			param = spa_pod_builder_pop(&b, &f[0]);
 | 
								param = spa_pod_builder_pop(&b, &f[0]);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -755,7 +753,7 @@ static int audioconvert_set_param(struct impl *this, const char *k, const char *
 | 
				
			||||||
	else if (spa_streq(k, "resample.disable"))
 | 
						else if (spa_streq(k, "resample.disable"))
 | 
				
			||||||
		this->props.resample_disabled = spa_atob(s);
 | 
							this->props.resample_disabled = spa_atob(s);
 | 
				
			||||||
	else if (spa_streq(k, "dither.noise"))
 | 
						else if (spa_streq(k, "dither.noise"))
 | 
				
			||||||
		spa_atou32(s, &this->props.dither_noise, 0);
 | 
							spa_atou32(s, &this->dither.noise, 0);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
| 
						 | 
					@ -1396,18 +1394,24 @@ static int setup_out_convert(struct impl *this)
 | 
				
			||||||
			this->cpu_flags, out->conv.cpu_flags, out->conv.is_passthrough);
 | 
								this->cpu_flags, out->conv.cpu_flags, out->conv.is_passthrough);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->props.dither_noise > 0) {
 | 
						return 0;
 | 
				
			||||||
		this->dither.quantize = calc_width(&dst_info) * 8;
 | 
					}
 | 
				
			||||||
		this->dither.quantize -= SPA_MIN(this->dither.quantize, this->props.dither_noise);
 | 
					 | 
				
			||||||
		this->dither.n_channels = dst_info.info.raw.channels;
 | 
					 | 
				
			||||||
		this->dither.cpu_flags = this->cpu_flags;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((res = dither_init(&this->dither)) < 0)
 | 
					static int setup_dither(struct impl *this)
 | 
				
			||||||
			return res;
 | 
					{
 | 
				
			||||||
 | 
						struct dir *out = &this->dir[SPA_DIRECTION_OUTPUT];
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spa_log_info(this->log, "%p: dither noise:%d quantize:%d", this,
 | 
						this->dither.quantize = calc_width(&out->format) * 8;
 | 
				
			||||||
				this->props.dither_noise, this->dither.quantize);
 | 
						this->dither.n_channels = out->format.info.raw.channels;
 | 
				
			||||||
	}
 | 
						this->dither.cpu_flags = this->cpu_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((res = dither_init(&this->dither)) < 0)
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_log_info(this->log, "%p:got dither %08x:%08x noise:%d quantize:%d", this,
 | 
				
			||||||
 | 
								this->cpu_flags, this->dither.cpu_flags,
 | 
				
			||||||
 | 
								this->dither.noise, this->dither.quantize);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1453,6 +1457,8 @@ static int setup_convert(struct impl *this)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
	if ((res = setup_out_convert(this)) < 0)
 | 
						if ((res = setup_out_convert(this)) < 0)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
 | 
						if ((res = setup_dither(this)) < 0)
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < MAX_PORTS; i++) {
 | 
						for (i = 0; i < MAX_PORTS; i++) {
 | 
				
			||||||
		this->tmp_datas[0][i] = SPA_PTROFF(this->tmp, this->empty_size * i, void);
 | 
							this->tmp_datas[0][i] = SPA_PTROFF(this->tmp, this->empty_size * i, void);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ static const struct dither_info {
 | 
				
			||||||
} dither_table[] =
 | 
					} dither_table[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined (HAVE_SSE2)
 | 
					#if defined (HAVE_SSE2)
 | 
				
			||||||
	{ dither_f32_sse2, 0 },
 | 
						{ dither_f32_sse2, SPA_CPU_FLAG_SSE, },
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	{ dither_f32_c, 0 },
 | 
						{ dither_f32_c, 0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -74,12 +74,16 @@ int dither_init(struct dither *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct dither_info *info;
 | 
						const struct dither_info *info;
 | 
				
			||||||
	size_t i;
 | 
						size_t i;
 | 
				
			||||||
 | 
						uint32_t scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	info = find_dither_info(d->cpu_flags);
 | 
						info = find_dither_info(d->cpu_flags);
 | 
				
			||||||
	if (info == NULL)
 | 
						if (info == NULL)
 | 
				
			||||||
		return -ENOTSUP;
 | 
							return -ENOTSUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->scale = 1.0f / powf(2.0f, 31 + d->quantize);
 | 
						scale = d->quantize;
 | 
				
			||||||
 | 
						scale -= SPA_MIN(scale, d->noise);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d->scale = 1.0f / powf(2.0f, 31 + scale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->dither_size = DITHER_SIZE;
 | 
						d->dither_size = DITHER_SIZE;
 | 
				
			||||||
	d->dither = calloc(d->dither_size + DITHER_OPS_MAX_OVERREAD +
 | 
						d->dither = calloc(d->dither_size + DITHER_OPS_MAX_OVERREAD +
 | 
				
			||||||
| 
						 | 
					@ -90,6 +94,8 @@ int dither_init(struct dither *d)
 | 
				
			||||||
	for (i = 0; i < SPA_N_ELEMENTS(d->random); i++)
 | 
						for (i = 0; i < SPA_N_ELEMENTS(d->random); i++)
 | 
				
			||||||
		d->random[i] = random();
 | 
							d->random[i] = random();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d->cpu_flags = info->cpu_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->free = impl_dither_free;
 | 
						d->free = impl_dither_free;
 | 
				
			||||||
	d->process = info->process;
 | 
						d->process = info->process;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dither {
 | 
					struct dither {
 | 
				
			||||||
	uint32_t quantize;
 | 
						uint32_t quantize;
 | 
				
			||||||
 | 
						uint32_t noise;
 | 
				
			||||||
#define DITHER_METHOD_NONE		0
 | 
					#define DITHER_METHOD_NONE		0
 | 
				
			||||||
#define DITHER_METHOD_RECTANGULAR	2
 | 
					#define DITHER_METHOD_RECTANGULAR	2
 | 
				
			||||||
#define DITHER_METHOD_TRIANGULAR	3
 | 
					#define DITHER_METHOD_TRIANGULAR	3
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -396,10 +396,9 @@ int resample_native_init(struct resample *r)
 | 
				
			||||||
	build_filter(d->filter, d->filter_stride, n_taps, n_phases, scale);
 | 
						build_filter(d->filter, d->filter_stride, n_taps, n_phases, scale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d->info = find_resample_info(SPA_AUDIO_FORMAT_F32, r->cpu_flags);
 | 
						d->info = find_resample_info(SPA_AUDIO_FORMAT_F32, r->cpu_flags);
 | 
				
			||||||
	if (SPA_UNLIKELY(!d->info))
 | 
						if (SPA_UNLIKELY(d->info == NULL)) {
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	    spa_log_error(r->log, "failed to find suitable resample format!");
 | 
						    spa_log_error(r->log, "failed to find suitable resample format!");
 | 
				
			||||||
	    return -1;
 | 
						    return -ENOTSUP;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_debug(r->log, "native %p: q:%d in:%d out:%d n_taps:%d n_phases:%d features:%08x:%08x",
 | 
						spa_log_debug(r->log, "native %p: q:%d in:%d out:%d n_taps:%d n_phases:%d features:%08x:%08x",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,6 +73,7 @@ int volume_init(struct volume *vol)
 | 
				
			||||||
	if (info == NULL)
 | 
						if (info == NULL)
 | 
				
			||||||
		return -ENOTSUP;
 | 
							return -ENOTSUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vol->cpu_flags = info->cpu_flags;
 | 
				
			||||||
	vol->free = impl_volume_free;
 | 
						vol->free = impl_volume_free;
 | 
				
			||||||
	vol->process = info->process;
 | 
						vol->process = info->process;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue