[pulseaudio-commits] 3 commits - src/pulsecore src/utils

Tanu Kaskinen tanuk at kemper.freedesktop.org
Wed Jun 27 05:41:41 PDT 2012


 src/pulsecore/cli-command.c |   48 ++++++++++++++++++++++++++++++++++++++++++++
 src/pulsecore/cli-text.c    |    5 ++--
 src/pulsecore/device-port.c |   28 +++++++++++++++++++++++++
 src/pulsecore/device-port.h |    3 ++
 src/pulsecore/sink.c        |   28 +++++++++++++++++++++++++
 src/pulsecore/sink.h        |    8 +++++++
 src/pulsecore/source.c      |   26 +++++++++++++++++++++++
 src/pulsecore/source.h      |    9 ++++++++
 src/utils/pacmd.c           |    1 
 9 files changed, 154 insertions(+), 2 deletions(-)

New commits:
commit 7688e64739b4bd0d8ca7879e34e40a96e83fdf5a
Author: poljar <poljarinho at gmail.com>
Date:   Fri Jun 22 20:55:55 2012 +0200

    pacmd: Add functions to handle the latency offset
    
    pacmd was extended so it can handle the new latency offset.
    
    A new function was added so we can set the latency also the list
    commands were extended to print the latency offset on the ports.

diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index fc9465b..33f4d49 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -135,6 +135,7 @@ static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer
 static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 
 /* A method table for all available commands */
@@ -168,6 +169,7 @@ static const struct command commands[] = {
     { "set-card-profile",        pa_cli_command_card_profile,       "Change the profile of a card (args: index|name, profile-name)", 3},
     { "set-sink-port",           pa_cli_command_sink_port,          "Change the port of a sink (args: index|name, port-name)", 3},
     { "set-source-port",         pa_cli_command_source_port,        "Change the port of a source (args: index|name, port-name)", 3},
+    { "set-port-latency-offset", pa_cli_command_port_offset,        "Change the latency of a port (args: card-index|card-name, port-name, latency-offset)", 4},
     { "suspend-sink",            pa_cli_command_suspend_sink,       "Suspend sink (args: index|name, bool)", 3},
     { "suspend-source",          pa_cli_command_suspend_source,     "Suspend source (args: index|name, bool)", 3},
     { "suspend",                 pa_cli_command_suspend,            "Suspend all sinks and all sources (args: bool)", 2},
@@ -1723,6 +1725,52 @@ static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
     return 0;
 }
 
+static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    const char *n, *p, *l;
+    pa_device_port *port;
+    pa_card *card;
+    int32_t offset;
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    if (!(n = pa_tokenizer_get(t, 1))) {
+        pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
+        return -1;
+    }
+
+    if (!(p = pa_tokenizer_get(t, 2))) {
+        pa_strbuf_puts(buf, "You need to specify a port by its name.\n");
+        return -1;
+    }
+
+    if (!(l = pa_tokenizer_get(t, 3))) {
+        pa_strbuf_puts(buf, "You need to specify a latency offset.\n");
+        return -1;
+    }
+
+    if (pa_atoi(l, &offset) < 0) {
+        pa_strbuf_puts(buf, "Failed to parse the latency offset.\n");
+        return -1;
+    }
+
+    if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
+        pa_strbuf_puts(buf, "No card found by this name or index.\n");
+        return -1;
+    }
+
+    if (!(port = pa_hashmap_get(card->ports, p))) {
+        pa_strbuf_puts(buf, "No port found by this name.\n");
+        return -1;
+    }
+
+    pa_device_port_set_latency_offset(port, (pa_usec_t) offset);
+
+    return 0;
+}
+
 static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     pa_module *m;
     pa_sink *sink;
diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c
index d234b96..f322172 100644
--- a/src/pulsecore/cli-text.c
+++ b/src/pulsecore/cli-text.c
@@ -126,8 +126,9 @@ static void append_port_list(pa_strbuf *s, pa_hashmap *ports)
     pa_strbuf_puts(s, "\tports:\n");
     PA_HASHMAP_FOREACH(p, ports, state) {
         char *t = pa_proplist_to_string_sep(p->proplist, "\n\t\t\t\t");
-        pa_strbuf_printf(s, "\t\t%s: %s (priority %u, available: %s)\n",
-            p->name, p->description, p->priority, port_available_to_string(p->available));
+        pa_strbuf_printf(s, "\t\t%s: %s (priority %u, latency offset %" PRId64 " usec, available: %s)\n",
+            p->name, p->description, p->priority, p->latency_offset,
+            port_available_to_string(p->available));
         pa_strbuf_printf(s, "\t\t\tproperties:\n\t\t\t\t%s\n", t);
         pa_xfree(t);
     }
diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c
index c7c693b..a47a54a 100644
--- a/src/utils/pacmd.c
+++ b/src/utils/pacmd.c
@@ -73,6 +73,7 @@ static void help(const char *argv0) {
     printf("%s %s %s\n", argv0, "suspend", _("1|0"));
     printf("%s %s %s\n", argv0, "set-card-profile", _("CARD PROFILE"));
     printf("%s %s %s\n", argv0, "set-(sink|source)-port", _("NAME|#N PORT"));
+    printf("%s %s %s\n", argv0, "set-port-latency-offset", _("CARD-NAME|CARD-#N PORT OFFSET"));
     printf("%s %s %s\n", argv0, "set-log-level", _("NUMERIC LEVEL"));
     printf("%s %s %s\n", argv0, "set-log-meta", _("1|0"));
     printf("%s %s %s\n", argv0, "set-log-time", _("1|0"));

commit eebdda456bb79d581294a9032d4be9a9e55df3bd
Author: poljar <poljarinho at gmail.com>
Date:   Fri Jun 22 20:55:54 2012 +0200

    sink, source: Add a latency offset which is inherited from the port
    
    A latency offset variable was added to the sink/source struct.
    
    Also a function was introduced to update the latency offset of the
    sink/source and a new message type was introduced so we can send the latency
    offset to the IO thread.
    
    The latency offset is automatically populated with the latency from the
    currently active port.

diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index ae486a8..46e37e2 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -115,7 +115,28 @@ void pa_device_port_hashmap_free(pa_hashmap *h) {
 }
 
 void pa_device_port_set_latency_offset(pa_device_port *p, pa_usec_t offset) {
+    uint32_t state;
+
     pa_assert(p);
 
     p->latency_offset = offset;
+
+    if (p->is_output) {
+        pa_sink *sink;
+
+        PA_IDXSET_FOREACH(sink, p->core->sinks, state)
+            if (sink->active_port == p) {
+                pa_sink_set_latency_offset(sink, p->latency_offset);
+                break;
+            }
+
+    } else {
+        pa_source *source;
+
+        PA_IDXSET_FOREACH(source, p->core->sources, state)
+            if (source->active_port == p) {
+                pa_source_set_latency_offset(source, p->latency_offset);
+                break;
+            }
+    }
 }
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index e4c343d..545a8e1 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -308,6 +308,11 @@ pa_sink* pa_sink_new(
                 s->active_port = p;
     }
 
+    if (s->active_port)
+        s->latency_offset = s->active_port->latency_offset;
+    else
+        s->latency_offset = 0;
+
     s->save_volume = data->save_volume;
     s->save_muted = data->save_muted;
 
@@ -338,6 +343,7 @@ pa_sink* pa_sink_new(
     pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
     s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
     s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
+    s->thread_info.latency_offset = s->latency_offset;
 
     /* FIXME: This should probably be moved to pa_sink_put() */
     pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
@@ -1422,6 +1428,8 @@ pa_usec_t pa_sink_get_latency(pa_sink *s) {
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
 
+    usec += s->latency_offset;
+
     return usec;
 }
 
@@ -1449,6 +1457,8 @@ pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s) {
     if (o->process_msg(o, PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
         return -1;
 
+    usec += s->thread_info.latency_offset;
+
     return usec;
 }
 
@@ -2812,6 +2822,10 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             pa_sink_get_mute(s, TRUE);
             return 0;
 
+        case PA_SINK_MESSAGE_SET_LATENCY_OFFSET:
+            s->thread_info.latency_offset = (pa_usec_t) offset;
+            return 0;
+
         case PA_SINK_MESSAGE_GET_LATENCY:
         case PA_SINK_MESSAGE_MAX:
             ;
@@ -3224,6 +3238,18 @@ void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
 }
 
 /* Called from main context */
+void pa_sink_set_latency_offset(pa_sink *s, pa_usec_t offset) {
+    pa_sink_assert_ref(s);
+
+    s->latency_offset = offset;
+
+    if (PA_SINK_IS_LINKED(s->state))
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_OFFSET, NULL, (int64_t) offset, NULL) == 0);
+    else
+        s->thread_info.fixed_latency = offset;
+}
+
+/* Called from main context */
 size_t pa_sink_get_max_rewind(pa_sink *s) {
     size_t r;
     pa_assert_ctl_context();
@@ -3293,6 +3319,8 @@ int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
     s->active_port = port;
     s->save_port = save;
 
+    pa_sink_set_latency_offset(s, s->active_port->latency_offset);
+
     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
 
     return 0;
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 0b5048a..b138a1d 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -113,6 +113,9 @@ struct pa_sink {
     pa_device_port *active_port;
     pa_atomic_t mixer_dirty;
 
+    /* The latency offset is inherited from the currently active port */
+    pa_usec_t latency_offset;
+
     unsigned priority;
 
     /* Called when the main loop requests a state change. Called from
@@ -268,6 +271,9 @@ struct pa_sink {
          * in changing it */
         pa_usec_t fixed_latency; /* for sinks with PA_SINK_DYNAMIC_LATENCY this is 0 */
 
+        /* This latency offset is a direct copy from s->latency_offset */
+        pa_usec_t latency_offset;
+
         /* Delayed volume change events are queued here. The events
          * are stored in expiration order. The one expiring next is in
          * the head of the list. */
@@ -317,6 +323,7 @@ typedef enum pa_sink_message {
     PA_SINK_MESSAGE_SET_MAX_REQUEST,
     PA_SINK_MESSAGE_SET_PORT,
     PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE,
+    PA_SINK_MESSAGE_SET_LATENCY_OFFSET,
     PA_SINK_MESSAGE_MAX
 } pa_sink_message_t;
 
@@ -403,6 +410,7 @@ unsigned pa_device_init_priority(pa_proplist *p);
 /**** May be called by everyone, from main context */
 
 pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough);
+void pa_sink_set_latency_offset(pa_sink *s, pa_usec_t offset);
 
 /* The returned value is supposed to be in the time domain of the sound card! */
 pa_usec_t pa_sink_get_latency(pa_sink *s);
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 6308f54..63a75ef 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -296,6 +296,11 @@ pa_source* pa_source_new(
                 s->active_port = p;
     }
 
+    if (s->active_port)
+        s->latency_offset = s->active_port->latency_offset;
+    else
+        s->latency_offset = 0;
+
     s->save_volume = data->save_volume;
     s->save_muted = data->save_muted;
 
@@ -323,6 +328,7 @@ pa_source* pa_source_new(
     pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
     s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
     s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
+    s->thread_info.latency_offset = s->latency_offset;
 
     /* FIXME: This should probably be moved to pa_source_put() */
     pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
@@ -1024,6 +1030,8 @@ pa_usec_t pa_source_get_latency(pa_source *s) {
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
 
+    usec += s->latency_offset;
+
     return usec;
 }
 
@@ -1051,6 +1059,8 @@ pa_usec_t pa_source_get_latency_within_thread(pa_source *s) {
     if (o->process_msg(o, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
         return -1;
 
+    usec += s->thread_info.latency_offset;
+
     return usec;
 }
 
@@ -2168,6 +2178,10 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
             pa_source_get_mute(s, TRUE);
             return 0;
 
+        case PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET:
+            s->thread_info.latency_offset = (pa_usec_t) offset;
+            return 0;
+
         case PA_SOURCE_MESSAGE_MAX:
             ;
     }
@@ -2508,6 +2522,18 @@ void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency)
 }
 
 /* Called from main thread */
+void pa_source_set_latency_offset(pa_source *s, pa_usec_t offset) {
+    pa_source_assert_ref(s);
+
+    s->latency_offset = offset;
+
+    if (PA_SOURCE_IS_LINKED(s->state))
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET, NULL, (int64_t) offset, NULL) == 0);
+    else
+        s->thread_info.fixed_latency = offset;
+}
+
+/* Called from main thread */
 size_t pa_source_get_max_rewind(pa_source *s) {
     size_t r;
     pa_assert_ctl_context();
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index 30c2037..da024e6 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -113,6 +113,9 @@ struct pa_source {
     pa_device_port *active_port;
     pa_atomic_t mixer_dirty;
 
+    /* The latency offset is inherited from the currently active port */
+    pa_usec_t latency_offset;
+
     unsigned priority;
 
     /* Called when the main loop requests a state change. Called from
@@ -209,6 +212,9 @@ struct pa_source {
 
         pa_usec_t fixed_latency; /* for sources with PA_SOURCE_DYNAMIC_LATENCY this is 0 */
 
+        /* This latency offset is a direct copy from s->latency_offset */
+        pa_usec_t latency_offset;
+
         /* Delayed volume change events are queued here. The events
          * are stored in expiration order. The one expiring next is in
          * the head of the list. */
@@ -254,6 +260,7 @@ typedef enum pa_source_message {
     PA_SOURCE_MESSAGE_SET_MAX_REWIND,
     PA_SOURCE_MESSAGE_SET_PORT,
     PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE,
+    PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET,
     PA_SOURCE_MESSAGE_MAX
 } pa_source_message_t;
 
@@ -335,6 +342,8 @@ void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flag
 
 /*** May be called by everyone, from main context */
 
+void pa_source_set_latency_offset(pa_source *s, pa_usec_t offset);
+
 /* The returned value is supposed to be in the time domain of the sound card! */
 pa_usec_t pa_source_get_latency(pa_source *s);
 pa_usec_t pa_source_get_requested_latency(pa_source *s);

commit bc0348789623f0b253795c2d661bc9ea25111793
Author: poljar <poljarinho at gmail.com>
Date:   Fri Jun 22 20:55:53 2012 +0200

    device-port: Add a latency variable to the port struct
    
    A latency offset variable was added to the port struct and a function to
    set the latency offset.
    
    The latency offset does nothing for now, but it will be later added to
    the sink/source latency.

diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 5870913..ae486a8 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -97,6 +97,7 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des
     p->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     p->is_input = FALSE;
     p->is_output = FALSE;
+    p->latency_offset = 0;
     p->proplist = pa_proplist_new();
 
     return p;
@@ -112,3 +113,9 @@ void pa_device_port_hashmap_free(pa_hashmap *h) {
 
     pa_hashmap_free(h, NULL, NULL);
 }
+
+void pa_device_port_set_latency_offset(pa_device_port *p, pa_usec_t offset) {
+    pa_assert(p);
+
+    p->latency_offset = offset;
+}
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index 63d5ccf..5880195 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -51,6 +51,7 @@ struct pa_device_port {
     pa_hashmap *profiles; /* Does not own the profiles */
     pa_bool_t is_input:1;
     pa_bool_t is_output:1;
+    pa_usec_t latency_offset;
 
     /* .. followed by some implementation specific data */
 };
@@ -67,4 +68,6 @@ void pa_device_port_hashmap_free(pa_hashmap *h);
 /* The port's available status has changed */
 void pa_device_port_set_available(pa_device_port *p, pa_port_available_t available);
 
+void pa_device_port_set_latency_offset(pa_device_port *p, pa_usec_t offset);
+
 #endif



More information about the pulseaudio-commits mailing list