[pulseaudio-discuss] [PATCH] loopback: max_latency_msec argument

Georg Chini georg at chini.tk
Sun Feb 18 10:37:06 UTC 2018


On 15.02.2018 12:50, Raman Shyshniou wrote:
> Currently loopback module indefinitely increased latency if underruns
> occurs. This patch allows to set up the upper limit of latency.
> ---
>   src/modules/module-loopback.c | 34 ++++++++++++++++++++++++++++++----
>   1 file changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
> index aecac0a..052d255 100644
> --- a/src/modules/module-loopback.c
> +++ b/src/modules/module-loopback.c
> @@ -45,6 +45,7 @@ PA_MODULE_USAGE(
>           "sink=<sink to connect to> "
>           "adjust_time=<how often to readjust rates in s> "
>           "latency_msec=<latency in ms> "
> +        "max_latency_msec=<maximum latency in ms> "
>           "format=<sample format> "
>           "rate=<sample rate> "
>           "channels=<number of channels> "
> @@ -89,6 +90,7 @@ struct userdata {
>   
>       /* Values from command line configuration */
>       pa_usec_t latency;
> +    pa_usec_t max_latency;
>       pa_usec_t adjust_time;
>   
>       /* Latency boundaries and current values */
> @@ -158,6 +160,7 @@ static const char* const valid_modargs[] = {
>       "sink",
>       "adjust_time",
>       "latency_msec",
> +    "max_latency_msec",
>       "format",
>       "rate",
>       "channels",
> @@ -325,10 +328,20 @@ static void adjust_rates(struct userdata *u) {
>   
>       /* If we are seeing underruns then the latency is too small */
>       if (u->underrun_counter > 2) {
> -        u->underrun_latency_limit = PA_MAX(u->latency, u->minimum_latency) + 5 * PA_USEC_PER_MSEC;
> -        u->underrun_latency_limit = PA_CLIP_SUB((int64_t)u->underrun_latency_limit, u->sink_latency_offset + u->source_latency_offset);
> +        pa_usec_t target_latency;
> +
> +        target_latency = PA_MAX(u->latency, u->minimum_latency) + 5 * PA_USEC_PER_MSEC;
> +
> +        if (u->max_latency == 0 || target_latency < u->max_latency) {
> +            u->underrun_latency_limit = PA_CLIP_SUB((int64_t)target_latency, u->sink_latency_offset + u->source_latency_offset);
> +            pa_log_warn("Too many underruns, increasing latency to %0.2f ms", (double)u->underrun_latency_limit / PA_USEC_PER_MSEC);

You have to use target_latency here ...

> +        } else {
> +            u->underrun_latency_limit = PA_CLIP_SUB((int64_t)u->max_latency, u->sink_latency_offset + u->source_latency_offset);
> +            pa_log_warn("Too many underruns, configured maximum latency of %0.2f ms is reached", (double)u->underrun_latency_limit / PA_USEC_PER_MSEC);

and u->max_latency here. Otherwise looks good.

> +            pa_log_warn("Consider increasing the max_latency_msec");
> +        }
> +
>           update_minimum_latency(u, u->sink_input->sink, false);
> -        pa_log_warn("Too many underruns, increasing latency to %0.2f ms", (double)u->minimum_latency / PA_USEC_PER_MSEC);
>           u->underrun_counter = 0;
>       }
>   
> @@ -347,7 +360,7 @@ static void adjust_rates(struct userdata *u) {
>       }
>       u->adjust_time_stamp = now;
>   
> -    /* Rates and latencies*/
> +    /* Rates and latencies */
>       old_rate = u->sink_input->sample_spec.rate;
>       base_rate = u->source_output->sample_spec.rate;
>   
> @@ -1252,6 +1265,7 @@ int pa__init(pa_module *m) {
>       pa_source_output_new_data source_output_data;
>       bool source_dont_move;
>       uint32_t latency_msec;
> +    uint32_t max_latency_msec;
>       pa_sample_spec ss;
>       pa_channel_map map;
>       bool format_set = false;
> @@ -1336,10 +1350,22 @@ int pa__init(pa_module *m) {
>           goto fail;
>       }
>   
> +    max_latency_msec = 0;
> +    if (pa_modargs_get_value_u32(ma, "max_latency_msec", &max_latency_msec) < 0) {
> +        pa_log("Invalid maximum latency specification");
> +        goto fail;
> +    }
> +
> +    if (max_latency_msec > 0 && max_latency_msec < latency_msec) {
> +        pa_log_warn("Configured maximum latency is smaller than latency, using latency instead");
> +        max_latency_msec = latency_msec;
> +    }
> +
>       m->userdata = u = pa_xnew0(struct userdata, 1);
>       u->core = m->core;
>       u->module = m;
>       u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
> +    u->max_latency = (pa_usec_t) max_latency_msec * PA_USEC_PER_MSEC;
>       u->output_thread_info.pop_called = false;
>       u->output_thread_info.pop_adjust = false;
>       u->output_thread_info.push_called = false;




More information about the pulseaudio-discuss mailing list