From: Peter Meerwald <p.meerwald@xxxxxxxxxxxxxxxxxx> computes EC block size in frames (rounded down to nearest power-of-2) based on sample rate and milliseconds move code from speex AEC implementation to module-echo-cancel such that functionality can be reused by other AEC implementations Signed-off-by: Peter Meerwald <p.meerwald at bct-electronic.com> --- src/modules/echo-cancel/echo-cancel.h | 4 ++++ src/modules/echo-cancel/module-echo-cancel.c | 15 +++++++++++++++ src/modules/echo-cancel/speex.c | 11 +++-------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h index d9929df..7f333b8 100644 --- a/src/modules/echo-cancel/echo-cancel.h +++ b/src/modules/echo-cancel/echo-cancel.h @@ -152,6 +152,10 @@ struct pa_echo_canceller { void pa_echo_canceller_get_capture_volume(pa_echo_canceller *ec, pa_cvolume *v); void pa_echo_canceller_set_capture_volume(pa_echo_canceller *ec, pa_cvolume *v); +/* Computes EC block size in frames (rounded down to nearest power-of-2) based + * on sample rate and milliseconds. */ +uint32_t pa_echo_canceller_blocksize_power2(unsigned rate, unsigned ms); + /* Null canceller functions */ pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec, pa_sample_spec *rec_ss, pa_channel_map *rec_map, diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index f550245..b0dcbf0 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -1605,6 +1605,21 @@ void pa_echo_canceller_set_capture_volume(pa_echo_canceller *ec, pa_cvolume *v) } } +uint32_t pa_echo_canceller_blocksize_power2(unsigned rate, unsigned ms) { + unsigned nframes = (rate * ms) / 1000; + uint32_t y = 1 << ((8 * sizeof(uint32_t)) - 2); + + assert(rate >= 4000); + assert(ms >= 1); + + /* nframes should be a power of 2, round down to nearest power of two */ + while (y > nframes) + y >>= 1; + + assert(y >= 1); + return y; +} + static pa_echo_canceller_method_t get_ec_method_from_string(const char *method) { if (pa_streq(method, "null")) return PA_ECHO_CANCELLER_NULL; diff --git a/src/modules/echo-cancel/speex.c b/src/modules/echo-cancel/speex.c index 5bb4a77..dcaf2ad 100644 --- a/src/modules/echo-cancel/speex.c +++ b/src/modules/echo-cancel/speex.c @@ -155,7 +155,7 @@ pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec, uint32_t *nframes, const char *args) { int rate; - uint32_t y, frame_size_ms, filter_size_ms; + uint32_t frame_size_ms, filter_size_ms; pa_modargs *ma; if (!(ma = pa_modargs_new(args, valid_modargs))) { @@ -178,16 +178,11 @@ pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec, pa_speex_ec_fixate_spec(rec_ss, rec_map, play_ss, play_map, out_ss, out_map); rate = out_ss->rate; - *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; - *nframes = y; + *nframes = pa_echo_canceller_blocksize_power2(rate, frame_size_ms); pa_log_debug ("Using nframes %d, channels %d, rate %d", *nframes, out_ss->channels, out_ss->rate); - ec->params.priv.speex.state = speex_echo_state_init_mc (*nframes, (rate * filter_size_ms) / 1000, out_ss->channels, out_ss->channels); + ec->params.priv.speex.state = speex_echo_state_init_mc(*nframes, (rate * filter_size_ms) / 1000, out_ss->channels, out_ss->channels); if (!ec->params.priv.speex.state) goto fail; -- 1.7.9.5