[pulseaudio-discuss] [PATCH v2 10/25] echo-cancel: Deal with volume limit breakage in webrtc AGC

arun at accosted.net arun at accosted.net
Tue Dec 15 19:39:56 PST 2015


From: Arun Raghavan <git at arunraghavan.net>

The AGC code no longer seems to honour the analog volume limits we set,
and internally uses 0-255 as the volume range. So we switch to use that
(keeping the old API usage as is in case this gets fixed upstream).
---
 src/modules/echo-cancel/webrtc.cc | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/modules/echo-cancel/webrtc.cc b/src/modules/echo-cancel/webrtc.cc
index 58af280..a5d5c2e 100644
--- a/src/modules/echo-cancel/webrtc.cc
+++ b/src/modules/echo-cancel/webrtc.cc
@@ -51,6 +51,8 @@ PA_C_DECL_END
 #define DEFAULT_INTELLIGIBILITY_ENHANCER false
 #define DEFAULT_TRACE false
 
+#define WEBRTC_AGC_MAX_VOLUME 255
+
 static const char* const valid_modargs[] = {
     "high_pass_filter",
     "noise_suppression",
@@ -95,6 +97,16 @@ class PaWebrtcTraceCallback : public webrtc::TraceCallback {
     }
 };
 
+static int webrtc_volume_from_pa(pa_volume_t v)
+{
+    return (v * WEBRTC_AGC_MAX_VOLUME) / PA_VOLUME_NORM;
+}
+
+static pa_volume_t webrtc_volume_to_pa(int v)
+{
+    return (v * PA_VOLUME_NORM) / WEBRTC_AGC_MAX_VOLUME;
+}
+
 static void pa_webrtc_ec_fixate_spec(pa_sample_spec *rec_ss, pa_channel_map *rec_map,
                                      pa_sample_spec *play_ss, pa_channel_map *play_map,
                                      pa_sample_spec *out_ss, pa_channel_map *out_map)
@@ -271,7 +283,7 @@ bool pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
             ec->params.priv.webrtc.agc = false;
         } else {
             apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveAnalog);
-            if (apm->gain_control()->set_analog_level_limits(0, PA_VOLUME_NORM-1) != apm->kNoError) {
+            if (apm->gain_control()->set_analog_level_limits(0, WEBRTC_AGC_MAX_VOLUME) != apm->kNoError) {
                 pa_log("Failed to initialise AGC");
                 goto fail;
             }
@@ -323,6 +335,7 @@ void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out
     webrtc::AudioFrame out_frame;
     const pa_sample_spec *ss = &ec->params.priv.webrtc.sample_spec;
     pa_cvolume v;
+    int old_volume, new_volume;
 
     out_frame.num_channels_ = ss->channels;
     out_frame.sample_rate_hz_ = ss->rate;
@@ -335,15 +348,19 @@ void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out
     if (ec->params.priv.webrtc.agc) {
         pa_cvolume_init(&v);
         pa_echo_canceller_get_capture_volume(ec, &v);
-        apm->gain_control()->set_stream_analog_level(pa_cvolume_avg(&v));
+        old_volume = webrtc_volume_from_pa(pa_cvolume_avg(&v));
+        apm->gain_control()->set_stream_analog_level(old_volume);
     }
 
     apm->set_stream_delay_ms(0);
     apm->ProcessStream(&out_frame);
 
     if (ec->params.priv.webrtc.agc) {
-        pa_cvolume_set(&v, ss->channels, apm->gain_control()->stream_analog_level());
-        pa_echo_canceller_set_capture_volume(ec, &v);
+        new_volume = apm->gain_control()->stream_analog_level();
+        if (old_volume != new_volume) {
+            pa_cvolume_set(&v, ss->channels, webrtc_volume_to_pa(new_volume));
+            pa_echo_canceller_set_capture_volume(ec, &v);
+        }
     }
 
     memcpy(out, out_frame.data_, ec->params.priv.webrtc.blocksize);
-- 
2.5.0



More information about the pulseaudio-discuss mailing list