]> code.delx.au - pulseaudio/commitdiff
echo-cancel: Pass arguments to the specific canceller module
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 6 Sep 2010 15:54:55 +0000 (21:24 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Tue, 7 Sep 2010 09:42:12 +0000 (15:12 +0530)
This allows us to tweak module parameters for whichever AEC module is
chosen.

src/modules/echo-cancel/echo-cancel.h
src/modules/echo-cancel/module-echo-cancel.c
src/modules/echo-cancel/speex.c

index bb6c0ed4cb421a6b274bda9f71e40aa65472f70d..186ce3273df581a5dd20d34d35c037aa648d04f2 100644 (file)
@@ -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);
index 2e724344d2f903f9776b54c25ca806398037ce08..d6968cd04a26538a29e55631627884c6df8e2608 100644 (file)
@@ -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;
         }
index 1b9e76f43ddb4f2efb761b70b8d4cf932db8f3a8..a8fcc86cbb2bebac8a35d7f707dc828d6510473b 100644 (file)
     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)