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 <p.meerwald@bct-electronic.com>
This commit is contained in:
Peter Meerwald 2013-02-13 17:26:51 +01:00 committed by Tanu Kaskinen
parent e845c86c64
commit db7415b7e9
3 changed files with 22 additions and 9 deletions

View file

@ -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_get_capture_volume(pa_echo_canceller *ec, pa_cvolume *v);
void pa_echo_canceller_set_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 */ /* Null canceller functions */
pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec, 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 *source_ss, pa_channel_map *source_map,

View file

@ -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) { static pa_echo_canceller_method_t get_ec_method_from_string(const char *method) {
if (pa_streq(method, "null")) if (pa_streq(method, "null"))
return PA_ECHO_CANCELLER_NULL; return PA_ECHO_CANCELLER_NULL;

View file

@ -151,7 +151,7 @@ pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
uint32_t *nframes, const char *args) uint32_t *nframes, const char *args)
{ {
int rate; int rate;
uint32_t y, frame_size_ms, filter_size_ms; uint32_t frame_size_ms, filter_size_ms;
pa_modargs *ma; pa_modargs *ma;
if (!(ma = pa_modargs_new(args, valid_modargs))) { 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); pa_speex_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);
rate = source_ss->rate; rate = source_ss->rate;
*nframes = (rate * frame_size_ms) / 1000; *nframes = pa_echo_canceller_blocksize_power2(rate, frame_size_ms);
/* 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;
pa_log_debug ("Using nframes %d, channels %d, rate %d", *nframes, source_ss->channels, source_ss->rate); 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) if (!ec->params.priv.speex.state)
goto fail; goto fail;