mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
audioconvert: update initial resampler rate match
When starting the converter, calculate the initial size needed by the resampler to fill one quantum. This makes it possible to get the requested amount of samples before the first process call is made.
This commit is contained in:
parent
7c9b96c606
commit
63e283f377
1 changed files with 53 additions and 45 deletions
|
|
@ -1813,10 +1813,53 @@ static int ensure_tmp(struct impl *this, uint32_t maxsize, uint32_t maxports)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t resample_update_rate_match(struct impl *this, bool passthrough, uint32_t out_size, uint32_t in_queued)
|
||||
{
|
||||
uint32_t delay, match_size;
|
||||
|
||||
if (passthrough) {
|
||||
delay = 0;
|
||||
match_size = out_size;
|
||||
} else {
|
||||
double rate = this->rate_scale / this->props.rate;
|
||||
if (this->io_rate_match &&
|
||||
SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE))
|
||||
rate *= this->io_rate_match->rate;
|
||||
resample_update_rate(&this->resample, rate);
|
||||
delay = resample_delay(&this->resample);
|
||||
match_size = resample_in_len(&this->resample, out_size);
|
||||
}
|
||||
match_size -= SPA_MIN(match_size, in_queued);
|
||||
|
||||
spa_log_trace_fp(this->log, "%p: next match %u", this, match_size);
|
||||
|
||||
if (this->io_rate_match) {
|
||||
this->io_rate_match->delay = delay + in_queued;
|
||||
this->io_rate_match->size = match_size;
|
||||
}
|
||||
return match_size;
|
||||
}
|
||||
|
||||
static inline bool resample_is_passthrough(struct impl *this)
|
||||
{
|
||||
if (this->props.resample_disabled)
|
||||
return true;
|
||||
if (this->resample.i_rate != this->resample.o_rate)
|
||||
return false;
|
||||
if (this->rate_scale != 1.0)
|
||||
return false;
|
||||
if (this->rate_adjust)
|
||||
return false;
|
||||
if (this->io_rate_match != NULL &&
|
||||
SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int setup_convert(struct impl *this)
|
||||
{
|
||||
struct dir *in, *out;
|
||||
uint32_t i, rate, maxsize, maxports;
|
||||
uint32_t i, rate, maxsize, maxports, duration;
|
||||
struct port *p;
|
||||
int res;
|
||||
|
||||
|
|
@ -1832,7 +1875,13 @@ static int setup_convert(struct impl *this)
|
|||
if (!in->have_format || !out->have_format)
|
||||
return -EINVAL;
|
||||
|
||||
rate = this->io_position ? this->io_position->clock.target_rate.denom : DEFAULT_RATE;
|
||||
if (this->io_position != NULL) {
|
||||
rate = this->io_position->clock.target_rate.denom;
|
||||
duration = this->io_position->clock.target_duration;
|
||||
} else {
|
||||
rate = DEFAULT_RATE;
|
||||
duration = this->quantum_limit;
|
||||
}
|
||||
|
||||
/* in DSP mode we always convert to the DSP rate */
|
||||
if (in->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp)
|
||||
|
|
@ -1879,6 +1928,8 @@ static int setup_convert(struct impl *this)
|
|||
if ((res = ensure_tmp(this, maxsize, maxports)) < 0)
|
||||
return res;
|
||||
|
||||
resample_update_rate_match(this, resample_is_passthrough(this), duration, 0);
|
||||
|
||||
this->setup = true;
|
||||
|
||||
emit_node_info(this, false);
|
||||
|
|
@ -2736,49 +2787,6 @@ static inline uint32_t resample_get_in_size(struct impl *this, bool passthrough,
|
|||
return match_size;
|
||||
}
|
||||
|
||||
static uint32_t resample_update_rate_match(struct impl *this, bool passthrough, uint32_t out_size, uint32_t in_queued)
|
||||
{
|
||||
uint32_t delay, match_size;
|
||||
|
||||
if (passthrough) {
|
||||
delay = 0;
|
||||
match_size = out_size;
|
||||
} else {
|
||||
double rate = this->rate_scale / this->props.rate;
|
||||
if (this->io_rate_match &&
|
||||
SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE))
|
||||
rate *= this->io_rate_match->rate;
|
||||
resample_update_rate(&this->resample, rate);
|
||||
delay = resample_delay(&this->resample);
|
||||
match_size = resample_in_len(&this->resample, out_size);
|
||||
}
|
||||
match_size -= SPA_MIN(match_size, in_queued);
|
||||
|
||||
spa_log_trace_fp(this->log, "%p: next match %u", this, match_size);
|
||||
|
||||
if (this->io_rate_match) {
|
||||
this->io_rate_match->delay = delay + in_queued;
|
||||
this->io_rate_match->size = match_size;
|
||||
}
|
||||
return match_size;
|
||||
}
|
||||
|
||||
static inline bool resample_is_passthrough(struct impl *this)
|
||||
{
|
||||
if (this->props.resample_disabled)
|
||||
return true;
|
||||
if (this->resample.i_rate != this->resample.o_rate)
|
||||
return false;
|
||||
if (this->rate_scale != 1.0)
|
||||
return false;
|
||||
if (this->rate_adjust)
|
||||
return false;
|
||||
if (this->io_rate_match != NULL &&
|
||||
SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint64_t get_time_ns(struct impl *impl)
|
||||
{
|
||||
struct timespec now;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue