[pulseaudio-commits] 7 commits - src/.gitignore src/modules src/pulse src/pulsecore

Arun Raghavan arun at kemper.freedesktop.org
Thu Aug 25 06:19:37 PDT 2011


 src/.gitignore                               |    1 
 src/modules/dbus/iface-core.c                |    2 
 src/modules/dbus/iface-stream.c              |    2 
 src/modules/echo-cancel/adrian-aec.h         |   10 +-
 src/modules/echo-cancel/echo-cancel.h        |   13 +-
 src/modules/echo-cancel/module-echo-cancel.c |  108 ++----------------------
 src/modules/echo-cancel/speex.c              |  119 ++++++++++++++++++++++++++-
 src/pulse/gccmacro.h                         |    2 
 src/pulsecore/dbus-util.c                    |    2 
 src/pulsecore/sndfile-util.c                 |   22 +++-
 10 files changed, 158 insertions(+), 123 deletions(-)

New commits:
commit e04d592a473a9d36d5b1ba5981dab56c3c9d56db
Author: Maarten Bosmans <mkbosmans at gmail.com>
Date:   Wed Aug 24 20:08:08 2011 +0200

    sndfile-util: Check return value of sf_command for errors
    
    It's better to show a message what the error is,
    instead of just asserting that no errors happen in an external library call.

diff --git a/src/pulsecore/sndfile-util.c b/src/pulsecore/sndfile-util.c
index 67256c7..fe20486 100644
--- a/src/pulsecore/sndfile-util.c
+++ b/src/pulsecore/sndfile-util.c
@@ -34,12 +34,16 @@
 
 int pa_sndfile_read_sample_spec(SNDFILE *sf, pa_sample_spec *ss) {
     SF_INFO sfi;
+    int sf_errno;
 
     pa_assert(sf);
     pa_assert(ss);
 
     pa_zero(sfi);
-    pa_assert_se(sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)) == 0);
+    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
+        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
+        return -1;
+    }
 
     switch (sfi.format & SF_FORMAT_SUBMASK) {
 
@@ -175,6 +179,7 @@ int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {
     };
 
     SF_INFO sfi;
+    int sf_errno;
     int *channels;
     unsigned c;
 
@@ -182,12 +187,13 @@ int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {
     pa_assert(cm);
 
     pa_zero(sfi);
-    pa_assert_se(sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)) == 0);
+    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
+        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
+        return -1;
+    }
 
     channels = pa_xnew(int, sfi.channels);
-    if (!sf_command(sf, SFC_GET_CHANNEL_MAP_INFO,
-                    channels, sizeof(channels[0]) * sfi.channels)) {
-
+    if (!sf_command(sf, SFC_GET_CHANNEL_MAP_INFO, channels, sizeof(channels[0]) * sfi.channels)) {
         pa_xfree(channels);
         return -1;
     }
@@ -325,6 +331,7 @@ void pa_sndfile_init_proplist(SNDFILE *sf, pa_proplist *p) {
 
     SF_INFO sfi;
     SF_FORMAT_INFO fi;
+    int sf_errno;
     unsigned c;
 
     pa_assert(sf);
@@ -346,7 +353,10 @@ void pa_sndfile_init_proplist(SNDFILE *sf, pa_proplist *p) {
     }
 
     pa_zero(sfi);
-    pa_assert_se(sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)) == 0);
+    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
+        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
+        return;
+    }
 
     pa_zero(fi);
     fi.format = sfi.format;

commit 55fdb0162cdb8ff3874bf6a2057df681397e9995
Author: Maarten Bosmans <mkbosmans at gmail.com>
Date:   Wed Aug 24 20:08:07 2011 +0200

    Remove extra ; s where they are not allowed in strict C99

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 042ca3b..f2e3468 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -480,7 +480,7 @@ static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg,
     c->core->default_sample_spec.channels = n_channels;
 
     pa_dbus_send_empty_reply(conn, msg);
-};
+}
 
 static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_dbusiface_core *c = userdata;
diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c
index d9f1237..ecd0ff3 100644
--- a/src/modules/dbus/iface-stream.c
+++ b/src/modules/dbus/iface-stream.c
@@ -444,7 +444,7 @@ static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageI
     pa_sink_input_set_mute(s->sink_input, mute, TRUE);
 
     pa_dbus_send_empty_reply(conn, msg);
-};
+}
 
 static void handle_get_buffer_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_dbusiface_stream *s = userdata;
diff --git a/src/modules/echo-cancel/adrian-aec.h b/src/modules/echo-cancel/adrian-aec.h
index d024b3c..e733f83 100644
--- a/src/modules/echo-cancel/adrian-aec.h
+++ b/src/modules/echo-cancel/adrian-aec.h
@@ -123,7 +123,7 @@ static  REAL IIR_HP_highpass(IIR_HP *i, REAL in) {
     /* Highpass = Signal - Lowpass. Lowpass = Exponential Smoothing */
     i->x += a0 * (in - i->x);
     return in - i->x;
-  };
+  }
 
 typedef struct FIR_HP_300Hz FIR_HP_300Hz;
 
@@ -362,21 +362,21 @@ static  REAL AEC_nlms_pw(AEC *a, REAL d, REAL x_, float stepsize);
 
 PA_GCC_UNUSED static  float AEC_getambient(AEC *a) {
     return a->dfast;
-  };
+  }
 static  void AEC_setambient(AEC *a, float Min_xf) {
     a->dotp_xf_xf -= a->delta;  // subtract old delta
     a->delta = (NLMS_LEN-1) * Min_xf * Min_xf;
     a->dotp_xf_xf += a->delta;  // add new delta
-  };
+  }
 PA_GCC_UNUSED static  void AEC_setgain(AEC *a, float gain_) {
     a->gain = gain_;
-  };
+  }
 #if 0
   void AEC_openwdisplay(AEC *a);
 #endif
 PA_GCC_UNUSED static  void AEC_setaes(AEC *a, float aes_y2_) {
     a->aes_y2 = aes_y2_;
-  };
+  }
 
 #define _AEC_H
 #endif
diff --git a/src/pulse/gccmacro.h b/src/pulse/gccmacro.h
index fe16967..1e818ff 100644
--- a/src/pulse/gccmacro.h
+++ b/src/pulse/gccmacro.h
@@ -120,7 +120,7 @@
 #ifndef PA_GCC_WEAKREF
 #if defined(__GNUC__) && defined(__ELF__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 4))
 /** Macro for usage of GCC's weakref attribute */
-#define PA_GCC_WEAKREF(x) __attribute__((weakref(#x)));
+#define PA_GCC_WEAKREF(x) __attribute__((weakref(#x)))
 #endif
 #endif
 
diff --git a/src/pulsecore/dbus-util.c b/src/pulsecore/dbus-util.c
index 09ab071..b79b752 100644
--- a/src/pulsecore/dbus-util.c
+++ b/src/pulsecore/dbus-util.c
@@ -610,7 +610,7 @@ void pa_dbus_append_basic_array(DBusMessageIter *iter, int item_type, const void
         pa_assert_se(dbus_message_iter_append_basic(&array_iter, item_type, &((uint8_t*) array)[i * item_size]));
 
     pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
-};
+}
 
 void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data) {
     DBusMessageIter variant_iter;

commit 168254f3bf2a6db08176b5f451a1fc1d886d0f57
Author: Maarten Bosmans <mkbosmans at gmail.com>
Date:   Wed Aug 24 20:08:06 2011 +0200

    echo-cancel: Use stream index in debug message
    
    instead of the less useful stream pointer.

diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index fe39baa..62905bd 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1046,7 +1046,7 @@ static void source_output_attach_cb(pa_source_output *o) {
     pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
     pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
 
-    pa_log_debug("Source output %p attach", o);
+    pa_log_debug("Source output %d attach", o->index);
 
     pa_source_attach_within_thread(u->source);
 
@@ -1076,7 +1076,7 @@ static void sink_input_attach_cb(pa_sink_input *i) {
     pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
     pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
 
-    pa_log_debug("Sink input %p attach", i);
+    pa_log_debug("Sink input %d attach", i->index);
 
     u->rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
             i->sink->thread_info.rtpoll,
@@ -1098,7 +1098,7 @@ static void source_output_detach_cb(pa_source_output *o) {
     pa_source_detach_within_thread(u->source);
     pa_source_set_rtpoll(u->source, NULL);
 
-    pa_log_debug("Source output %p detach", o);
+    pa_log_debug("Source output %d detach", o->index);
 
     if (u->rtpoll_item_read) {
         pa_rtpoll_item_free(u->rtpoll_item_read);
@@ -1117,7 +1117,7 @@ static void sink_input_detach_cb(pa_sink_input *i) {
 
     pa_sink_set_rtpoll(u->sink, NULL);
 
-    pa_log_debug("Sink input %p detach", i);
+    pa_log_debug("Sink input %d detach", i->index);
 
     if (u->rtpoll_item_write) {
         pa_rtpoll_item_free(u->rtpoll_item_write);
@@ -1133,7 +1133,7 @@ static void source_output_state_change_cb(pa_source_output *o, pa_source_output_
     pa_source_output_assert_io_context(o);
     pa_assert_se(u = o->userdata);
 
-    pa_log_debug("Source output %p state %d", o, state);
+    pa_log_debug("Source output %d state %d", o->index, state);
 }
 
 /* Called from IO thread context */
@@ -1143,7 +1143,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
-    pa_log_debug("Sink input %p state %d", i, state);
+    pa_log_debug("Sink input %d state %d", i->index, state);
 
     /* If we are added for the first time, ask for a rewinding so that
      * we are heard right-away. */
@@ -1174,7 +1174,7 @@ static void source_output_kill_cb(pa_source_output *o) {
     pa_source_unref(u->source);
     u->source = NULL;
 
-    pa_log_debug("Source output kill %p", o);
+    pa_log_debug("Source output kill %d", o->index);
 
     pa_module_unload_request(u->module, TRUE);
 }
@@ -1198,7 +1198,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
     pa_sink_unref(u->sink);
     u->sink = NULL;
 
-    pa_log_debug("Sink input kill %p", i);
+    pa_log_debug("Sink input kill %d", i->index);
 
     pa_module_unload_request(u->module, TRUE);
 }

commit 35bafe06e70df256d1a3768d17ce155844312e27
Author: Maarten Bosmans <mkbosmans at gmail.com>
Date:   Wed Aug 24 20:08:05 2011 +0200

    gitignore: Add Orc autogenerated files

diff --git a/src/.gitignore b/src/.gitignore
index 072a75c..1e1822d 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -68,3 +68,4 @@ vector-test
 connect-stress
 extended-test
 format-test
+*-orc-gen.[ch]

commit 7dfb166dba0aaba2a3ee4b78b152d46966d3a38b
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Thu Aug 25 17:47:05 2011 +0530

    echo-cancel: Move speex preprocessing out of the main module
    
    I initially included put the Speex preprocessing assuming that we'd want
    to use the digital gain control and noise suppression from Speex for all
    echo cancelling implementations. In practice, we're probably going to
    get entire implementations all processing in one package (WebRTC, custom
    modules from various vendors, etc.).
    
    This moves out this preprocessing and related knobs into the speex
    implementation, which serves to clean out all implementation-specific
    details from the module-echo-cancel core.

diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h
index b2cf61d..9f67980 100644
--- a/src/modules/echo-cancel/echo-cancel.h
+++ b/src/modules/echo-cancel/echo-cancel.h
@@ -43,6 +43,7 @@ struct pa_echo_canceller_params {
     union {
         struct {
             SpeexEchoState *state;
+            SpeexPreprocessState *pp_state;
         } speex;
         struct {
             uint32_t blocksize;
@@ -67,13 +68,6 @@ struct pa_echo_canceller {
     void        (*done)                 (pa_echo_canceller *ec);
 
     pa_echo_canceller_params params;
-
-    pa_bool_t agc;
-    pa_bool_t denoise;
-    pa_bool_t echo_suppress;
-    int32_t echo_suppress_attenuation;
-    int32_t echo_suppress_attenuation_active;
-    SpeexPreprocessState *pp_state;
 };
 
 /* Speex canceller functions */
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 04e5b02..fe39baa 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -72,11 +72,6 @@ PA_MODULE_USAGE(
           "channel_map=<channel map> "
           "aec_method=<implementation to use> "
           "aec_args=<parameters for the AEC engine> "
-          "agc=<perform automagic gain control?> "
-          "denoise=<apply denoising?> "
-          "echo_suppress=<perform residual echo suppression? (only with the speex canceller)> "
-          "echo_suppress_attenuation=<dB value of residual echo attenuation> "
-          "echo_suppress_attenuation_active=<dB value of residual echo attenuation when near end is active> "
           "save_aec=<save AEC data in /tmp> "
           "autoloaded=<set if this module is being loaded automatically> "
         ));
@@ -108,10 +103,6 @@ static const pa_echo_canceller ec_table[] = {
 #define DEFAULT_RATE 32000
 #define DEFAULT_CHANNELS 1
 #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC)
-#define DEFAULT_AGC_ENABLED TRUE
-#define DEFAULT_DENOISE_ENABLED TRUE
-#define DEFAULT_ECHO_SUPPRESS_ENABLED TRUE
-#define DEFAULT_ECHO_SUPPRESS_ATTENUATION 0
 #define DEFAULT_SAVE_AEC 0
 #define DEFAULT_AUTOLOADED FALSE
 
@@ -218,11 +209,6 @@ static const char* const valid_modargs[] = {
     "channel_map",
     "aec_method",
     "aec_args",
-    "agc",
-    "denoise",
-    "echo_suppress",
-    "echo_suppress_attenuation",
-    "echo_suppress_attenuation_active",
     "save_aec",
     "autoloaded",
     NULL
@@ -727,10 +713,6 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
                 /* perform echo cancellation */
                 u->ec->run(u->ec, rdata, pdata, cdata);
 
-                /* preprecessor is run after AEC. This is not a mistake! */
-                if (u->ec->pp_state)
-                    speex_preprocess_run(u->ec->pp_state, (spx_int16_t *) cdata);
-
                 if (u->save_aec) {
                     if (u->canceled_file)
                         fwrite(cdata, 1, u->blocksize, u->canceled_file);
@@ -1407,48 +1389,6 @@ int pa__init(pa_module*m) {
     else
         u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
 
-    u->ec->agc = DEFAULT_AGC_ENABLED;
-    if (pa_modargs_get_value_boolean(ma, "agc", &u->ec->agc) < 0) {
-        pa_log("Failed to parse agc value");
-        goto fail;
-    }
-
-    u->ec->denoise = DEFAULT_DENOISE_ENABLED;
-    if (pa_modargs_get_value_boolean(ma, "denoise", &u->ec->denoise) < 0) {
-        pa_log("Failed to parse denoise value");
-        goto fail;
-    }
-
-    u->ec->echo_suppress = DEFAULT_ECHO_SUPPRESS_ENABLED;
-    if (pa_modargs_get_value_boolean(ma, "echo_suppress", &u->ec->echo_suppress) < 0) {
-        pa_log("Failed to parse echo_suppress value");
-        goto fail;
-    }
-    if (u->ec->echo_suppress && ec_method != PA_ECHO_CANCELLER_SPEEX) {
-        pa_log("Echo suppression is only useful with the speex canceller");
-        goto fail;
-    }
-
-    u->ec->echo_suppress_attenuation = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
-    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation", &u->ec->echo_suppress_attenuation) < 0) {
-        pa_log("Failed to parse echo_suppress_attenuation value");
-        goto fail;
-    }
-    if (u->ec->echo_suppress_attenuation > 0) {
-        pa_log("echo_suppress_attenuation should be a negative dB value");
-        goto fail;
-    }
-
-    u->ec->echo_suppress_attenuation_active = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
-    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation_active", &u->ec->echo_suppress_attenuation_active) < 0) {
-        pa_log("Failed to parse echo_suppress_attenuation_active value");
-        goto fail;
-    }
-    if (u->ec->echo_suppress_attenuation_active > 0) {
-        pa_log("echo_suppress_attenuation_active should be a negative dB value");
-        goto fail;
-    }
-
     u->save_aec = DEFAULT_SAVE_AEC;
     if (pa_modargs_get_value_u32(ma, "save_aec", &u->save_aec) < 0) {
         pa_log("Failed to parse save_aec value");
@@ -1470,31 +1410,6 @@ int pa__init(pa_module*m) {
         }
     }
 
-    if (u->ec->agc || u->ec->denoise || u->ec->echo_suppress) {
-        spx_int32_t tmp;
-
-        if (source_ss.channels != 1) {
-            pa_log("AGC, denoising and echo suppression only work with channels=1");
-            goto fail;
-        }
-
-        u->ec->pp_state = speex_preprocess_state_init(u->blocksize / pa_frame_size(&source_ss), source_ss.rate);
-
-        tmp = u->ec->agc;
-        speex_preprocess_ctl(u->ec->pp_state, SPEEX_PREPROCESS_SET_AGC, &tmp);
-        tmp = u->ec->denoise;
-        speex_preprocess_ctl(u->ec->pp_state, SPEEX_PREPROCESS_SET_DENOISE, &tmp);
-        if (u->ec->echo_suppress) {
-            if (u->ec->echo_suppress_attenuation)
-                speex_preprocess_ctl(u->ec->pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &u->ec->echo_suppress_attenuation);
-            if (u->ec->echo_suppress_attenuation_active) {
-                speex_preprocess_ctl(u->ec->pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE,
-                                     &u->ec->echo_suppress_attenuation_active);
-            }
-            speex_preprocess_ctl(u->ec->pp_state, SPEEX_PREPROCESS_SET_ECHO_STATE, u->ec->params.priv.speex.state);
-        }
-    }
-
     /* Create source */
     pa_source_new_data_init(&source_data);
     source_data.driver = __FILE__;
@@ -1765,9 +1680,6 @@ void pa__done(pa_module*m) {
     if (u->sink_memblockq)
         pa_memblockq_free(u->sink_memblockq);
 
-    if (u->ec->pp_state)
-        speex_preprocess_state_destroy(u->ec->pp_state);
-
     if (u->ec) {
         if (u->ec->done)
             u->ec->done(u->ec);
diff --git a/src/modules/echo-cancel/speex.c b/src/modules/echo-cancel/speex.c
index 72c5268..d6331fc 100644
--- a/src/modules/echo-cancel/speex.c
+++ b/src/modules/echo-cancel/speex.c
@@ -25,6 +25,7 @@
 #include <config.h>
 #endif
 
+#include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include "echo-cancel.h"
 
@@ -32,10 +33,19 @@
 #define DEFAULT_FRAME_SIZE_MS 20
 /* should be between 100-500 ms */
 #define DEFAULT_FILTER_SIZE_MS 200
+#define DEFAULT_AGC_ENABLED TRUE
+#define DEFAULT_DENOISE_ENABLED TRUE
+#define DEFAULT_ECHO_SUPPRESS_ENABLED TRUE
+#define DEFAULT_ECHO_SUPPRESS_ATTENUATION 0
 
 static const char* const valid_modargs[] = {
     "frame_size_ms",
     "filter_size_ms",
+    "agc",
+    "denoise",
+    "echo_suppress",
+    "echo_suppress_attenuation",
+    "echo_suppress_attenuation_active",
     NULL
 };
 
@@ -48,6 +58,93 @@ static void pa_speex_ec_fixate_spec(pa_sample_spec *source_ss, pa_channel_map *s
     *sink_map = *source_map;
 }
 
+static pa_bool_t pa_speex_ec_preprocessor_init(pa_echo_canceller *ec, pa_sample_spec *source_ss, uint32_t blocksize, pa_modargs *ma) {
+    pa_bool_t agc;
+    pa_bool_t denoise;
+    pa_bool_t echo_suppress;
+    int32_t echo_suppress_attenuation;
+    int32_t echo_suppress_attenuation_active;
+
+    agc = DEFAULT_AGC_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "agc", &agc) < 0) {
+        pa_log("Failed to parse agc value");
+        goto fail;
+    }
+
+    denoise = DEFAULT_DENOISE_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "denoise", &denoise) < 0) {
+        pa_log("Failed to parse denoise value");
+        goto fail;
+    }
+
+    echo_suppress = DEFAULT_ECHO_SUPPRESS_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "echo_suppress", &echo_suppress) < 0) {
+        pa_log("Failed to parse echo_suppress value");
+        goto fail;
+    }
+
+    echo_suppress_attenuation = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
+    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation", &echo_suppress_attenuation) < 0) {
+        pa_log("Failed to parse echo_suppress_attenuation value");
+        goto fail;
+    }
+    if (echo_suppress_attenuation > 0) {
+        pa_log("echo_suppress_attenuation should be a negative dB value");
+        goto fail;
+    }
+
+    echo_suppress_attenuation_active = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
+    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation_active", &echo_suppress_attenuation_active) < 0) {
+        pa_log("Failed to parse echo_suppress_attenuation_active value");
+        goto fail;
+    }
+    if (echo_suppress_attenuation_active > 0) {
+        pa_log("echo_suppress_attenuation_active should be a negative dB value");
+        goto fail;
+    }
+
+    if (agc || denoise || echo_suppress) {
+        spx_int32_t tmp;
+
+        if (source_ss->channels != 1) {
+            pa_log("AGC, denoising and echo suppression only work with channels=1");
+            goto fail;
+        }
+
+        ec->params.priv.speex.pp_state = speex_preprocess_state_init(blocksize / pa_frame_size(source_ss), source_ss->rate);
+
+        tmp = agc;
+        speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_AGC, &tmp);
+
+        tmp = denoise;
+        speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_DENOISE, &tmp);
+
+        if (echo_suppress) {
+            if (echo_suppress_attenuation)
+                speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS,
+                                     &echo_suppress_attenuation);
+
+            if (echo_suppress_attenuation_active) {
+                speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE,
+                                     &echo_suppress_attenuation_active);
+            }
+
+            speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_STATE,
+                                 ec->params.priv.speex.state);
+        }
+
+        pa_log_info("Loaded speex preprocessor with params: agc=%s, denoise=%s, echo_suppress=%s", pa_yes_no(agc),
+                    pa_yes_no(denoise), pa_yes_no(echo_suppress));
+    } else
+        pa_log_info("All preprocessing options are disabled");
+
+    return TRUE;
+
+fail:
+    return FALSE;
+}
+
+
 pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
                            pa_sample_spec *source_ss, pa_channel_map *source_map,
                            pa_sample_spec *sink_ss, pa_channel_map *sink_map,
@@ -95,21 +192,37 @@ pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
 
     speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);
 
+    if (!pa_speex_ec_preprocessor_init(ec, source_ss, *blocksize, ma))
+        goto fail;
+
     pa_modargs_free(ma);
     return TRUE;
 
 fail:
     if (ma)
         pa_modargs_free(ma);
+    if (ec->params.priv.speex.state)
+        speex_preprocess_state_destroy(ec->params.priv.speex.pp_state);
     return FALSE;
 }
 
 void pa_speex_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
-    speex_echo_cancellation(ec->params.priv.speex.state, (const spx_int16_t *) rec, (const spx_int16_t *) play, (spx_int16_t *) out);
+    speex_echo_cancellation(ec->params.priv.speex.state, (const spx_int16_t *) rec, (const spx_int16_t *) play,
+                            (spx_int16_t *) out);
+
+    /* preprecessor is run after AEC. This is not a mistake! */
+    if (ec->params.priv.speex.pp_state)
+        speex_preprocess_run(ec->params.priv.speex.pp_state, (spx_int16_t *) out);
 }
 
 void pa_speex_ec_done(pa_echo_canceller *ec) {
-    if (ec->params.priv.speex.state)
+    if (ec->params.priv.speex.pp_state) {
+        speex_preprocess_state_destroy(ec->params.priv.speex.pp_state);
+        ec->params.priv.speex.pp_state = NULL;
+    }
+
+    if (ec->params.priv.speex.state) {
         speex_echo_state_destroy(ec->params.priv.speex.state);
-    ec->params.priv.speex.state = NULL;
+        ec->params.priv.speex.state = NULL;
+    }
 }

commit af6229cbe1c0040701095eced39729c72da9c125
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Wed Aug 24 10:35:09 2011 +0530

    echo-cancel: Use pa_streq instead of strcmp

diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 65fdcf9..04e5b02 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1318,9 +1318,9 @@ static void sink_input_mute_changed_cb(pa_sink_input *i) {
 }
 
 static pa_echo_canceller_method_t get_ec_method_from_string(const char *method) {
-    if (strcmp(method, "speex") == 0)
+    if (pa_streq(method, "speex"))
         return PA_ECHO_CANCELLER_SPEEX;
-    else if (strcmp(method, "adrian") == 0)
+    else if (pa_streq(method, "adrian"))
         return PA_ECHO_CANCELLER_ADRIAN;
     else
         return PA_ECHO_CANCELLER_INVALID;

commit ba69d66c33d83a3b794166feb47d446df1b002a9
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Wed Aug 24 10:34:19 2011 +0530

    echo-cancel: Add multiple include protection for header

diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h
index aa40adc..b2cf61d 100644
--- a/src/modules/echo-cancel/echo-cancel.h
+++ b/src/modules/echo-cancel/echo-cancel.h
@@ -19,6 +19,9 @@
     USA.
 ***/
 
+#ifndef fooechocancelhfoo
+#define fooechocancelhfoo
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -88,3 +91,5 @@ pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
                            uint32_t *blocksize, const char *args);
 void pa_adrian_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 void pa_adrian_ec_done(pa_echo_canceller *ec);
+
+#endif /* fooechocancelhfoo */



More information about the pulseaudio-commits mailing list