From db7415b7e958d2180db6385c76d5dea5ccbbe156 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 13 Feb 2013 17:26:51 +0100 Subject: [PATCH] echo-cancel: Add function pa_echo_canceller_blocksize_power2() 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 --- src/modules/echo-cancel/echo-cancel.h | 4 ++++ src/modules/echo-cancel/module-echo-cancel.c | 15 +++++++++++++++ src/modules/echo-cancel/speex.c | 12 +++--------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h index e7eed30..c33b1ef 100644 --- a/src/modules/echo-cancel/echo-cancel.h +++ b/src/modules/echo-cancel/echo-cancel.h @@ -131,6 +131,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 *source_ss, pa_channel_map *source_map, diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index 11ad1de..4a36bb0 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -1569,6 +1569,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 6c532f2..9469092 100644 --- a/src/modules/echo-cancel/speex.c +++ b/src/modules/echo-cancel/speex.c @@ -151,7 +151,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))) { @@ -174,16 +174,10 @@ 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; - *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, source_ss->channels, source_ss->rate); - - ec->params.priv.speex.state = speex_echo_state_init_mc (*nframes, (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; -- 2.7.4