• 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 
112   CaptureTransportVerificationProcessor() = delete;
113   CaptureTransportVerificationProcessor(
114       const CaptureTransportVerificationProcessor&) = delete;
115   CaptureTransportVerificationProcessor& operator=(
116       const CaptureTransportVerificationProcessor&) = delete;
117 
118   ~CaptureTransportVerificationProcessor() override = default;
119 
ProcessCapture(bool level_change,bool saturated_microphone_signal,Block * linear_output,Block * capture_block)120   void ProcessCapture(bool level_change,
121                       bool saturated_microphone_signal,
122                       Block* linear_output,
123                       Block* capture_block) override {}
124 
BufferRender(const Block & block)125   void BufferRender(const Block& block) override {}
126 
UpdateEchoLeakageStatus(bool leakage_detected)127   void UpdateEchoLeakageStatus(bool leakage_detected) override {}
128 
GetMetrics(EchoControl::Metrics * metrics) const129   void GetMetrics(EchoControl::Metrics* metrics) const override {}
130 
SetAudioBufferDelay(int delay_ms)131   void SetAudioBufferDelay(int delay_ms) override {}
132 
SetCaptureOutputUsage(bool capture_output_used)133   void SetCaptureOutputUsage(bool capture_output_used) {}
134 };
135 
136 // Class for testing that the render data is properly received by the block
137 // processor.
138 class RenderTransportVerificationProcessor : public BlockProcessor {
139  public:
RenderTransportVerificationProcessor(size_t num_bands)140   explicit RenderTransportVerificationProcessor(size_t num_bands) {}
141 
142   RenderTransportVerificationProcessor() = delete;
143   RenderTransportVerificationProcessor(
144       const RenderTransportVerificationProcessor&) = delete;
145   RenderTransportVerificationProcessor& operator=(
146       const RenderTransportVerificationProcessor&) = delete;
147 
148   ~RenderTransportVerificationProcessor() override = default;
149 
ProcessCapture(bool level_change,bool saturated_microphone_signal,Block * linear_output,Block * capture_block)150   void ProcessCapture(bool level_change,
151                       bool saturated_microphone_signal,
152                       Block* linear_output,
153                       Block* capture_block) override {
154     Block render_block = received_render_blocks_.front();
155     received_render_blocks_.pop_front();
156     capture_block->Swap(render_block);
157   }
158 
BufferRender(const Block & block)159   void BufferRender(const Block& block) override {
160     received_render_blocks_.push_back(block);
161   }
162 
UpdateEchoLeakageStatus(bool leakage_detected)163   void UpdateEchoLeakageStatus(bool leakage_detected) override {}
164 
GetMetrics(EchoControl::Metrics * metrics) const165   void GetMetrics(EchoControl::Metrics* metrics) const override {}
166 
SetAudioBufferDelay(int delay_ms)167   void SetAudioBufferDelay(int delay_ms) override {}
168 
SetCaptureOutputUsage(bool capture_output_used)169   void SetCaptureOutputUsage(bool capture_output_used) {}
170 
171  private:
172   std::deque<Block> received_render_blocks_;
173 };
174 
ProduceDebugText(int sample_rate_hz)175 std::string ProduceDebugText(int sample_rate_hz) {
176   rtc::StringBuilder ss;
177   ss << "Sample rate: " << sample_rate_hz;
178   return ss.Release();
179 }
180 
ProduceDebugText(int sample_rate_hz,int variant)181 std::string ProduceDebugText(int sample_rate_hz, int variant) {
182   rtc::StringBuilder ss;
183   ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
184   return ss.Release();
185 }
186 
RunAecInStereo(AudioBuffer & buffer,EchoCanceller3 & aec3,float channel_0_value,float channel_1_value)187 void RunAecInStereo(AudioBuffer& buffer,
188                     EchoCanceller3& aec3,
189                     float channel_0_value,
190                     float channel_1_value) {
191   rtc::ArrayView<float> data_channel_0(&buffer.channels()[0][0],
192                                        buffer.num_frames());
193   std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
194   rtc::ArrayView<float> data_channel_1(&buffer.channels()[1][0],
195                                        buffer.num_frames());
196   std::fill(data_channel_1.begin(), data_channel_1.end(), channel_1_value);
197   aec3.AnalyzeRender(&buffer);
198   aec3.AnalyzeCapture(&buffer);
199   aec3.ProcessCapture(&buffer, /*level_change=*/false);
200 }
201 
RunAecInSMono(AudioBuffer & buffer,EchoCanceller3 & aec3,float channel_0_value)202 void RunAecInSMono(AudioBuffer& buffer,
203                    EchoCanceller3& aec3,
204                    float channel_0_value) {
205   rtc::ArrayView<float> data_channel_0(&buffer.channels()[0][0],
206                                        buffer.num_frames());
207   std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
208   aec3.AnalyzeRender(&buffer);
209   aec3.AnalyzeCapture(&buffer);
210   aec3.ProcessCapture(&buffer, /*level_change=*/false);
211 }
212 
213 }  // namespace
214 
215 class EchoCanceller3Tester {
216  public:
EchoCanceller3Tester(int sample_rate_hz)217   explicit EchoCanceller3Tester(int sample_rate_hz)
218       : sample_rate_hz_(sample_rate_hz),
219         num_bands_(NumBandsForRate(sample_rate_hz_)),
220         frame_length_(160),
221         fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
222         capture_buffer_(fullband_frame_length_ * 100,
223                         1,
224                         fullband_frame_length_ * 100,
225                         1,
226                         fullband_frame_length_ * 100,
227                         1),
228         render_buffer_(fullband_frame_length_ * 100,
229                        1,
230                        fullband_frame_length_ * 100,
231                        1,
232                        fullband_frame_length_ * 100,
233                        1) {}
234 
235   EchoCanceller3Tester() = delete;
236   EchoCanceller3Tester(const EchoCanceller3Tester&) = delete;
237   EchoCanceller3Tester& operator=(const EchoCanceller3Tester&) = delete;
238 
239   // Verifies that the capture data is properly received by the block processor
240   // and that the processor data is properly passed to the EchoCanceller3
241   // output.
RunCaptureTransportVerificationTest()242   void RunCaptureTransportVerificationTest() {
243     EchoCanceller3 aec3(EchoCanceller3Config(),
244                         /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
245                         1, 1);
246     aec3.SetBlockProcessorForTesting(
247         std::make_unique<CaptureTransportVerificationProcessor>(num_bands_));
248 
249     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
250          ++frame_index) {
251       aec3.AnalyzeCapture(&capture_buffer_);
252       OptionalBandSplit();
253       PopulateInputFrame(frame_length_, num_bands_, frame_index,
254                          &capture_buffer_.split_bands(0)[0], 0);
255       PopulateInputFrame(frame_length_, frame_index,
256                          &render_buffer_.channels()[0][0], 0);
257 
258       aec3.AnalyzeRender(&render_buffer_);
259       aec3.ProcessCapture(&capture_buffer_, false);
260       EXPECT_TRUE(VerifyOutputFrameBitexactness(
261           frame_length_, num_bands_, frame_index,
262           &capture_buffer_.split_bands(0)[0], -64));
263     }
264   }
265 
266   // Test method for testing that the render data is properly received by the
267   // block processor.
RunRenderTransportVerificationTest()268   void RunRenderTransportVerificationTest() {
269     EchoCanceller3 aec3(EchoCanceller3Config(),
270                         /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
271                         1, 1);
272     aec3.SetBlockProcessorForTesting(
273         std::make_unique<RenderTransportVerificationProcessor>(num_bands_));
274 
275     std::vector<std::vector<float>> render_input(1);
276     std::vector<float> capture_output;
277     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
278          ++frame_index) {
279       aec3.AnalyzeCapture(&capture_buffer_);
280       OptionalBandSplit();
281       PopulateInputFrame(frame_length_, num_bands_, frame_index,
282                          &capture_buffer_.split_bands(0)[0], 100);
283       PopulateInputFrame(frame_length_, num_bands_, frame_index,
284                          &render_buffer_.split_bands(0)[0], 0);
285 
286       for (size_t k = 0; k < frame_length_; ++k) {
287         render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
288       }
289       aec3.AnalyzeRender(&render_buffer_);
290       aec3.ProcessCapture(&capture_buffer_, false);
291       for (size_t k = 0; k < frame_length_; ++k) {
292         capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
293       }
294     }
295 
296     EXPECT_TRUE(
297         VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
298   }
299 
300   // Verifies that information about echo path changes are properly propagated
301   // to the block processor.
302   // The cases tested are:
303   // -That no set echo path change flags are received when there is no echo path
304   // change.
305   // -That set echo path change flags are received and continues to be received
306   // as long as echo path changes are flagged.
307   // -That set echo path change flags are no longer received when echo path
308   // change events stop being flagged.
309   enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };
310 
RunEchoPathChangeVerificationTest(EchoPathChangeTestVariant echo_path_change_test_variant)311   void RunEchoPathChangeVerificationTest(
312       EchoPathChangeTestVariant echo_path_change_test_variant) {
313     constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
314     constexpr size_t kExpectedNumBlocksToProcess =
315         (kNumFramesToProcess * 160) / kBlockSize;
316     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
317         block_processor_mock(
318             new StrictMock<webrtc::test::MockBlockProcessor>());
319     EXPECT_CALL(*block_processor_mock, BufferRender(_))
320         .Times(kExpectedNumBlocksToProcess);
321     EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
322 
323     switch (echo_path_change_test_variant) {
324       case EchoPathChangeTestVariant::kNone:
325         EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
326             .Times(kExpectedNumBlocksToProcess);
327         break;
328       case EchoPathChangeTestVariant::kOneSticky:
329         EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
330             .Times(kExpectedNumBlocksToProcess);
331         break;
332       case EchoPathChangeTestVariant::kOneNonSticky:
333         EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
334             .Times(kNumFullBlocksPerFrame);
335         EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
336             .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
337         break;
338     }
339 
340     EchoCanceller3 aec3(EchoCanceller3Config(),
341                         /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
342                         1, 1);
343     aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
344 
345     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
346          ++frame_index) {
347       bool echo_path_change = false;
348       switch (echo_path_change_test_variant) {
349         case EchoPathChangeTestVariant::kNone:
350           break;
351         case EchoPathChangeTestVariant::kOneSticky:
352           echo_path_change = true;
353           break;
354         case EchoPathChangeTestVariant::kOneNonSticky:
355           if (frame_index == 0) {
356             echo_path_change = true;
357           }
358           break;
359       }
360 
361       aec3.AnalyzeCapture(&capture_buffer_);
362       OptionalBandSplit();
363 
364       PopulateInputFrame(frame_length_, num_bands_, frame_index,
365                          &capture_buffer_.split_bands(0)[0], 0);
366       PopulateInputFrame(frame_length_, frame_index,
367                          &render_buffer_.channels()[0][0], 0);
368 
369       aec3.AnalyzeRender(&render_buffer_);
370       aec3.ProcessCapture(&capture_buffer_, echo_path_change);
371     }
372   }
373 
374   // Test for verifying that echo leakage information is being properly passed
375   // to the processor.
376   // The cases tested are:
377   // -That no method calls are received when they should not.
378   // -That false values are received each time they are flagged.
379   // -That true values are received each time they are flagged.
380   // -That a false value is received when flagged after a true value has been
381   // flagged.
382   enum class EchoLeakageTestVariant {
383     kNone,
384     kFalseSticky,
385     kTrueSticky,
386     kTrueNonSticky
387   };
388 
RunEchoLeakageVerificationTest(EchoLeakageTestVariant leakage_report_variant)389   void RunEchoLeakageVerificationTest(
390       EchoLeakageTestVariant leakage_report_variant) {
391     constexpr size_t kExpectedNumBlocksToProcess =
392         (kNumFramesToProcess * 160) / kBlockSize;
393     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
394         block_processor_mock(
395             new StrictMock<webrtc::test::MockBlockProcessor>());
396     EXPECT_CALL(*block_processor_mock, BufferRender(_))
397         .Times(kExpectedNumBlocksToProcess);
398     EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
399         .Times(kExpectedNumBlocksToProcess);
400 
401     switch (leakage_report_variant) {
402       case EchoLeakageTestVariant::kNone:
403         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
404         break;
405       case EchoLeakageTestVariant::kFalseSticky:
406         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
407             .Times(1);
408         break;
409       case EchoLeakageTestVariant::kTrueSticky:
410         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
411             .Times(1);
412         break;
413       case EchoLeakageTestVariant::kTrueNonSticky: {
414         ::testing::InSequence s;
415         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
416             .Times(1);
417         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
418             .Times(kNumFramesToProcess - 1);
419       } break;
420     }
421 
422     EchoCanceller3 aec3(EchoCanceller3Config(),
423                         /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
424                         1, 1);
425     aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
426 
427     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
428          ++frame_index) {
429       switch (leakage_report_variant) {
430         case EchoLeakageTestVariant::kNone:
431           break;
432         case EchoLeakageTestVariant::kFalseSticky:
433           if (frame_index == 0) {
434             aec3.UpdateEchoLeakageStatus(false);
435           }
436           break;
437         case EchoLeakageTestVariant::kTrueSticky:
438           if (frame_index == 0) {
439             aec3.UpdateEchoLeakageStatus(true);
440           }
441           break;
442         case EchoLeakageTestVariant::kTrueNonSticky:
443           if (frame_index == 0) {
444             aec3.UpdateEchoLeakageStatus(true);
445           } else {
446             aec3.UpdateEchoLeakageStatus(false);
447           }
448           break;
449       }
450 
451       aec3.AnalyzeCapture(&capture_buffer_);
452       OptionalBandSplit();
453 
454       PopulateInputFrame(frame_length_, num_bands_, frame_index,
455                          &capture_buffer_.split_bands(0)[0], 0);
456       PopulateInputFrame(frame_length_, frame_index,
457                          &render_buffer_.channels()[0][0], 0);
458 
459       aec3.AnalyzeRender(&render_buffer_);
460       aec3.ProcessCapture(&capture_buffer_, false);
461     }
462   }
463 
464   // This verifies that saturation information is properly passed to the
465   // BlockProcessor.
466   // The cases tested are:
467   // -That no saturation event is passed to the processor if there is no
468   // saturation.
469   // -That one frame with one negative saturated sample value is reported to be
470   // saturated and that following non-saturated frames are properly reported as
471   // not being saturated.
472   // -That one frame with one positive saturated sample value is reported to be
473   // saturated and that following non-saturated frames are properly reported as
474   // not being saturated.
475   enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };
476 
RunCaptureSaturationVerificationTest(SaturationTestVariant saturation_variant)477   void RunCaptureSaturationVerificationTest(
478       SaturationTestVariant saturation_variant) {
479     const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
480     const size_t kExpectedNumBlocksToProcess =
481         (kNumFramesToProcess * 160) / kBlockSize;
482     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
483         block_processor_mock(
484             new StrictMock<webrtc::test::MockBlockProcessor>());
485     EXPECT_CALL(*block_processor_mock, BufferRender(_))
486         .Times(kExpectedNumBlocksToProcess);
487     EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
488 
489     switch (saturation_variant) {
490       case SaturationTestVariant::kNone:
491         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
492             .Times(kExpectedNumBlocksToProcess);
493         break;
494       case SaturationTestVariant::kOneNegative: {
495         ::testing::InSequence s;
496         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
497             .Times(kNumFullBlocksPerFrame);
498         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
499             .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
500       } break;
501       case SaturationTestVariant::kOnePositive: {
502         ::testing::InSequence s;
503         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
504             .Times(kNumFullBlocksPerFrame);
505         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
506             .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
507       } break;
508     }
509 
510     EchoCanceller3 aec3(EchoCanceller3Config(),
511                         /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
512                         1, 1);
513     aec3.SetBlockProcessorForTesting(std::move(block_processor_mock));
514     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
515          ++frame_index) {
516       for (int k = 0; k < fullband_frame_length_; ++k) {
517         capture_buffer_.channels()[0][k] = 0.f;
518       }
519       switch (saturation_variant) {
520         case SaturationTestVariant::kNone:
521           break;
522         case SaturationTestVariant::kOneNegative:
523           if (frame_index == 0) {
524             capture_buffer_.channels()[0][10] = -32768.f;
525           }
526           break;
527         case SaturationTestVariant::kOnePositive:
528           if (frame_index == 0) {
529             capture_buffer_.channels()[0][10] = 32767.f;
530           }
531           break;
532       }
533 
534       aec3.AnalyzeCapture(&capture_buffer_);
535       OptionalBandSplit();
536 
537       PopulateInputFrame(frame_length_, num_bands_, frame_index,
538                          &capture_buffer_.split_bands(0)[0], 0);
539       PopulateInputFrame(frame_length_, num_bands_, frame_index,
540                          &render_buffer_.split_bands(0)[0], 0);
541 
542       aec3.AnalyzeRender(&render_buffer_);
543       aec3.ProcessCapture(&capture_buffer_, false);
544     }
545   }
546 
547   // This test verifies that the swapqueue is able to handle jitter in the
548   // capture and render API calls.
RunRenderSwapQueueVerificationTest()549   void RunRenderSwapQueueVerificationTest() {
550     const EchoCanceller3Config config;
551     EchoCanceller3 aec3(config, /*multichannel_config=*/absl::nullopt,
552                         sample_rate_hz_, 1, 1);
553     aec3.SetBlockProcessorForTesting(
554         std::make_unique<RenderTransportVerificationProcessor>(num_bands_));
555 
556     std::vector<std::vector<float>> render_input(1);
557     std::vector<float> capture_output;
558 
559     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
560          ++frame_index) {
561       if (sample_rate_hz_ > 16000) {
562         render_buffer_.SplitIntoFrequencyBands();
563       }
564       PopulateInputFrame(frame_length_, num_bands_, frame_index,
565                          &render_buffer_.split_bands(0)[0], 0);
566 
567       if (sample_rate_hz_ > 16000) {
568         render_buffer_.SplitIntoFrequencyBands();
569       }
570 
571       for (size_t k = 0; k < frame_length_; ++k) {
572         render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
573       }
574       aec3.AnalyzeRender(&render_buffer_);
575     }
576 
577     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
578          ++frame_index) {
579       aec3.AnalyzeCapture(&capture_buffer_);
580       if (sample_rate_hz_ > 16000) {
581         capture_buffer_.SplitIntoFrequencyBands();
582       }
583 
584       PopulateInputFrame(frame_length_, num_bands_, frame_index,
585                          &capture_buffer_.split_bands(0)[0], 0);
586 
587       aec3.ProcessCapture(&capture_buffer_, false);
588       for (size_t k = 0; k < frame_length_; ++k) {
589         capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
590       }
591     }
592 
593     EXPECT_TRUE(
594         VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
595   }
596 
597   // This test verifies that a buffer overrun in the render swapqueue is
598   // properly reported.
RunRenderPipelineSwapQueueOverrunReturnValueTest()599   void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
600     EchoCanceller3 aec3(EchoCanceller3Config(),
601                         /*multichannel_config=*/absl::nullopt, sample_rate_hz_,
602                         1, 1);
603 
604     constexpr size_t kRenderTransferQueueSize = 30;
605     for (size_t k = 0; k < 2; ++k) {
606       for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
607            ++frame_index) {
608         if (sample_rate_hz_ > 16000) {
609           render_buffer_.SplitIntoFrequencyBands();
610         }
611         PopulateInputFrame(frame_length_, frame_index,
612                            &render_buffer_.channels()[0][0], 0);
613 
614         aec3.AnalyzeRender(&render_buffer_);
615       }
616     }
617   }
618 
619 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
620   // Verifies the that the check for the number of bands in the AnalyzeRender
621   // input is correct by adjusting the sample rates of EchoCanceller3 and the
622   // input AudioBuffer to have a different number of bands.
RunAnalyzeRenderNumBandsCheckVerification()623   void RunAnalyzeRenderNumBandsCheckVerification() {
624     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
625     // way that the number of bands for the rates are different.
626     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
627     EchoCanceller3 aec3(EchoCanceller3Config(),
628                         /*multichannel_config=*/absl::nullopt,
629                         aec3_sample_rate_hz, 1, 1);
630     PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
631 
632     EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
633   }
634 
635   // Verifies the that the check for the number of bands in the ProcessCapture
636   // input is correct by adjusting the sample rates of EchoCanceller3 and the
637   // input AudioBuffer to have a different number of bands.
RunProcessCaptureNumBandsCheckVerification()638   void RunProcessCaptureNumBandsCheckVerification() {
639     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
640     // way that the number of bands for the rates are different.
641     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
642     EchoCanceller3 aec3(EchoCanceller3Config(),
643                         /*multichannel_config=*/absl::nullopt,
644                         aec3_sample_rate_hz, 1, 1);
645     PopulateInputFrame(frame_length_, num_bands_, 0,
646                        &capture_buffer_.split_bands_f(0)[0], 100);
647     EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
648   }
649 
650 #endif
651 
652  private:
OptionalBandSplit()653   void OptionalBandSplit() {
654     if (sample_rate_hz_ > 16000) {
655       capture_buffer_.SplitIntoFrequencyBands();
656       render_buffer_.SplitIntoFrequencyBands();
657     }
658   }
659 
660   static constexpr size_t kNumFramesToProcess = 20;
661   const int sample_rate_hz_;
662   const size_t num_bands_;
663   const size_t frame_length_;
664   const int fullband_frame_length_;
665   AudioBuffer capture_buffer_;
666   AudioBuffer render_buffer_;
667 };
668 
TEST(EchoCanceller3Buffering,CaptureBitexactness)669 TEST(EchoCanceller3Buffering, CaptureBitexactness) {
670   for (auto rate : {16000, 32000, 48000}) {
671     SCOPED_TRACE(ProduceDebugText(rate));
672     EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
673   }
674 }
675 
TEST(EchoCanceller3Buffering,RenderBitexactness)676 TEST(EchoCanceller3Buffering, RenderBitexactness) {
677   for (auto rate : {16000, 32000, 48000}) {
678     SCOPED_TRACE(ProduceDebugText(rate));
679     EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
680   }
681 }
682 
TEST(EchoCanceller3Buffering,RenderSwapQueue)683 TEST(EchoCanceller3Buffering, RenderSwapQueue) {
684   EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
685 }
686 
TEST(EchoCanceller3Buffering,RenderSwapQueueOverrunReturnValue)687 TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
688   for (auto rate : {16000, 32000, 48000}) {
689     SCOPED_TRACE(ProduceDebugText(rate));
690     EchoCanceller3Tester(rate)
691         .RunRenderPipelineSwapQueueOverrunReturnValueTest();
692   }
693 }
694 
TEST(EchoCanceller3Messaging,CaptureSaturation)695 TEST(EchoCanceller3Messaging, CaptureSaturation) {
696   auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
697                    EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
698                    EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
699   for (auto rate : {16000, 32000, 48000}) {
700     for (auto variant : variants) {
701       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
702       EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
703     }
704   }
705 }
706 
TEST(EchoCanceller3Messaging,EchoPathChange)707 TEST(EchoCanceller3Messaging, EchoPathChange) {
708   auto variants = {
709       EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
710       EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
711       EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
712   for (auto rate : {16000, 32000, 48000}) {
713     for (auto variant : variants) {
714       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
715       EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
716     }
717   }
718 }
719 
TEST(EchoCanceller3Messaging,EchoLeakage)720 TEST(EchoCanceller3Messaging, EchoLeakage) {
721   auto variants = {
722       EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
723       EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
724       EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
725       EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
726   for (auto rate : {16000, 32000, 48000}) {
727     for (auto variant : variants) {
728       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
729       EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
730     }
731   }
732 }
733 
734 // Tests the parameter functionality for the field trial override for the
735 // anti-howling gain.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorAntiHowlingGainOverride)736 TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
737   EchoCanceller3Config default_config;
738   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
739   ASSERT_EQ(
740       default_config.suppressor.high_bands_suppression.anti_howling_gain,
741       adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
742 
743   webrtc::test::ScopedFieldTrials field_trials(
744       "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
745   adjusted_config = AdjustConfig(default_config);
746 
747   ASSERT_NE(
748       default_config.suppressor.high_bands_suppression.anti_howling_gain,
749       adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
750   EXPECT_FLOAT_EQ(
751       0.02f,
752       adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
753 }
754 
755 // Tests the field trial override for the enforcement of a low active render
756 // limit.
TEST(EchoCanceller3FieldTrials,Aec3EnforceLowActiveRenderLimit)757 TEST(EchoCanceller3FieldTrials, Aec3EnforceLowActiveRenderLimit) {
758   EchoCanceller3Config default_config;
759   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
760   ASSERT_EQ(default_config.render_levels.active_render_limit,
761             adjusted_config.render_levels.active_render_limit);
762 
763   webrtc::test::ScopedFieldTrials field_trials(
764       "WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
765   adjusted_config = AdjustConfig(default_config);
766 
767   ASSERT_NE(default_config.render_levels.active_render_limit,
768             adjusted_config.render_levels.active_render_limit);
769   EXPECT_FLOAT_EQ(50.f, adjusted_config.render_levels.active_render_limit);
770 }
771 
772 // Testing the field trial-based override of the suppressor parameters for a
773 // joint passing of all parameters.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorTuningOverrideAllParams)774 TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideAllParams) {
775   webrtc::test::ScopedFieldTrials field_trials(
776       "WebRTC-Aec3SuppressorTuningOverride/"
777       "nearend_tuning_mask_lf_enr_transparent:0.1,nearend_tuning_mask_lf_enr_"
778       "suppress:0.2,nearend_tuning_mask_hf_enr_transparent:0.3,nearend_tuning_"
779       "mask_hf_enr_suppress:0.4,nearend_tuning_max_inc_factor:0.5,nearend_"
780       "tuning_max_dec_factor_lf:0.6,normal_tuning_mask_lf_enr_transparent:0.7,"
781       "normal_tuning_mask_lf_enr_suppress:0.8,normal_tuning_mask_hf_enr_"
782       "transparent:0.9,normal_tuning_mask_hf_enr_suppress:1.0,normal_tuning_"
783       "max_inc_factor:1.1,normal_tuning_max_dec_factor_lf:1.2,dominant_nearend_"
784       "detection_enr_threshold:1.3,dominant_nearend_detection_enr_exit_"
785       "threshold:1.4,dominant_nearend_detection_snr_threshold:1.5,dominant_"
786       "nearend_detection_hold_duration:10,dominant_nearend_detection_trigger_"
787       "threshold:11/");
788 
789   EchoCanceller3Config default_config;
790   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
791 
792   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
793             default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
794   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
795             default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
796   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
797             default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
798   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
799             default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
800   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
801             default_config.suppressor.nearend_tuning.max_inc_factor);
802   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
803             default_config.suppressor.nearend_tuning.max_dec_factor_lf);
804   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
805             default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
806   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
807             default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
808   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
809             default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
810   ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
811             default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
812   ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_inc_factor,
813             default_config.suppressor.normal_tuning.max_inc_factor);
814   ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
815             default_config.suppressor.normal_tuning.max_dec_factor_lf);
816   ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
817             default_config.suppressor.dominant_nearend_detection.enr_threshold);
818   ASSERT_NE(
819       adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
820       default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
821   ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
822             default_config.suppressor.dominant_nearend_detection.snr_threshold);
823   ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
824             default_config.suppressor.dominant_nearend_detection.hold_duration);
825   ASSERT_NE(
826       adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
827       default_config.suppressor.dominant_nearend_detection.trigger_threshold);
828 
829   EXPECT_FLOAT_EQ(
830       adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent, 0.1);
831   EXPECT_FLOAT_EQ(
832       adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress, 0.2);
833   EXPECT_FLOAT_EQ(
834       adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent, 0.3);
835   EXPECT_FLOAT_EQ(
836       adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress, 0.4);
837   EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
838                   0.5);
839   EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
840                   0.6);
841   EXPECT_FLOAT_EQ(
842       adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent, 0.7);
843   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
844                   0.8);
845   EXPECT_FLOAT_EQ(
846       adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent, 0.9);
847   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
848                   1.0);
849   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor, 1.1);
850   EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
851                   1.2);
852   EXPECT_FLOAT_EQ(
853       adjusted_config.suppressor.dominant_nearend_detection.enr_threshold, 1.3);
854   EXPECT_FLOAT_EQ(
855       adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
856       1.4);
857   EXPECT_FLOAT_EQ(
858       adjusted_config.suppressor.dominant_nearend_detection.snr_threshold, 1.5);
859   EXPECT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
860             10);
861   EXPECT_EQ(
862       adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
863       11);
864 }
865 
866 // Testing the field trial-based override of the suppressor parameters for
867 // passing one parameter.
TEST(EchoCanceller3FieldTrials,Aec3SuppressorTuningOverrideOneParam)868 TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideOneParam) {
869   webrtc::test::ScopedFieldTrials field_trials(
870       "WebRTC-Aec3SuppressorTuningOverride/nearend_tuning_max_inc_factor:0.5/");
871 
872   EchoCanceller3Config default_config;
873   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
874 
875   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
876             default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
877   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
878             default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
879   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
880             default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
881   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
882             default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
883   ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
884             default_config.suppressor.nearend_tuning.max_dec_factor_lf);
885   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
886             default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
887   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
888             default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
889   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
890             default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
891   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
892             default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
893   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor,
894             default_config.suppressor.normal_tuning.max_inc_factor);
895   ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
896             default_config.suppressor.normal_tuning.max_dec_factor_lf);
897   ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
898             default_config.suppressor.dominant_nearend_detection.enr_threshold);
899   ASSERT_EQ(
900       adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
901       default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
902   ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
903             default_config.suppressor.dominant_nearend_detection.snr_threshold);
904   ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
905             default_config.suppressor.dominant_nearend_detection.hold_duration);
906   ASSERT_EQ(
907       adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
908       default_config.suppressor.dominant_nearend_detection.trigger_threshold);
909 
910   ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
911             default_config.suppressor.nearend_tuning.max_inc_factor);
912 
913   EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
914                   0.5);
915 }
916 
917 // Testing the field trial-based that override the exponential decay parameters.
TEST(EchoCanceller3FieldTrials,Aec3UseNearendReverb)918 TEST(EchoCanceller3FieldTrials, Aec3UseNearendReverb) {
919   webrtc::test::ScopedFieldTrials field_trials(
920       "WebRTC-Aec3UseNearendReverbLen/default_len:0.9,nearend_len:0.8/");
921   EchoCanceller3Config default_config;
922   EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
923   EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 0.9);
924   EXPECT_FLOAT_EQ(adjusted_config.ep_strength.nearend_len, 0.8);
925 }
926 
TEST(EchoCanceller3,DetectionOfProperStereo)927 TEST(EchoCanceller3, DetectionOfProperStereo) {
928   constexpr int kSampleRateHz = 16000;
929   constexpr int kNumChannels = 2;
930   AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
931                      /*input_num_channels=*/kNumChannels,
932                      /*input_rate=*/kSampleRateHz,
933                      /*buffer_num_channels=*/kNumChannels,
934                      /*output_rate=*/kSampleRateHz,
935                      /*output_num_channels=*/kNumChannels);
936 
937   constexpr size_t kNumBlocksForMonoConfig = 1;
938   constexpr size_t kNumBlocksForSurroundConfig = 2;
939   EchoCanceller3Config mono_config;
940   absl::optional<EchoCanceller3Config> multichannel_config;
941 
942   mono_config.multi_channel.detect_stereo_content = true;
943   mono_config.multi_channel.stereo_detection_threshold = 0.0f;
944   mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
945   multichannel_config = mono_config;
946   mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
947   multichannel_config->filter.coarse_initial.length_blocks =
948       kNumBlocksForSurroundConfig;
949 
950   EchoCanceller3 aec3(mono_config, multichannel_config,
951                       /*sample_rate_hz=*/kSampleRateHz,
952                       /*num_render_channels=*/kNumChannels,
953                       /*num_capture_input_channels=*/kNumChannels);
954 
955   EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
956   EXPECT_EQ(
957       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
958       kNumBlocksForMonoConfig);
959 
960   RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
961   EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
962   EXPECT_EQ(
963       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
964       kNumBlocksForMonoConfig);
965 
966   RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
967   EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
968   EXPECT_EQ(
969       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
970       kNumBlocksForSurroundConfig);
971 }
972 
TEST(EchoCanceller3,DetectionOfProperStereoUsingThreshold)973 TEST(EchoCanceller3, DetectionOfProperStereoUsingThreshold) {
974   constexpr int kSampleRateHz = 16000;
975   constexpr int kNumChannels = 2;
976   AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
977                      /*input_num_channels=*/kNumChannels,
978                      /*input_rate=*/kSampleRateHz,
979                      /*buffer_num_channels=*/kNumChannels,
980                      /*output_rate=*/kSampleRateHz,
981                      /*output_num_channels=*/kNumChannels);
982 
983   constexpr size_t kNumBlocksForMonoConfig = 1;
984   constexpr size_t kNumBlocksForSurroundConfig = 2;
985   EchoCanceller3Config mono_config;
986   absl::optional<EchoCanceller3Config> multichannel_config;
987 
988   constexpr float kStereoDetectionThreshold = 2.0f;
989   mono_config.multi_channel.detect_stereo_content = true;
990   mono_config.multi_channel.stereo_detection_threshold =
991       kStereoDetectionThreshold;
992   mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
993   multichannel_config = mono_config;
994   mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
995   multichannel_config->filter.coarse_initial.length_blocks =
996       kNumBlocksForSurroundConfig;
997 
998   EchoCanceller3 aec3(mono_config, multichannel_config,
999                       /*sample_rate_hz=*/kSampleRateHz,
1000                       /*num_render_channels=*/kNumChannels,
1001                       /*num_capture_input_channels=*/kNumChannels);
1002 
1003   EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1004   EXPECT_EQ(
1005       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1006       kNumBlocksForMonoConfig);
1007 
1008   RunAecInStereo(buffer, aec3, 100.0f,
1009                  100.0f + kStereoDetectionThreshold - 1.0f);
1010   EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1011   EXPECT_EQ(
1012       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1013       kNumBlocksForMonoConfig);
1014 
1015   RunAecInStereo(buffer, aec3, 100.0f,
1016                  100.0f + kStereoDetectionThreshold + 10.0f);
1017   EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
1018   EXPECT_EQ(
1019       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1020       kNumBlocksForSurroundConfig);
1021 }
1022 
TEST(EchoCanceller3,DetectionOfProperStereoUsingHysteresis)1023 TEST(EchoCanceller3, DetectionOfProperStereoUsingHysteresis) {
1024   constexpr int kSampleRateHz = 16000;
1025   constexpr int kNumChannels = 2;
1026   AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
1027                      /*input_num_channels=*/kNumChannels,
1028                      /*input_rate=*/kSampleRateHz,
1029                      /*buffer_num_channels=*/kNumChannels,
1030                      /*output_rate=*/kSampleRateHz,
1031                      /*output_num_channels=*/kNumChannels);
1032 
1033   constexpr size_t kNumBlocksForMonoConfig = 1;
1034   constexpr size_t kNumBlocksForSurroundConfig = 2;
1035   EchoCanceller3Config mono_config;
1036   absl::optional<EchoCanceller3Config> surround_config;
1037 
1038   mono_config.multi_channel.detect_stereo_content = true;
1039   mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.5f;
1040   surround_config = mono_config;
1041   mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
1042   surround_config->filter.coarse_initial.length_blocks =
1043       kNumBlocksForSurroundConfig;
1044 
1045   EchoCanceller3 aec3(mono_config, surround_config,
1046                       /*sample_rate_hz=*/kSampleRateHz,
1047                       /*num_render_channels=*/kNumChannels,
1048                       /*num_capture_input_channels=*/kNumChannels);
1049 
1050   EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1051   EXPECT_EQ(
1052       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1053       kNumBlocksForMonoConfig);
1054 
1055   RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
1056   EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1057   EXPECT_EQ(
1058       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1059       kNumBlocksForMonoConfig);
1060 
1061   constexpr int kNumFramesPerSecond = 100;
1062   for (int k = 0;
1063        k < static_cast<int>(
1064                kNumFramesPerSecond *
1065                mono_config.multi_channel.stereo_detection_hysteresis_seconds);
1066        ++k) {
1067     RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
1068     EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1069     EXPECT_EQ(
1070         aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1071         kNumBlocksForMonoConfig);
1072   }
1073 
1074   RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
1075   EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
1076   EXPECT_EQ(
1077       aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1078       kNumBlocksForSurroundConfig);
1079 }
1080 
TEST(EchoCanceller3,StereoContentDetectionForMonoSignals)1081 TEST(EchoCanceller3, StereoContentDetectionForMonoSignals) {
1082   constexpr int kSampleRateHz = 16000;
1083   constexpr int kNumChannels = 2;
1084   AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
1085                      /*input_num_channels=*/kNumChannels,
1086                      /*input_rate=*/kSampleRateHz,
1087                      /*buffer_num_channels=*/kNumChannels,
1088                      /*output_rate=*/kSampleRateHz,
1089                      /*output_num_channels=*/kNumChannels);
1090 
1091   constexpr size_t kNumBlocksForMonoConfig = 1;
1092   constexpr size_t kNumBlocksForSurroundConfig = 2;
1093   EchoCanceller3Config mono_config;
1094   absl::optional<EchoCanceller3Config> multichannel_config;
1095 
1096   for (bool detect_stereo_content : {false, true}) {
1097     mono_config.multi_channel.detect_stereo_content = detect_stereo_content;
1098     multichannel_config = mono_config;
1099     mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
1100     multichannel_config->filter.coarse_initial.length_blocks =
1101         kNumBlocksForSurroundConfig;
1102 
1103     AudioBuffer mono_buffer(/*input_rate=*/kSampleRateHz,
1104                             /*input_num_channels=*/1,
1105                             /*input_rate=*/kSampleRateHz,
1106                             /*buffer_num_channels=*/1,
1107                             /*output_rate=*/kSampleRateHz,
1108                             /*output_num_channels=*/1);
1109 
1110     EchoCanceller3 aec3(mono_config, multichannel_config,
1111                         /*sample_rate_hz=*/kSampleRateHz,
1112                         /*num_render_channels=*/1,
1113                         /*num_capture_input_channels=*/1);
1114 
1115     EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1116     EXPECT_EQ(
1117         aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1118         kNumBlocksForMonoConfig);
1119 
1120     RunAecInSMono(mono_buffer, aec3, 100.0f);
1121     EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
1122     EXPECT_EQ(
1123         aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
1124         kNumBlocksForMonoConfig);
1125   }
1126 }
1127 
1128 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
1129 
TEST(EchoCanceller3InputCheckDeathTest,WrongCaptureNumBandsCheckVerification)1130 TEST(EchoCanceller3InputCheckDeathTest, WrongCaptureNumBandsCheckVerification) {
1131   for (auto rate : {16000, 32000, 48000}) {
1132     SCOPED_TRACE(ProduceDebugText(rate));
1133     EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
1134   }
1135 }
1136 
1137 // Verifiers that the verification for null input to the capture processing api
1138 // call works.
TEST(EchoCanceller3InputCheckDeathTest,NullCaptureProcessingParameter)1139 TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
1140   EXPECT_DEATH(
1141       EchoCanceller3(EchoCanceller3Config(),
1142                      /*multichannel_config_=*/absl::nullopt, 16000, 1, 1)
1143           .ProcessCapture(nullptr, false),
1144       "");
1145 }
1146 
1147 // Verifies the check for correct sample rate.
1148 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
1149 // tests on test bots has been fixed.
TEST(EchoCanceller3InputCheckDeathTest,DISABLED_WrongSampleRate)1150 TEST(EchoCanceller3InputCheckDeathTest, DISABLED_WrongSampleRate) {
1151   ApmDataDumper data_dumper(0);
1152   EXPECT_DEATH(
1153       EchoCanceller3(EchoCanceller3Config(),
1154                      /*multichannel_config_=*/absl::nullopt, 8001, 1, 1),
1155       "");
1156 }
1157 
1158 #endif
1159 
1160 }  // namespace webrtc
1161