[pulseaudio-discuss] [PATCH 20/22] loopback: Add low_device_latency parameter
Georg Chini
georg at chini.tk
Mon Feb 13 12:02:17 UTC 2017
For USB devices the latency jitter strongly depends on device latency. Therefore
a boolean low_device_latency parameter is introduced to half the device latency.
Normally 1/3 of the configured end-to-end latency is used, with the parameter
this is changed to 1/6. In many situations the parameter can improve latency
stability but it will also lead to significantly higher CPU consumption.
---
src/modules/module-loopback.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index 14253a8..952c395 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -47,6 +47,7 @@ PA_MODULE_USAGE(
"sink=<sink to connect to> "
"adjust_time=<how often to readjust rates in s> "
"latency_msec=<latency in ms> "
+ "low_device_latency=<boolean, use half of the normal device latency> "
"adjust_threshold_usec=<threshold for latency adjustment in usec> "
"format=<sample format> "
"rate=<sample rate> "
@@ -98,6 +99,7 @@ struct userdata {
pa_usec_t latency;
pa_usec_t adjust_time;
uint32_t adjust_threshold;
+ bool low_device_latency;
/* Latency boundaries and current values */
pa_usec_t min_source_latency;
@@ -188,6 +190,7 @@ static const char* const valid_modargs[] = {
"sink",
"adjust_time",
"latency_msec",
+ "low_device_latency",
"adjust_threshold_usec",
"format",
"rate",
@@ -759,11 +762,14 @@ static void get_effective_source_latency(struct userdata *u, pa_source *source,
* The choice of one third is rather arbitrary somewhere between the minimum
* possible latency (which would cause a lot of CPU load) and half the configured
* latency (which would lead to an empty memblockq if the sink is configured
- * likewise). */
+ * likewise). In low device latency mode set source to one sixth of the overall
+ * latency*/
static void set_source_output_latency(struct userdata *u, pa_source *source) {
pa_usec_t latency, requested_latency;
requested_latency = u->latency / 3;
+ if (u->low_device_latency)
+ requested_latency = u->latency / 6;
latency = PA_CLAMP(requested_latency , u->min_source_latency, u->max_source_latency);
u->configured_source_latency = pa_source_output_set_requested_latency(u->source_output, latency);
@@ -1112,11 +1118,14 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
* The choice of one third is rather arbitrary somewhere between the minimum
* possible latency (which would cause a lot of CPU load) and half the configured
* latency (which would lead to an empty memblockq if the source is configured
- * likewise). */
+ * likewise). In low device latency mode set sink to one sixth of the overall
+ * latency. */
static void set_sink_input_latency(struct userdata *u, pa_sink *sink) {
pa_usec_t latency, requested_latency;
requested_latency = u->latency / 3;
+ if (u->low_device_latency)
+ requested_latency = u->latency / 6;
latency = PA_CLAMP(requested_latency , u->min_sink_latency, u->max_sink_latency);
u->configured_sink_latency = pa_sink_input_set_requested_latency(u->sink_input, latency);
@@ -1433,6 +1442,7 @@ int pa__init(pa_module *m) {
uint32_t adjust_time_sec;
const char *n;
bool remix = true;
+ bool low_device_latency = false;
pa_assert(m);
@@ -1514,6 +1524,11 @@ int pa__init(pa_module *m) {
goto fail;
}
+ if (pa_modargs_get_value_boolean(ma, "low_device_latency", &low_device_latency) < 0) {
+ pa_log("Invalid boolean device latency parameter");
+ goto fail;
+ }
+
m->userdata = u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
@@ -1533,6 +1548,7 @@ int pa__init(pa_module *m) {
u->latency_error = 0;
u->adjust_threshold = adjust_threshold;
u->target_latency_cross_counter = 0;
+ u->low_device_latency = low_device_latency;
adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
--
2.10.1
More information about the pulseaudio-discuss
mailing list