[pulseaudio-discuss] [PATCH 2/4] echo-cancel: Fix calc_diff for asymmetric sample specs

Peter Meerwald pmeerw at pmeerw.net
Tue Dec 4 05:54:59 PST 2012


From: Stefan Huber <s.huber at bct-electronic.com>

In case that source and sink use different sample specs (e.g., different
number of channels) the computation of the latency difference fails.
To fix this, we obtain the corresponding latencies in terms of time using
the respective sample specs instead of buffer sizes.

Signed-off-by: Stefan Huber <s.huber at bct-electronic.com>
Acked-by: Peter Meerwald <p.meerwald at bct-electronic.com>
---
 src/modules/echo-cancel/module-echo-cancel.c |   26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 26ac30b..8d89d2d 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -294,24 +294,28 @@ enum {
 };
 
 static int64_t calc_diff(struct userdata *u, struct snapshot *snapshot) {
-    int64_t buffer, diff_time, buffer_latency;
+    int64_t diff_time, buffer_latency;
+    int64_t plen, rlen, source_delay, sink_delay, recv_counter, send_counter;
 
     /* get the number of samples between capture and playback */
-    if (snapshot->plen > snapshot->rlen)
-        buffer = snapshot->plen - snapshot->rlen;
+    plen = pa_bytes_to_usec(snapshot->plen, &u->sink_input->sample_spec);
+    rlen = pa_bytes_to_usec(snapshot->plen, &u->source_output->sample_spec);
+    if (plen > rlen)
+        buffer_latency = plen-rlen;
     else
-        buffer = 0;
+        buffer_latency = 0;
 
-    buffer += snapshot->source_delay + snapshot->sink_delay;
+    source_delay = pa_bytes_to_usec(snapshot->source_delay, &u->source_output->sample_spec);
+    sink_delay = pa_bytes_to_usec(snapshot->sink_delay, &u->sink_input->sample_spec);
+    buffer_latency += source_delay + sink_delay;
 
     /* add the amount of samples not yet transferred to the source context */
-    if (snapshot->recv_counter <= snapshot->send_counter)
-        buffer += (int64_t) (snapshot->send_counter - snapshot->recv_counter);
+    recv_counter = pa_bytes_to_usec(snapshot->recv_counter, &u->source_output->sample_spec);
+    send_counter = pa_bytes_to_usec(snapshot->send_counter, &u->sink_input->sample_spec);
+    if (recv_counter <= send_counter)
+        buffer_latency += send_counter - recv_counter;
     else
-        buffer += PA_CLIP_SUB(buffer, (int64_t) (snapshot->recv_counter - snapshot->send_counter));
-
-    /* convert to time */
-    buffer_latency = pa_bytes_to_usec(buffer, &u->source_output->sample_spec);
+        buffer_latency += PA_CLIP_SUB(buffer_latency, recv_counter - send_counter);
 
     /* capture and playback samples are perfectly aligned when diff_time is 0 */
     diff_time = (snapshot->sink_now + snapshot->sink_latency - buffer_latency) -
-- 
1.7.9.5



More information about the pulseaudio-discuss mailing list