summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/modules/echo-cancel/echo-cancel.h4
-rw-r--r--src/modules/echo-cancel/module-echo-cancel.c28
-rw-r--r--src/modules/echo-cancel/speex.c54
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)