• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/aec3/echo_canceller3.h"
12 
13 #include <deque>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "modules/audio_processing/aec3/aec3_common.h"
20 #include "modules/audio_processing/aec3/block_processor.h"
21 #include "modules/audio_processing/aec3/frame_blocker.h"
22 #include "modules/audio_processing/aec3/mock/mock_block_processor.h"
23 #include "modules/audio_processing/audio_buffer.h"
24 #include "modules/audio_processing/high_pass_filter.h"
25 #include "modules/audio_processing/utility/cascaded_biquad_filter.h"
26 #include "rtc_base/strings/string_builder.h"
27 #include "test/field_trial.h"
28 #include "test/gmock.h"
29 #include "test/gtest.h"
30 
31 namespace webrtc {
32 namespace {
33 
34 using ::testing::_;
35 using ::testing::StrictMock;
36 
37 // Populates the frame with linearly increasing sample values for each band,
38 // with a band-specific offset, in order to allow simple bitexactness
39 // verification for each band.
PopulateInputFrame(size_t frame_length,size_t num_bands,size_t frame_index,float * const * frame,int offset)40 void PopulateInputFrame(size_t frame_length,
41                         size_t num_bands,
42                         size_t frame_index,
43                         float* const* frame,
44                         int offset) {
45   for (size_t k = 0; k < num_bands; ++k) {
46     for (size_t i = 0; i < frame_length; ++i) {
47       float value = static_cast<int>(frame_index * frame_length + i) + offset;
48       frame[k][i] = (value > 0 ? 5000 * k + value : 0);
49     }
50   }
51 }
52 
53 // Populates the frame with linearly increasing sample values.
PopulateInputFrame(size_t frame_length,size_t frame_index,float * frame,int offset)54 void PopulateInputFrame(size_t frame_length,
55                         size_t frame_index,
56                         float* frame,
57                         int offset) {
58   for (size_t i = 0; i < frame_length; ++i) {
59     float value = static_cast<int>(frame_index * frame_length + i) + offset;
60     frame[i] = std::max(value, 0.f);
61   }
62 }
63 
64 // Verifies the that samples in the output frame are identical to the samples
65 // that were produced for the input frame, with an offset in order to compensate
66 // for buffering delays.
VerifyOutputFrameBitexactness(size_t frame_length,size_t num_bands,size_t frame_index,const float * const * frame,int offset)67 bool VerifyOutputFrameBitexactness(size_t frame_length,
68                                    size_t num_bands,
69                                    size_t frame_index,
70                                    const float* const* frame,
71                                    int offset) {
72   float reference_frame_data[kMaxNumBands][2 * kSubFrameLength];
73   float* reference_frame[kMaxNumBands];
74   for (size_t k = 0; k < num_bands; ++k) {
75     reference_frame[k] = &reference_frame_data[k][0];
76   }
77 
78   PopulateInputFrame(frame_length, num_bands, frame_index, reference_frame,
79                      offset);
80   for (size_t k = 0; k < num_bands; ++k) {
81     for (size_t i = 0; i < frame_length; ++i) {
82       if (reference_frame[k][i] != frame[k][i]) {
83         return false;
84       }
85     }
86   }
87 
88   return true;
89 }
90 
VerifyOutputFrameBitexactness(rtc::ArrayView<const float> reference,rtc::ArrayView<const float> frame,int offset)91 bool VerifyOutputFrameBitexactness(rtc::ArrayView<const float> reference,
92                                    rtc::ArrayView<const float> frame,
93                                    int offset) {
94   for (size_t k = 0; k < frame.size(); ++k) {
95     int reference_index = static_cast<int>(k) + offset;
96     if (reference_index >= 0) {
97       if (reference[reference_index] != frame[k]) {
98         return false;
99       }
100     }
101   }
102   return true;
103 }
104 
105 // Class for testing that the capture data is properly received by the block
106 // processor and that the processor data is properly passed to the
107 // EchoCanceller3 output.
108 class CaptureTransportVerificationProcessor : public BlockProcessor {
109  public:
CaptureTransportVerificationProcessor(size_t num_bands)110   explicit CaptureTransportVerificationProcessor(size_t num_bands) {}
111   ~CaptureTransportVerificationProcessor() override = default;
112 
ProcessCapture(bool level_change,bool saturated_microphone_signal,std::vector<std::vector<std::vector<float>>> * linear_output,std::vector<std::vector<std::vector<float>>> * capture_block)113   void ProcessCapture(
114       bool level_change,
115       bool saturated_microphone_signal,
116       std::vector<std::vector<std::vector<float>>>* linear_output,
117       std::vector<std::vector<std::vector<float>>>* capture_block) override {}
118 
BufferRender(const std::vector<std::vector<std::vector<float>>> & block)119   void BufferRender(
120       const std::vector<std::vector<std::vector<float>>>& block) override {}
121 
UpdateEchoLeakageStatus(bool leakage_detected)122   void UpdateEchoLeakageStatus(bool leakage_detected) override {}
123 
GetMetrics(EchoControl::Metrics * metrics) const124   void GetMetrics(EchoControl::Metrics* metrics) const override {}
125 
SetAudioBufferDelay(int delay_ms)126   void SetAudioBufferDelay(int delay_ms) override {}
127 
128  private:
129   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTransportVerificationProcessor);
130 };
131 
132 // Class for testing that the render data is properly received by the block
133 // processor.
134 class RenderTransportVerificationProcessor : public BlockProcessor {
135  public:
RenderTransportVerificationProcessor(size_t num_bands)136   explicit RenderTransportVerificationProcessor(size_t num_bands) {}
137   ~RenderTransportVerificationProcessor() override = default;
138 
ProcessCapture(bool level_change,bool saturated_microphone_signal,std::vector<std::vector<std::vector<float>>> * linear_output,std::vector<std::vector<std::vector<float>>> * capture_block)139   void ProcessCapture(
140       bool level_change,
141       bool saturated_microphone_signal,
142       std::vector<std::vector<std::vector<float>>>* linear_output,
143       std::vector<std::vector<std::vector<float>>>* capture_block) override {
144     std::vector<std::vector<std::vector<float>>> render_block =
145         received_render_blocks_.front();
146     received_render_blocks_.pop_front();
147     capture_block->swap(render_block);
148   }
149 
BufferRender(const std::vector<std::vector<std::vector<float>>> & block)150   void BufferRender(
151       const std::vector<std::vector<std::vector<float>>>& block) override {
152     received_render_blocks_.push_back(block);
153   }
154 
UpdateEchoLeakageStatus(bool leakage_detected)155   void UpdateEchoLeakageStatus(bool leakage_detected) override {}
156 
GetMetrics(EchoControl::Metrics * metrics) const157   void GetMetrics(EchoControl::Metrics* metrics) const override {}
158 
SetAudioBufferDelay(int delay_ms)159   void SetAudioBufferDelay(int delay_ms) override {}
160 
161  private:
162   std::deque<std::vector<std::vector<std::vector<float>>>>
163       received_render_blocks_;
164   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderTransportVerificationProcessor);
165 };
166 
167 class EchoCanceller3Tester {
168  public:
EchoCanceller3Tester(int sample_rate_hz)169   explicit EchoCanceller3Tester(int sample_rate_hz)
170       : sample_rate_hz_(sample_rate_hz),
171         num_bands_(NumBandsForRate(sample_rate_hz_)),
172         frame_length_(160),
173         fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
174         capture_buffer_(fullband_frame_length_ * 100,
175                         1,
176                         fullband_frame_length_ * 100,
177                         1,
178                         fullband_frame_length_ * 100,
179                         1),
180         render_buffer_(fullband_frame_length_ * 100,
181                        1,
182                        fullband_frame_length_ * 100,
183                        1,
184                        fullband_frame_length_ * 100,
185                        1) {}
186 
187   // Verifies that the capture data is properly received by the block processor
188   // and that the processor data is properly passed to the EchoCanceller3
189   // output.
RunCaptureTransportVerificationTest()190   void RunCaptureTransportVerificationTest() {
191     EchoCanceller3 aec3(
192         EchoCanceller3Config(), sample_rate_hz_, 1, 1,
193         std::unique_ptr<BlockProcessor>(
194             new CaptureTransportVerificationProcessor(num_bands_)));
195 
196     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
197          ++frame_index) {
198       aec3.AnalyzeCapture(&capture_buffer_);
199       OptionalBandSplit();
200       PopulateInputFrame(frame_length_, num_bands_, frame_index,
201                          &capture_buffer_.split_bands(0)[0], 0);
202       PopulateInputFrame(frame_length_, frame_index,
203                          &render_buffer_.channels()[0][0], 0);
204 
205       aec3.AnalyzeRender(&render_buffer_);
206       aec3.ProcessCapture(&capture_buffer_, false);
207       EXPECT_TRUE(VerifyOutputFrameBitexactness(
208           frame_length_, num_bands_, frame_index,
209           &capture_buffer_.split_bands(0)[0], -64));
210     }
211   }
212 
213   // Test method for testing that the render data is properly received by the
214   // block processor.
RunRenderTransportVerificationTest()215   void RunRenderTransportVerificationTest() {
216     EchoCanceller3 aec3(
217         EchoCanceller3Config(), sample_rate_hz_, 1, 1,
218         std::unique_ptr<BlockProcessor>(
219             new RenderTransportVerificationProcessor(num_bands_)));
220 
221     std::vector<std::vector<float>> render_input(1);
222     std::vector<float> capture_output;
223     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
224          ++frame_index) {
225       aec3.AnalyzeCapture(&capture_buffer_);
226       OptionalBandSplit();
227       PopulateInputFrame(frame_length_, num_bands_, frame_index,
228                          &capture_buffer_.split_bands(0)[0], 100);
229       PopulateInputFrame(frame_length_, num_bands_, frame_index,
230                          &render_buffer_.split_bands(0)[0], 0);
231 
232       for (size_t k = 0; k < frame_length_; ++k) {
233         render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
234       }
235       aec3.AnalyzeRender(&render_buffer_);
236       aec3.ProcessCapture(&capture_buffer_, false);
237       for (size_t k = 0; k < frame_length_; ++k) {
238         capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
239       }
240     }
241     HighPassFilter hp_filter(16000, 1);
242     hp_filter.Process(&render_input);
243 
244     EXPECT_TRUE(
245         VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
246   }
247 
248   // Verifies that information about echo path changes are properly propagated
249   // to the block processor.
250   // The cases tested are:
251   // -That no set echo path change flags are received when there is no echo path
252   // change.
253   // -That set echo path change flags are received and continues to be received
254   // as long as echo path changes are flagged.
255   // -That set echo path change flags are no longer received when echo path
256   // change events stop being flagged.
257   enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };
258 
RunEchoPathChangeVerificationTest(EchoPathChangeTestVariant echo_path_change_test_variant)259   void RunEchoPathChangeVerificationTest(
260       EchoPathChangeTestVariant echo_path_change_test_variant) {
261     constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
262     constexpr size_t kExpectedNumBlocksToProcess =
263         (kNumFramesToProcess * 160) / kBlockSize;
264     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
265         block_processor_mock(
266             new StrictMock<webrtc::test::MockBlockProcessor>());
267     EXPECT_CALL(*block_processor_mock, BufferRender(_))
268         .Times(kExpectedNumBlocksToProcess);
269     EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
270 
271     switch (echo_path_change_test_variant) {
272       case EchoPathChangeTestVariant::kNone:
273         EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
274             .Times(kExpectedNumBlocksToProcess);
275         break;
276       case EchoPathChangeTestVariant::kOneSticky:
277         EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
278             .Times(kExpectedNumBlocksToProcess);
279         break;
280       case EchoPathChangeTestVariant::kOneNonSticky:
281         EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
282             .Times(kNumFullBlocksPerFrame);
283         EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
284             .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
285         break;
286     }
287 
288     EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
289                         std::move(block_processor_mock));
290 
291     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
292          ++frame_index) {
293       bool echo_path_change = false;
294       switch (echo_path_change_test_variant) {
295         case EchoPathChangeTestVariant::kNone:
296           break;
297         case EchoPathChangeTestVariant::kOneSticky:
298           echo_path_change = true;
299           break;
300         case EchoPathChangeTestVariant::kOneNonSticky:
301           if (frame_index == 0) {
302             echo_path_change = true;
303           }
304           break;
305       }
306 
307       aec3.AnalyzeCapture(&capture_buffer_);
308       OptionalBandSplit();
309 
310       PopulateInputFrame(frame_length_, num_bands_, frame_index,
311                          &capture_buffer_.split_bands(0)[0], 0);
312       PopulateInputFrame(frame_length_, frame_index,
313                          &render_buffer_.channels()[0][0], 0);
314 
315       aec3.AnalyzeRender(&render_buffer_);
316       aec3.ProcessCapture(&capture_buffer_, echo_path_change);
317     }
318   }
319 
320   // Test for verifying that echo leakage information is being properly passed
321   // to the processor.
322   // The cases tested are:
323   // -That no method calls are received when they should not.
324   // -That false values are received each time they are flagged.
325   // -That true values are received each time they are flagged.
326   // -That a false value is received when flagged after a true value has been
327   // flagged.
328   enum class EchoLeakageTestVariant {
329     kNone,
330     kFalseSticky,
331     kTrueSticky,
332     kTrueNonSticky
333   };
334 
RunEchoLeakageVerificationTest(EchoLeakageTestVariant leakage_report_variant)335   void RunEchoLeakageVerificationTest(
336       EchoLeakageTestVariant leakage_report_variant) {
337     constexpr size_t kExpectedNumBlocksToProcess =
338         (kNumFramesToProcess * 160) / kBlockSize;
339     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
340         block_processor_mock(
341             new StrictMock<webrtc::test::MockBlockProcessor>());
342     EXPECT_CALL(*block_processor_mock, BufferRender(_))
343         .Times(kExpectedNumBlocksToProcess);
344     EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
345         .Times(kExpectedNumBlocksToProcess);
346 
347     switch (leakage_report_variant) {
348       case EchoLeakageTestVariant::kNone:
349         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
350         break;
351       case EchoLeakageTestVariant::kFalseSticky:
352         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
353             .Times(1);
354         break;
355       case EchoLeakageTestVariant::kTrueSticky:
356         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
357             .Times(1);
358         break;
359       case EchoLeakageTestVariant::kTrueNonSticky: {
360         ::testing::InSequence s;
361         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
362             .Times(1);
363         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
364             .Times(kNumFramesToProcess - 1);
365       } break;
366     }
367 
368     EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
369                         std::move(block_processor_mock));
370 
371     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
372          ++frame_index) {
373       switch (leakage_report_variant) {
374         case EchoLeakageTestVariant::kNone:
375           break;
376         case EchoLeakageTestVariant::kFalseSticky:
377           if (frame_index == 0) {
378             aec3.UpdateEchoLeakageStatus(false);
379           }
380           break;
381         case EchoLeakageTestVariant::kTrueSticky:
382           if (frame_index == 0) {
383             aec3.UpdateEchoLeakageStatus(true);
384           }
385           break;
386         case EchoLeakageTestVariant::kTrueNonSticky:
387           if (frame_index == 0) {
388             aec3.UpdateEchoLeakageStatus(true);
389           } else {
390             aec3.UpdateEchoLeakageStatus(false);
391           }
392           break;
393       }
394 
395       aec3.AnalyzeCapture(&capture_buffer_);
396       OptionalBandSplit();
397 
398       PopulateInputFrame(frame_length_, num_bands_, frame_index,
399                          &capture_buffer_.split_bands(0)[0], 0);
400       PopulateInputFrame(frame_length_, frame_index,
401                          &render_buffer_.channels()[0][0], 0);
402 
403       aec3.AnalyzeRender(&render_buffer_);
404       aec3.ProcessCapture(&capture_buffer_, false);
405     }
406   }
407 
408   // This verifies that saturation information is properly passed to the
409   // BlockProcessor.
410   // The cases tested are:
411   // -That no saturation event is passed to the processor if there is no
412   // saturation.
413   // -That one frame with one negative saturated sample value is reported to be
414   // saturated and that following non-saturated frames are properly reported as
415   // not being saturated.
416   // -That one frame with one positive saturated sample value is reported to be
417   // saturated and that following non-saturated frames are properly reported as
418   // not being saturated.
419   enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };
420 
RunCaptureSaturationVerificationTest(SaturationTestVariant saturation_variant)421   void RunCaptureSaturationVerificationTest(
422       SaturationTestVariant saturation_variant) {
423     const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
424     const size_t kExpectedNumBlocksToProcess =
425         (kNumFramesToProcess * 160) / kBlockSize;
426     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
427         block_processor_mock(
428             new StrictMock<webrtc::test::MockBlockProcessor>());
429     EXPECT_CALL(*block_processor_mock, BufferRender(_))
430         .Times(kExpectedNumBlocksToProcess);
431     EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
432 
433     switch (saturation_variant) {
434       case SaturationTestVariant::kNone:
435         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
436             .Times(kExpectedNumBlocksToProcess);
437         break;
438       case SaturationTestVariant::kOneNegative: {
439         ::testing::InSequence s;
440         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
441             .Times(kNumFullBlocksPerFrame);
442         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
443             .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
444       } break;
445       case SaturationTestVariant::kOnePositive: {
446         ::testing::InSequence s;
447         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
448             .Times(kNumFullBlocksPerFrame);
449         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
450             .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
451       } break;
452     }
453 
454     EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
455                         std::move(block_processor_mock));
456     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
457          ++frame_index) {
458       for (int k = 0; k < fullband_frame_length_; ++k) {
459         capture_buffer_.channels()[0][k] = 0.f;
460       }
461       switch (saturation_variant) {
462         case SaturationTestVariant::kNone:
463           break;
464         case SaturationTestVariant::kOneNegative:
465           if (frame_index == 0) {
466             capture_buffer_.channels()[0][10] = -32768.f;
467           }
468           break;
469         case SaturationTestVariant::kOnePositive:
470           if (frame_index == 0) {
471             capture_buffer_.channels()[0][10] = 32767.f;
472           }
473           break;
474       }
475 
476       aec3.AnalyzeCapture(&capture_buffer_);
477       OptionalBandSplit();
478 
479       PopulateInputFrame(frame_length_, num_bands_, frame_index,
480                          &capture_buffer_.split_bands(0)[0], 0);
481       PopulateInputFrame(frame_length_, num_bands_, frame_index,
482                          &render_buffer_.split_bands(0)[0], 0);
483 
484       aec3.AnalyzeRender(&render_buffer_);
485       aec3.ProcessCapture(&capture_buffer_, false);
486     }
487   }
488 
489   // This test verifies that the swapqueue is able to handle jitter in the
490   // capture and render API calls.
RunRenderSwapQueueVerificationTest()491   void RunRenderSwapQueueVerificationTest() {
492     const EchoCanceller3Config config;
493     EchoCanceller3 aec3(
494         config, sample_rate_hz_, 1, 1,
495         std::unique_ptr<BlockProcessor>(
496             new RenderTransportVerificationProcessor(num_bands_)));
497 
498     std::vector<std::vector<float>> render_input(1);
499     std::vector<float> capture_output;
500 
501     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
502          ++frame_index) {
503       if (sample_rate_hz_ > 16000) {
504         render_buffer_.SplitIntoFrequencyBands();
505       }
506       PopulateInputFrame(frame_length_, num_bands_, frame_index,
507                          &render_buffer_.split_bands(0)[0], 0);
508 
509       if (sample_rate_hz_ > 16000) {
510         render_buffer_.SplitIntoFrequencyBands();
511       }
512 
513       for (size_t k = 0; k < frame_length_; ++k) {
514         render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
515       }
516       aec3.AnalyzeRender(&render_buffer_);
517     }
518 
519     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
520          ++frame_index) {
521       aec3.AnalyzeCapture(&capture_buffer_);
522       if (sample_rate_hz_ > 16000) {
523         capture_buffer_.SplitIntoFrequencyBands();
524       }
525 
526       PopulateInputFrame(frame_length_, num_bands_, frame_index,
527                          &capture_buffer_.split_bands(0)[0], 0);
528 
529       aec3.ProcessCapture(&capture_buffer_, false);
530       for (size_t k = 0; k < frame_length_; ++k) {
531         capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
532       }
533     }
534     HighPassFilter hp_filter(16000, 1);
535     hp_filter.Process(&render_input);
536 
537     EXPECT_TRUE(
538         VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
539   }
540 
541   // This test verifies that a buffer overrun in the render swapqueue is
542   // properly reported.
RunRenderPipelineSwapQueueOverrunReturnValueTest()543   void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
544     EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1);
545 
546     constexpr size_t kRenderTransferQueueSize = 30;
547     for (size_t k = 0; k < 2; ++k) {
548       for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
549            ++frame_index) {
550         if (sample_rate_hz_ > 16000) {
551           render_buffer_.SplitIntoFrequencyBands();
552         }
553         PopulateInputFrame(frame_length_, frame_index,
554                            &render_buffer_.channels()[0][0], 0);
555 
556         aec3.AnalyzeRender(&render_buffer_);
557       }
558     }
559   }
560 
561 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
562   // Verifies the that the check for the number of bands in the AnalyzeRender
563   // input is correct by adjusting the sample rates of EchoCanceller3 and the
564   // input AudioBuffer to have a different number of bands.
RunAnalyzeRenderNumBandsCheckVerification()565   void RunAnalyzeRenderNumBandsCheckVerification() {
566     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
567     // way that the number of bands for the rates are different.
568     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
569     EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
570     PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
571 
572     EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
573   }
574 
575   // Verifies the that the check for the number of bands in the ProcessCapture
576   // input is correct by adjusting the sample rates of EchoCanceller3 and the
577   // input AudioBuffer to have a different number of bands.
RunProcessCaptureNumBandsCheckVerification()578   void RunProcessCaptureNumBandsCheckVerification() {
579     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
580     // way that the number of bands for the rates are different.
581     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
582     EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
583     PopulateInputFrame(frame_length_, num_bands_, 0,
584                        &capture_buffer_.split_bands_f(0)[0], 100);
585     EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
586   }
587 
588 #endif
589 
590  private:
OptionalBandSplit()591   void OptionalBandSplit() {
592     if (sample_rate_hz_ > 16000) {
593       capture_buffer_.SplitIntoFrequencyBands();
594       render_buffer_.SplitIntoFrequencyBands();
595     }
596   }
597 
598   static constexpr size_t kNumFramesToProcess = 20;
599   const int sample_rate_hz_;
600   const size_t num_bands_;
601   const size_t frame_length_;
602   const int fullband_frame_length_;
603   AudioBuffer capture_buffer_;
604   AudioBuffer render_buffer_;
605 
606   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCanceller3Tester);
607 };
608 
ProduceDebugText(int sample_rate_hz)609 std::string ProduceDebugText(int sample_rate_hz) {
610   rtc::StringBuilder ss;
611   ss << "Sample rate: " << sample_rate_hz;
612   return ss.Release();
613 }
614 
ProduceDebugText(int sample_rate_hz,int variant)615 std::string ProduceDebugText(int sample_rate_hz, int variant) {
616   rtc::StringBuilder ss;
617   ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
618   return ss.Release();
619 }
620 
621 }  // namespace
622 
TEST(EchoCanceller3Buffering,CaptureBitexactness)623 TEST(EchoCanceller3Buffering, CaptureBitexactness) {
624   for (auto rate : {16000, 32000, 48000}) {
625     SCOPED_TRACE(ProduceDebugText(rate));
626     EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
627   }
628 }
629 
TEST(EchoCanceller3Buffering,RenderBitexactness)630 TEST(EchoCanceller3Buffering, RenderBitexactness) {
631   for (auto rate : {16000, 32000, 48000}) {
632     SCOPED_TRACE(ProduceDebugText(rate));
633     EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
634   }
635 }
636 
TEST(EchoCanceller3Buffering,RenderSwapQueue)637 TEST(EchoCanceller3Buffering, RenderSwapQueue) {
638   EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
639 }
640 
TEST(EchoCanceller3Buffering,RenderSwapQueueOverrunReturnValue)641 TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
642   for (auto rate : {16000, 32000, 48000}) {
643     SCOPED_TRACE(ProduceDebugText(rate));
644     EchoCanceller3Tester(rate)
645         .RunRenderPipelineSwapQueueOverrunReturnValueTest();
646   }
647 }
648 
TEST(EchoCanceller3Messaging,CaptureSaturation)649 TEST(EchoCanceller3Messaging, CaptureSaturation) {
650   auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
651                    EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
652                    EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
653   for (auto rate : {16000, 32000, 48000}) {
654     for (auto variant : variants) {
655       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
656       EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
657     }
658   }
659 }
660 
TEST(EchoCanceller3Messaging,EchoPathChange)661 TEST(EchoCanceller3Messaging, EchoPathChange) {
662   auto variants = {
663       EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
664       EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
665       EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
666   for (auto rate : {16000, 32000, 48000}) {
667     for (auto variant : variants) {
668       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
669       EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
670     }
671   }
672 }
673 
TEST(EchoCanceller3Messaging,EchoLeakage)674 TEST(EchoCanceller3Messaging, EchoLeakage) {
675   auto variants = {
676       EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
677       EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
678       EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
679       EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
680   for (auto rate : {16000, 32000, 48000}) {
681     for (auto variant : variants) {
682       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
683       EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
684     }
685   }
686 }
687 
688 // Tests the parameter functionality for the field trial override for the
689 // default_len parameter.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorEpStrengthDefaultLenOverride)690 TEST(EchoCanceller3FieldTrials, Aec3SuppressorEpStrengthDefaultLenOverride) {
691   EchoCanceller3Config default_config;
692   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
693   ASSERT_EQ(default_config.ep_strength.default_len,
694             adjusted_config.ep_strength.default_len);
695 
696   webrtc::test::ScopedFieldTrials field_trials(
697       "WebRTC-Aec3SuppressorEpStrengthDefaultLenOverride/-0.02/");
698   adjusted_config = AdjustConfig(default_config);
699 
700   ASSERT_NE(default_config.ep_strength.default_len,
701             adjusted_config.ep_strength.default_len);
702   EXPECT_FLOAT_EQ(-0.02f, adjusted_config.ep_strength.default_len);
703 }
704 
705 // Tests the parameter functionality for the field trial override for the
706 // anti-howling gain.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorAntiHowlingGainOverride)707 TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
708   EchoCanceller3Config default_config;
709   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
710   ASSERT_EQ(
711       default_config.suppressor.high_bands_suppression.anti_howling_gain,
712       adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
713 
714   webrtc::test::ScopedFieldTrials field_trials(
715       "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
716   adjusted_config = AdjustConfig(default_config);
717 
718   ASSERT_NE(
719       default_config.suppressor.high_bands_suppression.anti_howling_gain,
720       adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
721   EXPECT_FLOAT_EQ(
722       0.02f,
723       adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
724 }
725 
726 // Tests the field trial override for the enforcement of a low active render
727 // limit.
TEST(EchoCanceller3FieldTrials,Aec3EnforceLowActiveRenderLimit)728 TEST(EchoCanceller3FieldTrials, Aec3EnforceLowActiveRenderLimit) {
729   EchoCanceller3Config default_config;
730   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
731   ASSERT_EQ(default_config.render_levels.active_render_limit,
732             adjusted_config.render_levels.active_render_limit);
733 
734   webrtc::test::ScopedFieldTrials field_trials(
735       "WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
736   adjusted_config = AdjustConfig(default_config);
737 
738   ASSERT_NE(default_config.render_levels.active_render_limit,
739             adjusted_config.render_levels.active_render_limit);
740   EXPECT_FLOAT_EQ(50.f, adjusted_config.render_levels.active_render_limit);
741 }
742 
743 // Testing the field trial-based override of the suppressor parameters for a
744 // joint passing of all parameters.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorTuningOverrideAllParams)745 TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideAllParams) {
746   webrtc::test::ScopedFieldTrials field_trials(
747       "WebRTC-Aec3SuppressorTuningOverride/"
748       "nearend_tuning_mask_lf_enr_transparent:0.1,nearend_tuning_mask_lf_enr_"
749       "suppress:0.2,nearend_tuning_mask_hf_enr_transparent:0.3,nearend_tuning_"
750       "mask_hf_enr_suppress:0.4,nearend_tuning_max_inc_factor:0.5,nearend_"
751       "tuning_max_dec_factor_lf:0.6,normal_tuning_mask_lf_enr_transparent:0.7,"
752       "normal_tuning_mask_lf_enr_suppress:0.8,normal_tuning_mask_hf_enr_"
753       "transparent:0.9,normal_tuning_mask_hf_enr_suppress:1.0,normal_tuning_"
754       "max_inc_factor:1.1,normal_tuning_max_dec_factor_lf:1.2,dominant_nearend_"
755       "detection_enr_threshold:1.3,dominant_nearend_detection_enr_exit_"
756       "threshold:1.4,dominant_nearend_detection_snr_threshold:1.5,dominant_"
757       "nearend_detection_hold_duration:10,dominant_nearend_detection_trigger_"
758       "threshold:11,ep_strength_default_len:1.6/");
759 
760   EchoCanceller3Config default_config;
761   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
762 
763   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
764             default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
765   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
766             default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
767   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
768             default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
769   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
770             default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
771   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
772             default_config.suppressor.nearend_tuning.max_inc_factor);
773   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
774             default_config.suppressor.nearend_tuning.max_dec_factor_lf);
775   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
776             default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
777   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
778             default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
779   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
780             default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
781   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
782             default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
783   ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_inc_factor,
784             default_config.suppressor.normal_tuning.max_inc_factor);
785   ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
786             default_config.suppressor.normal_tuning.max_dec_factor_lf);
787   ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
788             default_config.suppressor.dominant_nearend_detection.enr_threshold);
789   ASSERT_NE(
790       adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
791       default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
792   ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
793             default_config.suppressor.dominant_nearend_detection.snr_threshold);
794   ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
795             default_config.suppressor.dominant_nearend_detection.hold_duration);
796   ASSERT_NE(
797       adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
798       default_config.suppressor.dominant_nearend_detection.trigger_threshold);
799   ASSERT_NE(adjusted_config.ep_strength.default_len,
800             default_config.ep_strength.default_len);
801 
802   EXPECT_FLOAT_EQ(
803       adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent, 0.1);
804   EXPECT_FLOAT_EQ(
805       adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress, 0.2);
806   EXPECT_FLOAT_EQ(
807       adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent, 0.3);
808   EXPECT_FLOAT_EQ(
809       adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress, 0.4);
810   EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
811                   0.5);
812   EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
813                   0.6);
814   EXPECT_FLOAT_EQ(
815       adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent, 0.7);
816   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
817                   0.8);
818   EXPECT_FLOAT_EQ(
819       adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent, 0.9);
820   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
821                   1.0);
822   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor, 1.1);
823   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
824                   1.2);
825   EXPECT_FLOAT_EQ(
826       adjusted_config.suppressor.dominant_nearend_detection.enr_threshold, 1.3);
827   EXPECT_FLOAT_EQ(
828       adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
829       1.4);
830   EXPECT_FLOAT_EQ(
831       adjusted_config.suppressor.dominant_nearend_detection.snr_threshold, 1.5);
832   EXPECT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
833             10);
834   EXPECT_EQ(
835       adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
836       11);
837   EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 1.6);
838 }
839 
840 // Testing the field trial-based override of the suppressor parameters for
841 // passing one parameter.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorTuningOverrideOneParam)842 TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideOneParam) {
843   webrtc::test::ScopedFieldTrials field_trials(
844       "WebRTC-Aec3SuppressorTuningOverride/nearend_tuning_max_inc_factor:0.5/");
845 
846   EchoCanceller3Config default_config;
847   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
848 
849   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
850             default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
851   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
852             default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
853   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
854             default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
855   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
856             default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
857   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
858             default_config.suppressor.nearend_tuning.max_dec_factor_lf);
859   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
860             default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
861   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
862             default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
863   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
864             default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
865   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
866             default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
867   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor,
868             default_config.suppressor.normal_tuning.max_inc_factor);
869   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
870             default_config.suppressor.normal_tuning.max_dec_factor_lf);
871   ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
872             default_config.suppressor.dominant_nearend_detection.enr_threshold);
873   ASSERT_EQ(
874       adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
875       default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
876   ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
877             default_config.suppressor.dominant_nearend_detection.snr_threshold);
878   ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
879             default_config.suppressor.dominant_nearend_detection.hold_duration);
880   ASSERT_EQ(
881       adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
882       default_config.suppressor.dominant_nearend_detection.trigger_threshold);
883 
884   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
885             default_config.suppressor.nearend_tuning.max_inc_factor);
886 
887   EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
888                   0.5);
889 }
890 
891 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
892 
TEST(EchoCanceller3InputCheckDeathTest,WrongCaptureNumBandsCheckVerification)893 TEST(EchoCanceller3InputCheckDeathTest, WrongCaptureNumBandsCheckVerification) {
894   for (auto rate : {16000, 32000, 48000}) {
895     SCOPED_TRACE(ProduceDebugText(rate));
896     EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
897   }
898 }
899 
900 // Verifiers that the verification for null input to the capture processing api
901 // call works.
TEST(EchoCanceller3InputCheckDeathTest,NullCaptureProcessingParameter)902 TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
903   EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 16000, 1, 1)
904                    .ProcessCapture(nullptr, false),
905                "");
906 }
907 
908 // Verifies the check for correct sample rate.
909 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
910 // tests on test bots has been fixed.
TEST(EchoCanceller3InputCheckDeathTest,DISABLED_WrongSampleRate)911 TEST(EchoCanceller3InputCheckDeathTest, DISABLED_WrongSampleRate) {
912   ApmDataDumper data_dumper(0);
913   EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001, 1, 1), "");
914 }
915 
916 #endif
917 
918 }  // namespace webrtc
919