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) | 
