diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/echo-cancel/echo-cancel.h | 4 | ||||
-rw-r--r-- | src/modules/echo-cancel/module-echo-cancel.c | 28 | ||||
-rw-r--r-- | src/modules/echo-cancel/speex.c | 54 |
3 files changed, 53 insertions, 33 deletions
diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h index bb6c0ed4..186ce327 100644 --- a/src/modules/echo-cancel/echo-cancel.h +++ b/src/modules/echo-cancel/echo-cancel.h @@ -46,7 +46,7 @@ struct pa_echo_canceller_params { typedef struct pa_echo_canceller pa_echo_canceller; struct pa_echo_canceller { - pa_bool_t (*init) (pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, uint32_t filter_size_ms, uint32_t frame_size_ms); + pa_bool_t (*init) (pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, const char *args); void (*run) (pa_echo_canceller *ec, uint8_t *rec, uint8_t *play, uint8_t *out); void (*done) (pa_echo_canceller *ec); uint32_t (*get_block_size) (pa_echo_canceller *ec); @@ -55,7 +55,7 @@ struct pa_echo_canceller { }; /* Speex canceller functions */ -pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, uint32_t filter_size_ms, uint32_t frame_size_ms); +pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, const char *args); void pa_speex_ec_run(pa_echo_canceller *ec, uint8_t *rec, uint8_t *play, uint8_t *out); void pa_speex_ec_done(pa_echo_canceller *ec); uint32_t pa_speex_ec_get_block_size(pa_echo_canceller *ec); diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index 2e724344..d6968cd0 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -70,13 +70,12 @@ PA_MODULE_USAGE( "sink_name=<name for the sink> " "sink_properties=<properties for the sink> " "sink_master=<name of sink to filter> " - "frame_size_ms=<amount of data to process at one time> " - "filter_size_ms=<amount of echo to cancel> " "adjust_time=<how often to readjust rates in s> " "format=<sample format> " "rate=<sample rate> " "channels=<number of channels> " "channel_map=<channel map> " + "aec_args=<parameters for the AEC engine> " "save_aec=<save AEC data in /tmp> " )); @@ -97,11 +96,6 @@ static const pa_echo_canceller ec_table[] = { }, }; -/* should be between 10-20 ms */ -#define DEFAULT_FRAME_SIZE_MS 20 -/* should be between 100-500 ms */ -#define DEFAULT_FILTER_SIZE_MS 200 - #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC) #define DEFAULT_SAVE_AEC 0 @@ -154,7 +148,6 @@ struct userdata { pa_core *core; pa_module *module; - uint32_t frame_size_ms; uint32_t save_aec; pa_echo_canceller *ec; @@ -199,13 +192,12 @@ static const char* const valid_modargs[] = { "sink_name", "sink_properties", "sink_master", - "frame_size_ms", - "filter_size_ms", "adjust_time", "format", "rate", "channels", "channel_map", + "aec_args", "save_aec", NULL }; @@ -1287,7 +1279,6 @@ int pa__init(pa_module*m) { pa_source_new_data source_data; pa_sink_new_data sink_data; pa_memchunk silence; - uint32_t frame_size_ms, filter_size_ms; uint32_t adjust_time_sec; pa_assert(m); @@ -1309,18 +1300,6 @@ int pa__init(pa_module*m) { } pa_assert(sink_master); - frame_size_ms = DEFAULT_FRAME_SIZE_MS; - if (pa_modargs_get_value_u32(ma, "frame_size_ms", &frame_size_ms) < 0 || frame_size_ms < 1 || frame_size_ms > 200) { - pa_log("Invalid frame_size_ms specification"); - goto fail; - } - - filter_size_ms = DEFAULT_FILTER_SIZE_MS; - if (pa_modargs_get_value_u32(ma, "filter_size_ms", &filter_size_ms) < 0 || filter_size_ms < 1 || filter_size_ms > 2000) { - pa_log("Invalid filter_size_ms specification"); - goto fail; - } - ss = source_master->sample_spec; ss.format = PA_SAMPLE_S16LE; map = source_master->channel_map; @@ -1337,7 +1316,6 @@ int pa__init(pa_module*m) { u->core = m->core; u->module = m; m->userdata = u; - u->frame_size_ms = frame_size_ms; u->ec = pa_xnew0(pa_echo_canceller, 1); if (!u->ec) { @@ -1369,7 +1347,7 @@ 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->ec, ss, map, filter_size_ms, frame_size_ms)) { + if (!u->ec->init(u->ec, ss, map, pa_modargs_get_value(ma, "aec_args", NULL))) { pa_log("Failed to init AEC engine"); goto fail; } diff --git a/src/modules/echo-cancel/speex.c b/src/modules/echo-cancel/speex.c index 1b9e76f4..a8fcc86c 100644 --- a/src/modules/echo-cancel/speex.c +++ b/src/modules/echo-cancel/speex.c @@ -21,11 +21,46 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pulsecore/modargs.h> #include "echo-cancel.h" -pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, uint32_t filter_size_ms, uint32_t frame_size_ms) +/* should be between 10-20 ms */ +#define DEFAULT_FRAME_SIZE_MS 20 +/* should be between 100-500 ms */ +#define DEFAULT_FILTER_SIZE_MS 200 + +static const char* const valid_modargs[] = { + "frame_size_ms", + "filter_size_ms", + NULL +}; + +pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, const char *args) { int framelen, y, rate = ss.rate; + uint32_t frame_size_ms, filter_size_ms; + pa_modargs *ma; + + if (!(ma = pa_modargs_new(args, valid_modargs))) { + pa_log("Failed to parse submodule arguments."); + goto fail; + } + + filter_size_ms = DEFAULT_FILTER_SIZE_MS; + if (pa_modargs_get_value_u32(ma, "filter_size_ms", &filter_size_ms) < 0 || filter_size_ms < 1 || filter_size_ms > 2000) { + pa_log("Invalid filter_size_ms specification"); + goto fail; + } + + frame_size_ms = DEFAULT_FRAME_SIZE_MS; + if (pa_modargs_get_value_u32(ma, "frame_size_ms", &frame_size_ms) < 0 || frame_size_ms < 1 || frame_size_ms > 200) { + pa_log("Invalid frame_size_ms specification"); + goto fail; + } framelen = (rate * frame_size_ms) / 1000; /* framelen should be a power of 2, round down to nearest power of two */ @@ -40,11 +75,18 @@ pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_ ec->params.priv.speex.state = speex_echo_state_init_mc (framelen, (rate * filter_size_ms) / 1000, ss.channels, ss.channels); - if (ec->params.priv.speex.state) { - speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate); - return TRUE; - } else - return FALSE; + if (!ec->params.priv.speex.state) + goto fail; + + speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate); + + pa_modargs_free(ma); + return TRUE; + +fail: + if (ma) + pa_modargs_free(ma); + return FALSE; } void pa_speex_ec_run(pa_echo_canceller *ec, uint8_t *rec, uint8_t *play, uint8_t *out) |