[pulseaudio-commits] 2 commits - src/modules

Tanu Kaskinen tanuk at kemper.freedesktop.org
Thu Dec 20 02:59:57 PST 2012


 src/modules/echo-cancel/adrian.c             |   11 +-
 src/modules/echo-cancel/echo-cancel.h        |   21 +++--
 src/modules/echo-cancel/module-echo-cancel.c |  101 ++++++++++++++-------------
 src/modules/echo-cancel/null.c               |   22 ++---
 src/modules/echo-cancel/speex.c              |   28 +++----
 src/modules/echo-cancel/webrtc.cc            |    5 -
 6 files changed, 98 insertions(+), 90 deletions(-)

New commits:
commit de73a3ed9871007892501f655d7ad798f127f20c
Author: Stefan Huber <s.huber at bct-electronic.com>
Date:   Thu Dec 20 11:33:05 2012 +0100

    echo-cancel: Extend null implementation to arbitary sample specs
    
    The new null implementation works with arbitrary sample specs for source
    and sink. In particular, it handles a different number of channels for
    source and sink.
    
    Signed-off-by: Stefan Huber <s.huber at bct-electronic.com>
    Acked-by: Peter Meerwald <p.meerwald at bct-electronic.com>

diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h
index 9f14ade..e7eed30 100644
--- a/src/modules/echo-cancel/echo-cancel.h
+++ b/src/modules/echo-cancel/echo-cancel.h
@@ -46,6 +46,9 @@ typedef struct pa_echo_canceller_params pa_echo_canceller_params;
 
 struct pa_echo_canceller_params {
     union {
+        struct {
+            pa_sample_spec source_ss;
+        } null;
 #ifdef HAVE_SPEEX
         struct {
             SpeexEchoState *state;
diff --git a/src/modules/echo-cancel/null.c b/src/modules/echo-cancel/null.c
index bfd6c30..6d9531a 100644
--- a/src/modules/echo-cancel/null.c
+++ b/src/modules/echo-cancel/null.c
@@ -29,22 +29,23 @@ pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
                            uint32_t *nframes, const char *args) {
-    *nframes = 256;
-
-    source_ss->format = PA_SAMPLE_S16NE;
-    source_ss->channels = 1;
+    char strss_source[PA_SAMPLE_SPEC_SNPRINT_MAX];
+    char strss_sink[PA_SAMPLE_SPEC_SNPRINT_MAX];
 
-    *sink_ss = *source_ss;
-    *sink_map = *source_map;
+    *nframes = 256;
+    ec->params.priv.null.source_ss = *source_ss;
 
-    pa_log_debug("null AEC: nframes %u, channels %d, rate %d", *nframes, source_ss->channels, source_ss->rate);
+    pa_log_debug("null AEC: nframes=%u, sample spec source=%s, sample spec sink=%s", *nframes,
+            pa_sample_spec_snprint(strss_source, sizeof(strss_source), source_ss),
+            pa_sample_spec_snprint(strss_sink, sizeof(strss_sink), sink_ss));
 
     return TRUE;
 }
 
 void pa_null_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
-    // blocksize is nframes * frame-size
-    memcpy(out, rec, 256 * 2);
+    /* The null implementation simply copies the recorded buffer to the output
+       buffer and ignores the play buffer. */
+    memcpy(out, rec, 256 * pa_frame_size(&ec->params.priv.null.source_ss));
 }
 
 void pa_null_ec_done(pa_echo_canceller *ec) {

commit 3a92be3c5cee24fafae99dc20e4973adba9a5e57
Author: Stefan Huber <s.huber at bct-electronic.com>
Date:   Thu Dec 20 11:33:04 2012 +0100

    echo-cancel: Enable different blocksizes for sink and source
    
    In order to support different blocksizes for source and sink (e.g, for
    4-to-1 beamforming/echo canceling which involves 4 record channels and 1
    playback channel) the AEC API is altered:
    
    The blocksize for source and sink may differ (due to different sample
    specs) but the number of frames that are processed in one invokation of
    the AEC implementation's run() function is the same for the playback and
    the record stream. Consequently, the AEC implementation's init()
    function initalizes 'nframes' instead of 'blocksize' and the source's
    and sink's blocksizes are derived from 'nframes'. The old API also
    caused code duplication in each AEC implementation's init function for
    the compution of the blocksize, which is eliminated by the new API.
    
    Signed-off-by: Stefan Huber <s.huber at bct-electronic.com>
    Acked-by: Peter Meerwald <p.meerwald at bct-electronic.com>

diff --git a/src/modules/echo-cancel/adrian.c b/src/modules/echo-cancel/adrian.c
index ab3858a..91e3b35 100644
--- a/src/modules/echo-cancel/adrian.c
+++ b/src/modules/echo-cancel/adrian.c
@@ -57,9 +57,9 @@ static void pa_adrian_ec_fixate_spec(pa_sample_spec *source_ss, pa_channel_map *
 pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args)
+                           uint32_t *nframes, const char *args)
 {
-    int framelen, rate, have_vector = 0;
+    int rate, have_vector = 0;
     uint32_t frame_size_ms;
     pa_modargs *ma;
 
@@ -77,11 +77,10 @@ pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
     pa_adrian_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);
 
     rate = source_ss->rate;
-    framelen = (rate * frame_size_ms) / 1000;
+    *nframes = (rate * frame_size_ms) / 1000;
+    ec->params.priv.adrian.blocksize = (*nframes) * pa_frame_size(source_ss);
 
-    *blocksize = ec->params.priv.adrian.blocksize = framelen * pa_frame_size (source_ss);
-
-    pa_log_debug ("Using framelen %d, blocksize %u, channels %d, rate %d", framelen, ec->params.priv.adrian.blocksize, source_ss->channels, source_ss->rate);
+    pa_log_debug ("Using nframes %d, blocksize %u, channels %d, rate %d", *nframes, ec->params.priv.adrian.blocksize, source_ss->channels, source_ss->rate);
 
     /* For now we only support SSE */
     if (c->cpu_info.cpu_type == PA_CPU_X86 && (c->cpu_info.flags.x86 & PA_CPU_X86_SSE))
diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h
index 9ca78ff..9f14ade 100644
--- a/src/modules/echo-cancel/echo-cancel.h
+++ b/src/modules/echo-cancel/echo-cancel.h
@@ -86,7 +86,7 @@ struct pa_echo_canceller {
                                          pa_channel_map *source_map,
                                          pa_sample_spec *sink_ss,
                                          pa_channel_map *sink_map,
-                                         uint32_t *blocksize,
+                                         uint32_t *nframes,
                                          const char *args);
 
     /* You should have only one of play()+record() or run() set. The first
@@ -94,13 +94,13 @@ struct pa_echo_canceller {
      * samples yourself. If you set run(), module-echo-cancel will handle
      * synchronising the playback and record streams. */
 
-    /* Feed the engine 'blocksize' playback bytes.. */
+    /* Feed the engine 'nframes' playback frames. */
     void        (*play)                 (pa_echo_canceller *ec, const uint8_t *play);
-    /* Feed the engine 'blocksize' record bytes. blocksize processed bytes are
+    /* Feed the engine 'nframes' record frames. nframes processed frames are
      * returned in out. */
     void        (*record)               (pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out);
-    /* Feed the engine blocksize playback and record streams, with a reasonable
-     * effort at keeping the two in sync. blocksize processed bytes are
+    /* Feed the engine nframes playback and record frames, with a reasonable
+     * effort at keeping the two in sync. nframes processed frames are
      * returned in out. */
     void        (*run)                  (pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 
@@ -132,7 +132,7 @@ void pa_echo_canceller_set_capture_volume(pa_echo_canceller *ec, pa_cvolume *v);
 pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args);
+                           uint32_t *nframes, const char *args);
 void pa_null_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 void pa_null_ec_done(pa_echo_canceller *ec);
 
@@ -141,7 +141,7 @@ void pa_null_ec_done(pa_echo_canceller *ec);
 pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args);
+                           uint32_t *nframes, const char *args);
 void pa_speex_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 void pa_speex_ec_done(pa_echo_canceller *ec);
 #endif
@@ -151,7 +151,7 @@ void pa_speex_ec_done(pa_echo_canceller *ec);
 pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args);
+                           uint32_t *nframes, const char *args);
 void pa_adrian_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 void pa_adrian_ec_done(pa_echo_canceller *ec);
 #endif
@@ -162,7 +162,7 @@ PA_C_DECL_BEGIN
 pa_bool_t pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
                             pa_sample_spec *source_ss, pa_channel_map *source_map,
                             pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                            uint32_t *blocksize, const char *args);
+                            uint32_t *nframes, const char *args);
 void pa_webrtc_ec_play(pa_echo_canceller *ec, const uint8_t *play);
 void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out);
 void pa_webrtc_ec_set_drift(pa_echo_canceller *ec, float drift);
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 103aef0..11ad1de 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -211,7 +211,8 @@ struct userdata {
     pa_bool_t save_aec;
 
     pa_echo_canceller *ec;
-    uint32_t blocksize;
+    uint32_t source_blocksize;
+    uint32_t sink_blocksize;
 
     pa_bool_t need_realign;
 
@@ -417,7 +418,7 @@ static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t
                 /* Add the latency internal to our source output on top */
                 pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec) +
                 /* and the buffering we do on the source */
-                pa_bytes_to_usec(u->blocksize, &u->source_output->source->sample_spec);
+                pa_bytes_to_usec(u->source_blocksize, &u->source_output->source->sample_spec);
 
             return 0;
 
@@ -735,8 +736,8 @@ static void do_push_drift_comp(struct userdata *u) {
      * those remainder samples.
      */
     drift = ((float)(plen - u->sink_rem) - (rlen - u->source_rem)) / ((float)(rlen - u->source_rem));
-    u->sink_rem = plen % u->blocksize;
-    u->source_rem = rlen % u->blocksize;
+    u->sink_rem = plen % u->sink_blocksize;
+    u->source_rem = rlen % u->source_blocksize;
 
     /* Now let the canceller work its drift compensation magic */
     u->ec->set_drift(u->ec, drift);
@@ -747,8 +748,8 @@ static void do_push_drift_comp(struct userdata *u) {
     }
 
     /* Send in the playback samples first */
-    while (plen >= u->blocksize) {
-        pa_memblockq_peek_fixed_size(u->sink_memblockq, u->blocksize, &pchunk);
+    while (plen >= u->sink_blocksize) {
+        pa_memblockq_peek_fixed_size(u->sink_memblockq, u->sink_blocksize, &pchunk);
         pdata = pa_memblock_acquire(pchunk.memblock);
         pdata += pchunk.index;
 
@@ -756,27 +757,27 @@ static void do_push_drift_comp(struct userdata *u) {
 
         if (u->save_aec) {
             if (u->drift_file)
-                fprintf(u->drift_file, "p %d\n", u->blocksize);
+                fprintf(u->drift_file, "p %d\n", u->sink_blocksize);
             if (u->played_file)
-                unused = fwrite(pdata, 1, u->blocksize, u->played_file);
+                unused = fwrite(pdata, 1, u->sink_blocksize, u->played_file);
         }
 
         pa_memblock_release(pchunk.memblock);
-        pa_memblockq_drop(u->sink_memblockq, u->blocksize);
+        pa_memblockq_drop(u->sink_memblockq, u->sink_blocksize);
         pa_memblock_unref(pchunk.memblock);
 
-        plen -= u->blocksize;
+        plen -= u->sink_blocksize;
     }
 
     /* And now the capture samples */
-    while (rlen >= u->blocksize) {
-        pa_memblockq_peek_fixed_size(u->source_memblockq, u->blocksize, &rchunk);
+    while (rlen >= u->source_blocksize) {
+        pa_memblockq_peek_fixed_size(u->source_memblockq, u->source_blocksize, &rchunk);
 
         rdata = pa_memblock_acquire(rchunk.memblock);
         rdata += rchunk.index;
 
         cchunk.index = 0;
-        cchunk.length = u->blocksize;
+        cchunk.length = u->source_blocksize;
         cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
         cdata = pa_memblock_acquire(cchunk.memblock);
 
@@ -784,11 +785,11 @@ static void do_push_drift_comp(struct userdata *u) {
 
         if (u->save_aec) {
             if (u->drift_file)
-                fprintf(u->drift_file, "c %d\n", u->blocksize);
+                fprintf(u->drift_file, "c %d\n", u->source_blocksize);
             if (u->captured_file)
-                unused = fwrite(rdata, 1, u->blocksize, u->captured_file);
+                unused = fwrite(rdata, 1, u->source_blocksize, u->captured_file);
             if (u->canceled_file)
-                unused = fwrite(cdata, 1, u->blocksize, u->canceled_file);
+                unused = fwrite(cdata, 1, u->source_blocksize, u->canceled_file);
         }
 
         pa_memblock_release(cchunk.memblock);
@@ -799,8 +800,8 @@ static void do_push_drift_comp(struct userdata *u) {
         pa_source_post(u->source, &cchunk);
         pa_memblock_unref(cchunk.memblock);
 
-        pa_memblockq_drop(u->source_memblockq, u->blocksize);
-        rlen -= u->blocksize;
+        pa_memblockq_drop(u->source_memblockq, u->source_blocksize);
+        rlen -= u->source_blocksize;
     }
 }
 
@@ -818,13 +819,13 @@ static void do_push(struct userdata *u) {
     rlen = pa_memblockq_get_length(u->source_memblockq);
     plen = pa_memblockq_get_length(u->sink_memblockq);
 
-    while (rlen >= u->blocksize) {
+    while (rlen >= u->source_blocksize) {
         /* take fixed block from recorded samples */
-        pa_memblockq_peek_fixed_size(u->source_memblockq, u->blocksize, &rchunk);
+        pa_memblockq_peek_fixed_size(u->source_memblockq, u->source_blocksize, &rchunk);
 
-        if (plen >= u->blocksize) {
+        if (plen >= u->sink_blocksize) {
             /* take fixed block from played samples */
-            pa_memblockq_peek_fixed_size(u->sink_memblockq, u->blocksize, &pchunk);
+            pa_memblockq_peek_fixed_size(u->sink_memblockq, u->sink_blocksize, &pchunk);
 
             rdata = pa_memblock_acquire(rchunk.memblock);
             rdata += rchunk.index;
@@ -832,15 +833,15 @@ static void do_push(struct userdata *u) {
             pdata += pchunk.index;
 
             cchunk.index = 0;
-            cchunk.length = u->blocksize;
+            cchunk.length = u->source_blocksize;
             cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
             cdata = pa_memblock_acquire(cchunk.memblock);
 
             if (u->save_aec) {
                 if (u->captured_file)
-                    unused = fwrite(rdata, 1, u->blocksize, u->captured_file);
+                    unused = fwrite(rdata, 1, u->source_blocksize, u->captured_file);
                 if (u->played_file)
-                    unused = fwrite(pdata, 1, u->blocksize, u->played_file);
+                    unused = fwrite(pdata, 1, u->sink_blocksize, u->played_file);
             }
 
             /* perform echo cancellation */
@@ -848,7 +849,7 @@ static void do_push(struct userdata *u) {
 
             if (u->save_aec) {
                 if (u->canceled_file)
-                    unused = fwrite(cdata, 1, u->blocksize, u->canceled_file);
+                    unused = fwrite(cdata, 1, u->source_blocksize, u->canceled_file);
             }
 
             pa_memblock_release(cchunk.memblock);
@@ -856,7 +857,7 @@ static void do_push(struct userdata *u) {
             pa_memblock_release(rchunk.memblock);
 
             /* drop consumed sink samples */
-            pa_memblockq_drop(u->sink_memblockq, u->blocksize);
+            pa_memblockq_drop(u->sink_memblockq, u->sink_blocksize);
             pa_memblock_unref(pchunk.memblock);
 
             pa_memblock_unref(rchunk.memblock);
@@ -864,15 +865,15 @@ static void do_push(struct userdata *u) {
              * source */
             rchunk = cchunk;
 
-            plen -= u->blocksize;
+            plen -= u->sink_blocksize;
         }
 
         /* forward the (echo-canceled) data to the virtual source */
         pa_source_post(u->source, &rchunk);
         pa_memblock_unref(rchunk.memblock);
 
-        pa_memblockq_drop(u->source_memblockq, u->blocksize);
-        rlen -= u->blocksize;
+        pa_memblockq_drop(u->source_memblockq, u->source_blocksize);
+        rlen -= u->source_blocksize;
     }
 }
 
@@ -907,7 +908,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
     plen = pa_memblockq_get_length(u->sink_memblockq);
 
     /* Let's not do anything else till we have enough data to process */
-    if (rlen < u->blocksize)
+    if (rlen < u->source_blocksize)
         return;
 
     /* See if we need to drop samples in order to sync */
@@ -923,7 +924,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
          * means the only way to try to catch up is drop sink samples and let
          * the canceller cope up with this. */
         to_skip = rlen >= u->source_skip ? u->source_skip : rlen;
-        to_skip -= to_skip % u->blocksize;
+        to_skip -= to_skip % u->source_blocksize;
 
         if (to_skip) {
             pa_memblockq_peek_fixed_size(u->source_memblockq, to_skip, &rchunk);
@@ -936,9 +937,9 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
             u->source_skip -= to_skip;
         }
 
-        if (rlen && u->source_skip % u->blocksize) {
-            u->sink_skip += u->blocksize - (u->source_skip % u->blocksize);
-            u->source_skip -= (u->source_skip % u->blocksize);
+        if (rlen && u->source_skip % u->source_blocksize) {
+            u->sink_skip += (uint64_t) (u->source_blocksize - (u->source_skip % u->source_blocksize)) * u->sink_blocksize / u->source_blocksize;
+            u->source_skip -= (u->source_skip % u->source_blocksize);
         }
     }
 
@@ -1640,6 +1641,7 @@ int pa__init(pa_module*m) {
     pa_sink_new_data sink_data;
     pa_memchunk silence;
     uint32_t temp;
+    uint32_t nframes = 0;
 
     pa_assert(m);
 
@@ -1729,13 +1731,15 @@ int pa__init(pa_module*m) {
     u->asyncmsgq = pa_asyncmsgq_new(0);
     u->need_realign = TRUE;
 
-    if (u->ec->init) {
-        if (!u->ec->init(u->core, u->ec, &source_ss, &source_map, &sink_ss, &sink_map, &u->blocksize, pa_modargs_get_value(ma, "aec_args", NULL))) {
-            pa_log("Failed to init AEC engine");
-            goto fail;
-        }
+    pa_assert(u->ec->init);
+    if (!u->ec->init(u->core, u->ec, &source_ss, &source_map, &sink_ss, &sink_map, &nframes, pa_modargs_get_value(ma, "aec_args", NULL))) {
+        pa_log("Failed to init AEC engine");
+        goto fail;
     }
 
+    u->source_blocksize = nframes * pa_frame_size(&source_ss);
+    u->sink_blocksize = nframes * pa_frame_size(&sink_ss);
+
     if (u->ec->params.drift_compensation)
         pa_assert(u->ec->set_drift);
 
@@ -2071,6 +2075,7 @@ int main(int argc, char* argv[]) {
     int ret = 0, i;
     char c;
     float drift;
+    uint32_t nframes;
 
     pa_memzero(&u, sizeof(u));
 
@@ -2116,11 +2121,13 @@ int main(int argc, char* argv[]) {
     if (init_common(ma, &u, &source_ss, &source_map) < 0)
         goto fail;
 
-    if (!u.ec->init(u.core, u.ec, &source_ss, &source_map, &sink_ss, &sink_map, &u.blocksize,
+    if (!u.ec->init(u.core, u.ec, &source_ss, &source_map, &sink_ss, &sink_map, &nframes,
                      (argc > 5) ? argv[5] : NULL )) {
         pa_log("Failed to init AEC engine");
         goto fail;
     }
+    u.source_blocksize = nframes * pa_frame_size(&source_ss);
+    u.sink_blocksize = nframes * pa_frame_size(&sink_ss);
 
     if (u.ec->params.drift_compensation) {
         if (argc < 7) {
@@ -2136,20 +2143,20 @@ int main(int argc, char* argv[]) {
         }
     }
 
-    rdata = pa_xmalloc(u.blocksize);
-    pdata = pa_xmalloc(u.blocksize);
-    cdata = pa_xmalloc(u.blocksize);
+    rdata = pa_xmalloc(u.source_blocksize);
+    pdata = pa_xmalloc(u.sink_blocksize);
+    cdata = pa_xmalloc(u.source_blocksize);
 
     if (!u.ec->params.drift_compensation) {
-        while (fread(rdata, u.blocksize, 1, u.captured_file) > 0) {
-            if (fread(pdata, u.blocksize, 1, u.played_file) == 0) {
+        while (fread(rdata, u.source_blocksize, 1, u.captured_file) > 0) {
+            if (fread(pdata, u.sink_blocksize, 1, u.played_file) == 0) {
                 perror("Played file ended before captured file");
                 goto fail;
             }
 
             u.ec->run(u.ec, rdata, pdata, cdata);
 
-            unused = fwrite(cdata, u.blocksize, 1, u.canceled_file);
+            unused = fwrite(cdata, u.source_blocksize, 1, u.canceled_file);
         }
     } else {
         while (fscanf(u.drift_file, "%c", &c) > 0) {
diff --git a/src/modules/echo-cancel/null.c b/src/modules/echo-cancel/null.c
index 1820661..bfd6c30 100644
--- a/src/modules/echo-cancel/null.c
+++ b/src/modules/echo-cancel/null.c
@@ -28,8 +28,8 @@ PA_C_DECL_END
 pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args) {
-    unsigned framelen = 256;
+                           uint32_t *nframes, const char *args) {
+    *nframes = 256;
 
     source_ss->format = PA_SAMPLE_S16NE;
     source_ss->channels = 1;
@@ -37,14 +37,13 @@ pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec,
     *sink_ss = *source_ss;
     *sink_map = *source_map;
 
-    *blocksize = framelen * pa_frame_size(source_ss);
-
-    pa_log_debug("null AEC: framelen %u, blocksize %u, channels %d, rate %d", framelen, *blocksize, source_ss->channels, source_ss->rate);
+    pa_log_debug("null AEC: nframes %u, channels %d, rate %d", *nframes, source_ss->channels, source_ss->rate);
 
     return TRUE;
 }
 
 void pa_null_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
+    // blocksize is nframes * frame-size
     memcpy(out, rec, 256 * 2);
 }
 
diff --git a/src/modules/echo-cancel/speex.c b/src/modules/echo-cancel/speex.c
index d6331fc..5ebd0b3 100644
--- a/src/modules/echo-cancel/speex.c
+++ b/src/modules/echo-cancel/speex.c
@@ -58,7 +58,7 @@ static void pa_speex_ec_fixate_spec(pa_sample_spec *source_ss, pa_channel_map *s
     *sink_map = *source_map;
 }
 
-static pa_bool_t pa_speex_ec_preprocessor_init(pa_echo_canceller *ec, pa_sample_spec *source_ss, uint32_t blocksize, pa_modargs *ma) {
+static pa_bool_t pa_speex_ec_preprocessor_init(pa_echo_canceller *ec, pa_sample_spec *source_ss, uint32_t nframes, pa_modargs *ma) {
     pa_bool_t agc;
     pa_bool_t denoise;
     pa_bool_t echo_suppress;
@@ -111,7 +111,7 @@ static pa_bool_t pa_speex_ec_preprocessor_init(pa_echo_canceller *ec, pa_sample_
             goto fail;
         }
 
-        ec->params.priv.speex.pp_state = speex_preprocess_state_init(blocksize / pa_frame_size(source_ss), source_ss->rate);
+        ec->params.priv.speex.pp_state = speex_preprocess_state_init(nframes, source_ss->rate);
 
         tmp = agc;
         speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_AGC, &tmp);
@@ -148,10 +148,10 @@ fail:
 pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args)
+                           uint32_t *nframes, const char *args)
 {
-    int framelen, y, rate;
-    uint32_t frame_size_ms, filter_size_ms;
+    int rate;
+    uint32_t y, frame_size_ms, filter_size_ms;
     pa_modargs *ma;
 
     if (!(ma = pa_modargs_new(args, valid_modargs))) {
@@ -174,25 +174,23 @@ pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
     pa_speex_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);
 
     rate = source_ss->rate;
-    framelen = (rate * frame_size_ms) / 1000;
-    /* framelen should be a power of 2, round down to nearest power of two */
-    y = 1 << ((8 * sizeof (int)) - 2);
-    while (y > framelen)
+    *nframes = (rate * frame_size_ms) / 1000;
+    /* nframes should be a power of 2, round down to nearest power of two */
+    y = 1 << ((8 * sizeof (uint32_t)) - 2);
+    while (y > *nframes)
       y >>= 1;
-    framelen = y;
+    *nframes = y;
 
-    *blocksize = framelen * pa_frame_size (source_ss);
+    pa_log_debug ("Using nframes %d, channels %d, rate %d", *nframes, source_ss->channels, source_ss->rate);
 
-    pa_log_debug ("Using framelen %d, blocksize %u, channels %d, rate %d", framelen, *blocksize, source_ss->channels, source_ss->rate);
-
-    ec->params.priv.speex.state = speex_echo_state_init_mc (framelen, (rate * filter_size_ms) / 1000, source_ss->channels, source_ss->channels);
+    ec->params.priv.speex.state = speex_echo_state_init_mc (*nframes, (rate * filter_size_ms) / 1000, source_ss->channels, source_ss->channels);
 
     if (!ec->params.priv.speex.state)
         goto fail;
 
     speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);
 
-    if (!pa_speex_ec_preprocessor_init(ec, source_ss, *blocksize, ma))
+    if (!pa_speex_ec_preprocessor_init(ec, source_ss, *nframes, ma))
         goto fail;
 
     pa_modargs_free(ma);
diff --git a/src/modules/echo-cancel/webrtc.cc b/src/modules/echo-cancel/webrtc.cc
index 633b723..6ced28c 100644
--- a/src/modules/echo-cancel/webrtc.cc
+++ b/src/modules/echo-cancel/webrtc.cc
@@ -79,7 +79,7 @@ static int routing_mode_from_string(const char *rmode) {
 pa_bool_t pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
                             pa_sample_spec *source_ss, pa_channel_map *source_map,
                             pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                            uint32_t *blocksize, const char *args)
+                            uint32_t *nframes, const char *args)
 {
     webrtc::AudioProcessing *apm = NULL;
     pa_bool_t hpf, ns, agc, dgc, mobile, cn;
@@ -216,7 +216,8 @@ pa_bool_t pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
 
     ec->params.priv.webrtc.apm = apm;
     ec->params.priv.webrtc.sample_spec = *source_ss;
-    ec->params.priv.webrtc.blocksize = *blocksize = (uint64_t)pa_bytes_per_second(source_ss) * BLOCK_SIZE_US / PA_USEC_PER_SEC;
+    ec->params.priv.webrtc.blocksize = (uint64_t)pa_bytes_per_second(source_ss) * BLOCK_SIZE_US / PA_USEC_PER_SEC;
+    *nframes = ec->params.priv.webrtc.blocksize / pa_frame_size(source_ss);
 
     pa_modargs_free(ma);
     return TRUE;



More information about the pulseaudio-commits mailing list