diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/modules/echo-cancel/echo-cancel.h | 12 | ||||
| -rw-r--r-- | src/modules/echo-cancel/module-echo-cancel.c | 36 | ||||
| -rw-r--r-- | src/modules/echo-cancel/speex.c | 25 | 
3 files changed, 49 insertions, 24 deletions
| diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h index 186ce327..205c4d14 100644 --- a/src/modules/echo-cancel/echo-cancel.h +++ b/src/modules/echo-cancel/echo-cancel.h @@ -46,7 +46,12 @@ 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, const char *args); +    pa_bool_t   (*init)                 (pa_echo_canceller *ec, +                                         pa_sample_spec *source_ss, +                                         pa_channel_map *source_map, +                                         pa_sample_spec *sink_ss, +                                         pa_channel_map *sink_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 +60,10 @@ 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, const char *args); +pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, +                           pa_sample_spec *source_ss, pa_channel_map *source_map, +                           pa_sample_spec *sink_ss, pa_channel_map *sink_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 d6968cd0..6a88167b 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -1269,8 +1269,8 @@ static void sink_input_mute_changed_cb(pa_sink_input *i) {  int pa__init(pa_module*m) {      struct userdata *u; -    pa_sample_spec ss; -    pa_channel_map map; +    pa_sample_spec source_ss, sink_ss; +    pa_channel_map source_map, sink_map;      pa_modargs *ma;      pa_source *source_master=NULL;      pa_sink *sink_master=NULL; @@ -1300,14 +1300,16 @@ int pa__init(pa_module*m) {      }      pa_assert(sink_master); -    ss = source_master->sample_spec; -    ss.format = PA_SAMPLE_S16LE; -    map = source_master->channel_map; -    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { +    source_ss = source_master->sample_spec; +    source_map = source_master->channel_map; +    if (pa_modargs_get_sample_spec_and_channel_map(ma, &source_ss, &source_map, PA_CHANNEL_MAP_DEFAULT) < 0) {          pa_log("Invalid sample format specification or channel map");          goto fail;      } +    sink_ss = sink_master->sample_spec; +    sink_map = sink_master->channel_map; +      u = pa_xnew0(struct userdata, 1);      if (!u) {          pa_log("Failed to alloc userdata"); @@ -1347,7 +1349,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, pa_modargs_get_value(ma, "aec_args", NULL))) { +        if (!u->ec->init(u->ec, &source_ss, &source_map, &sink_ss, &sink_map, pa_modargs_get_value(ma, "aec_args", NULL))) {              pa_log("Failed to init AEC engine");              goto fail;          } @@ -1359,8 +1361,8 @@ int pa__init(pa_module*m) {      source_data.module = m;      if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))          source_data.name = pa_sprintf_malloc("%s.echo-cancel", source_master->name); -    pa_source_new_data_set_sample_spec(&source_data, &ss); -    pa_source_new_data_set_channel_map(&source_data, &map); +    pa_source_new_data_set_sample_spec(&source_data, &source_ss); +    pa_source_new_data_set_channel_map(&source_data, &source_map);      pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, source_master->name);      pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");      pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone"); @@ -1406,8 +1408,8 @@ int pa__init(pa_module*m) {      sink_data.module = m;      if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))          sink_data.name = pa_sprintf_malloc("%s.echo-cancel", sink_master->name); -    pa_sink_new_data_set_sample_spec(&sink_data, &ss); -    pa_sink_new_data_set_channel_map(&sink_data, &map); +    pa_sink_new_data_set_sample_spec(&sink_data, &sink_ss); +    pa_sink_new_data_set_channel_map(&sink_data, &sink_map);      pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, sink_master->name);      pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");      pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone"); @@ -1456,8 +1458,8 @@ int pa__init(pa_module*m) {      pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Source Stream");      pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); -    pa_source_output_new_data_set_sample_spec(&source_output_data, &ss); -    pa_source_output_new_data_set_channel_map(&source_output_data, &map); +    pa_source_output_new_data_set_sample_spec(&source_output_data, &source_ss); +    pa_source_output_new_data_set_channel_map(&source_output_data, &source_map);      pa_source_output_new(&u->source_output, m->core, &source_output_data);      pa_source_output_new_data_done(&source_output_data); @@ -1487,8 +1489,8 @@ int pa__init(pa_module*m) {      sink_input_data.sink = sink_master;      pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream");      pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); -    pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); -    pa_sink_input_new_data_set_channel_map(&sink_input_data, &map); +    pa_sink_input_new_data_set_sample_spec(&sink_input_data, &sink_ss); +    pa_sink_input_new_data_set_channel_map(&sink_input_data, &sink_map);      sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE;      pa_sink_input_new(&u->sink_input, m->core, &sink_input_data); @@ -1518,9 +1520,9 @@ int pa__init(pa_module*m) {      pa_sink_input_get_silence(u->sink_input, &silence);      u->source_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, -        pa_frame_size(&ss), 1, 1, 0, &silence); +        pa_frame_size(&source_ss), 1, 1, 0, &silence);      u->sink_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, -        pa_frame_size(&ss), 1, 1, 0, &silence); +        pa_frame_size(&sink_ss), 1, 1, 0, &silence);      pa_memblock_unref(silence.memblock); diff --git a/src/modules/echo-cancel/speex.c b/src/modules/echo-cancel/speex.c index a8fcc86c..cb8212e1 100644 --- a/src/modules/echo-cancel/speex.c +++ b/src/modules/echo-cancel/speex.c @@ -39,9 +39,21 @@ static const char* const valid_modargs[] = {      NULL  }; -pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_map map, const char *args) +static void pa_speex_ec_fixate_spec(pa_sample_spec *source_ss, pa_channel_map *source_map, +				    pa_sample_spec *sink_ss, pa_channel_map *sink_map)  { -    int framelen, y, rate = ss.rate; +    source_ss->format = PA_SAMPLE_S16LE; + +    *sink_ss = *source_ss; +    *sink_map = *source_map; +} + +pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, +                           pa_sample_spec *source_ss, pa_channel_map *source_map, +                           pa_sample_spec *sink_ss, pa_channel_map *sink_map, +                           const char *args) +{ +    int framelen, y, rate;      uint32_t frame_size_ms, filter_size_ms;      pa_modargs *ma; @@ -62,6 +74,9 @@ pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_          goto fail;      } +    pa_speex_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map); + +    rate = source_ss->rate;      framelen = (rate * frame_size_ms) / 1000;      /* framelen should be a power of 2, round down to nearest power of two */      y = 1 << ((8 * sizeof (int)) - 2); @@ -69,11 +84,11 @@ pa_bool_t pa_speex_ec_init(pa_echo_canceller *ec, pa_sample_spec ss, pa_channel_        y >>= 1;      framelen = y; -    ec->params.priv.speex.blocksize = framelen * pa_frame_size (&ss); +    ec->params.priv.speex.blocksize = framelen * pa_frame_size (source_ss); -    pa_log_debug ("Using framelen %d, blocksize %lld, channels %d, rate %d", framelen, (long long) ec->params.priv.speex.blocksize, ss.channels, ss.rate); +    pa_log_debug ("Using framelen %d, blocksize %lld, channels %d, rate %d", framelen, (long long) ec->params.priv.speex.blocksize, source_ss->channels, source_ss->rate); -    ec->params.priv.speex.state = speex_echo_state_init_mc (framelen, (rate * filter_size_ms) / 1000, ss.channels, ss.channels); +    ec->params.priv.speex.state = speex_echo_state_init_mc (framelen, (rate * filter_size_ms) / 1000, source_ss->channels, source_ss->channels);      if (!ec->params.priv.speex.state)  	goto fail; | 
