audiocovert: improve dither setup

The quantize is the amount of bits we want to keep from the original
signal, subtract the amount of bits for noise. Clamp this to 0 (all
noise).
Calculate the scale factor better with powf() and avoid overflows.

Fixes #2479
This commit is contained in:
Wim Taymans 2022-06-28 10:11:46 +02:00
parent 67c2202044
commit b7e26002be
3 changed files with 9 additions and 11 deletions

View file

@ -1395,9 +1395,10 @@ static int setup_out_convert(struct impl *this)
spa_log_debug(this->log, "%p: got converter features %08x:%08x passthrough:%d", this, spa_log_debug(this->log, "%p: got converter features %08x:%08x passthrough:%d", 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) { if (this->props.dither_noise > 0) {
this->dither.quantize = 32 - (calc_width(&dst_info) * 8); this->dither.quantize = calc_width(&dst_info) * 8;
this->dither.quantize += this->props.dither_noise; this->dither.quantize -= SPA_MIN(this->dither.quantize, this->props.dither_noise);
this->dither.n_channels = dst_info.info.raw.channels; this->dither.n_channels = dst_info.info.raw.channels;
this->dither.cpu_flags = this->cpu_flags; this->dither.cpu_flags = this->cpu_flags;
@ -2478,7 +2479,7 @@ static int impl_node_process(void *object)
} }
this->out_offset += n_samples; this->out_offset += n_samples;
if (this->props.dither_noise > 0) { if (this->dither.process != NULL) {
in_datas = (const void**)out_datas; in_datas = (const void**)out_datas;
if (out_passthrough) if (out_passthrough)
out_datas = dst_datas; out_datas = dst_datas;

View file

@ -79,10 +79,7 @@ int dither_init(struct dither *d)
if (info == NULL) if (info == NULL)
return -ENOTSUP; return -ENOTSUP;
if (d->quantize >= 32) d->scale = 1.0f / powf(2.0f, 31 + d->quantize);
return -EINVAL;
d->scale = 1.0f / (1ULL << (63 - d->quantize));
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 +

View file

@ -34,10 +34,10 @@
struct dither { struct dither {
uint32_t quantize; uint32_t quantize;
#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
#define DITHER_METHOD_SHAPED_5 4 #define DITHER_METHOD_SHAPED_5 4
uint32_t method; uint32_t method;
uint32_t n_channels; uint32_t n_channels;
uint32_t cpu_flags; uint32_t cpu_flags;