audioconvert: avoids pops and clicks when activating resampler

When we were using the resampler and then bypass it when the configured
rate == 1.0, we create a pop because we don't process the queued data in
the resampler anymore.

Avoid this by keeping the resampler active as soon as the rate property
is set on the audioconvert. The resampler itself will use a more
efficient copy method in that case anyway and it is expected that the
rate will change again later when we need to reactivate the resampler.
This commit is contained in:
Wim Taymans 2022-10-07 15:05:22 +02:00
parent 0d7e20534f
commit 01058d9b4c

View file

@ -220,6 +220,7 @@ struct impl {
unsigned int resample_peaks:1; unsigned int resample_peaks:1;
unsigned int is_passthrough:1; unsigned int is_passthrough:1;
unsigned int drained:1; unsigned int drained:1;
unsigned int rate_adjust:1;
uint32_t empty_size; uint32_t empty_size;
float *empty; float *empty;
@ -908,6 +909,11 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
break; break;
case SPA_PROP_rate: case SPA_PROP_rate:
spa_pod_get_double(&prop->value, &p->rate); spa_pod_get_double(&prop->value, &p->rate);
if (!this->rate_adjust && p->rate != 1.0) {
this->rate_adjust = true;
spa_log_info(this->log, "%p: activating adaptive resampler",
this);
}
break; break;
case SPA_PROP_params: case SPA_PROP_params:
changed += parse_prop_params(this, &prop->value); changed += parse_prop_params(this, &prop->value);
@ -1354,6 +1360,8 @@ static int setup_resample(struct impl *this)
this->resample.quality = this->props.resample_quality; this->resample.quality = this->props.resample_quality;
this->resample.cpu_flags = this->cpu_flags; this->resample.cpu_flags = this->cpu_flags;
this->rate_adjust = this->props.rate != 1.0;
if (this->resample_peaks) if (this->resample_peaks)
res = resample_peaks_init(&this->resample); res = resample_peaks_init(&this->resample);
else else
@ -2269,8 +2277,7 @@ static uint32_t resample_update_rate_match(struct impl *this, bool passthrough,
static inline bool resample_is_passthrough(struct impl *this) static inline bool resample_is_passthrough(struct impl *this)
{ {
return this->resample.i_rate == this->resample.o_rate && this->rate_scale == 1.0 && return this->resample.i_rate == this->resample.o_rate && this->rate_scale == 1.0 &&
this->props.rate == 1.0 && !this->rate_adjust && (this->io_rate_match == NULL ||
(this->io_rate_match == NULL ||
!SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE)); !SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE));
} }