[pulseaudio-discuss] [PATCH v3 17/24] echo-cancel: Fix webrtc canceller when rec channels != play channels

arun at accosted.net arun at accosted.net
Sun Jan 17 23:36:31 PST 2016


From: Arun Raghavan <git at arunraghavan.net>

The calculations around how many samples were sent to the canceller
engine was not updated when we started supporting different channel
counts for playback and capture.
---
 src/modules/echo-cancel/echo-cancel.h |  4 ++--
 src/modules/echo-cancel/webrtc.cc     | 25 +++++++++++++------------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/modules/echo-cancel/echo-cancel.h b/src/modules/echo-cancel/echo-cancel.h
index 37f99c0..4693516 100644
--- a/src/modules/echo-cancel/echo-cancel.h
+++ b/src/modules/echo-cancel/echo-cancel.h
@@ -64,8 +64,8 @@ struct pa_echo_canceller_params {
             /* This is a void* so that we don't have to convert this whole file
              * to C++ linkage. apm is a pointer to an AudioProcessing object */
             void *apm;
-            uint32_t blocksize;
-            pa_sample_spec sample_spec;
+            int32_t blocksize; /* in frames */
+            pa_sample_spec rec_ss, play_ss;
             bool agc;
             bool trace;
             bool first;
diff --git a/src/modules/echo-cancel/webrtc.cc b/src/modules/echo-cancel/webrtc.cc
index ec0a383..2732b38 100644
--- a/src/modules/echo-cancel/webrtc.cc
+++ b/src/modules/echo-cancel/webrtc.cc
@@ -327,9 +327,11 @@ bool pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
         apm->voice_detection()->Enable(true);
 
     ec->params.webrtc.apm = apm;
-    ec->params.webrtc.sample_spec = *out_ss;
-    ec->params.webrtc.blocksize = (uint64_t)pa_bytes_per_second(out_ss) * BLOCK_SIZE_US / PA_USEC_PER_SEC;
-    *nframes = ec->params.webrtc.blocksize / pa_frame_size(out_ss);
+    ec->params.webrtc.rec_ss = *rec_ss;
+    ec->params.webrtc.play_ss = *play_ss;
+    ec->params.webrtc.blocksize =
+        (uint64_t) (pa_bytes_per_second(out_ss) / pa_frame_size(out_ss)) * BLOCK_SIZE_US / PA_USEC_PER_SEC;
+    *nframes = ec->params.webrtc.blocksize;
     ec->params.webrtc.first = true;
 
     pa_modargs_free(ma);
@@ -349,15 +351,15 @@ fail:
 void pa_webrtc_ec_play(pa_echo_canceller *ec, const uint8_t *play) {
     webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.webrtc.apm;
     webrtc::AudioFrame play_frame;
-    const pa_sample_spec *ss = &ec->params.webrtc.sample_spec;
+    const pa_sample_spec *ss = &ec->params.webrtc.play_ss;
 
     play_frame.num_channels_ = ss->channels;
     play_frame.sample_rate_hz_ = ss->rate;
     play_frame.interleaved_ = true;
-    play_frame.samples_per_channel_ = ec->params.webrtc.blocksize / pa_frame_size(ss);
+    play_frame.samples_per_channel_ = ec->params.webrtc.blocksize;
 
     pa_assert(play_frame.samples_per_channel_ <= webrtc::AudioFrame::kMaxDataSizeSamples);
-    memcpy(play_frame.data_, play, ec->params.webrtc.blocksize);
+    memcpy(play_frame.data_, play, ec->params.webrtc.blocksize * pa_frame_size(ss));
 
     apm->ProcessReverseStream(&play_frame);
 }
@@ -365,17 +367,17 @@ void pa_webrtc_ec_play(pa_echo_canceller *ec, const uint8_t *play) {
 void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out) {
     webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.webrtc.apm;
     webrtc::AudioFrame out_frame;
-    const pa_sample_spec *ss = &ec->params.webrtc.sample_spec;
+    const pa_sample_spec *ss = &ec->params.webrtc.rec_ss;
     pa_cvolume v;
     int old_volume, new_volume;
 
     out_frame.num_channels_ = ss->channels;
     out_frame.sample_rate_hz_ = ss->rate;
     out_frame.interleaved_ = true;
-    out_frame.samples_per_channel_ = ec->params.webrtc.blocksize / pa_frame_size(ss);
+    out_frame.samples_per_channel_ = ec->params.webrtc.blocksize;
 
     pa_assert(out_frame.samples_per_channel_ <= webrtc::AudioFrame::kMaxDataSizeSamples);
-    memcpy(out_frame.data_, rec, ec->params.webrtc.blocksize);
+    memcpy(out_frame.data_, rec, ec->params.webrtc.blocksize * pa_frame_size(ss));
 
     if (ec->params.webrtc.agc) {
         pa_cvolume_init(&v);
@@ -405,14 +407,13 @@ void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out
         }
     }
 
-    memcpy(out, out_frame.data_, ec->params.webrtc.blocksize);
+    memcpy(out, out_frame.data_, ec->params.webrtc.blocksize * pa_frame_size(ss));
 }
 
 void pa_webrtc_ec_set_drift(pa_echo_canceller *ec, float drift) {
     webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.webrtc.apm;
-    const pa_sample_spec *ss = &ec->params.webrtc.sample_spec;
 
-    apm->echo_cancellation()->set_stream_drift_samples(drift * ec->params.webrtc.blocksize / pa_frame_size(ss));
+    apm->echo_cancellation()->set_stream_drift_samples(drift * ec->params.webrtc.blocksize);
 }
 
 void pa_webrtc_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
-- 
2.5.0



More information about the pulseaudio-discuss mailing list