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 <sstream>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "modules/audio_processing/aec3/aec3_common.h"
21 #include "modules/audio_processing/aec3/block_processor.h"
22 #include "modules/audio_processing/aec3/frame_blocker.h"
23 #include "modules/audio_processing/aec3/mock/mock_block_processor.h"
24 #include "modules/audio_processing/audio_buffer.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27 
28 namespace webrtc {
29 namespace {
30 
31 using testing::StrictMock;
32 using testing::_;
33 
34 // Populates the frame with linearly increasing sample values for each band,
35 // with a band-specific offset, in order to allow simple bitexactness
36 // verification for each band.
PopulateInputFrame(size_t frame_length,size_t num_bands,size_t frame_index,float * const * frame,int offset)37 void PopulateInputFrame(size_t frame_length,
38                         size_t num_bands,
39                         size_t frame_index,
40                         float* const* frame,
41                         int offset) {
42   for (size_t k = 0; k < num_bands; ++k) {
43     for (size_t i = 0; i < frame_length; ++i) {
44       float value = static_cast<int>(frame_index * frame_length + i) + offset;
45       frame[k][i] = (value > 0 ? 5000 * k + value : 0);
46     }
47   }
48 }
49 
50 // Populates the frame with linearly increasing sample values.
PopulateInputFrame(size_t frame_length,size_t frame_index,float * frame,int offset)51 void PopulateInputFrame(size_t frame_length,
52                         size_t frame_index,
53                         float* frame,
54                         int offset) {
55   for (size_t i = 0; i < frame_length; ++i) {
56     float value = static_cast<int>(frame_index * frame_length + i) + offset;
57     frame[i] = std::max(value, 0.f);
58   }
59 }
60 
61 // Verifies the that samples in the output frame are identical to the samples
62 // that were produced for the input frame, with an offset in order to compensate
63 // for buffering delays.
VerifyOutputFrameBitexactness(size_t frame_length,size_t num_bands,size_t frame_index,const float * const * frame,int offset)64 bool VerifyOutputFrameBitexactness(size_t frame_length,
65                                    size_t num_bands,
66                                    size_t frame_index,
67                                    const float* const* frame,
68                                    int offset) {
69   float reference_frame_data[kMaxNumBands][2 * kSubFrameLength];
70   float* reference_frame[kMaxNumBands];
71   for (size_t k = 0; k < num_bands; ++k) {
72     reference_frame[k] = &reference_frame_data[k][0];
73   }
74 
75   PopulateInputFrame(frame_length, num_bands, frame_index, reference_frame,
76                      offset);
77   for (size_t k = 0; k < num_bands; ++k) {
78     for (size_t i = 0; i < frame_length; ++i) {
79       if (reference_frame[k][i] != frame[k][i]) {
80         return false;
81       }
82     }
83   }
84 
85   return true;
86 }
87 
88 // Class for testing that the capture data is properly received by the block
89 // processor and that the processor data is properly passed to the
90 // EchoCanceller3 output.
91 class CaptureTransportVerificationProcessor : public BlockProcessor {
92  public:
CaptureTransportVerificationProcessor(size_t num_bands)93   explicit CaptureTransportVerificationProcessor(size_t num_bands) {}
94   ~CaptureTransportVerificationProcessor() override = default;
95 
ProcessCapture(bool level_change,bool saturated_microphone_signal,std::vector<std::vector<float>> * capture_block)96   void ProcessCapture(bool level_change,
97                       bool saturated_microphone_signal,
98                       std::vector<std::vector<float>>* capture_block) override {
99   }
100 
BufferRender(const std::vector<std::vector<float>> & block)101   void BufferRender(const std::vector<std::vector<float>>& block) override {}
102 
UpdateEchoLeakageStatus(bool leakage_detected)103   void UpdateEchoLeakageStatus(bool leakage_detected) override {}
104 
GetMetrics(EchoControl::Metrics * metrics) const105   void GetMetrics(EchoControl::Metrics* metrics) const override {}
106 
107  private:
108   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTransportVerificationProcessor);
109 };
110 
111 // Class for testing that the render data is properly received by the block
112 // processor.
113 class RenderTransportVerificationProcessor : public BlockProcessor {
114  public:
RenderTransportVerificationProcessor(size_t num_bands)115   explicit RenderTransportVerificationProcessor(size_t num_bands) {}
116   ~RenderTransportVerificationProcessor() override = default;
117 
ProcessCapture(bool level_change,bool saturated_microphone_signal,std::vector<std::vector<float>> * capture_block)118   void ProcessCapture(bool level_change,
119                       bool saturated_microphone_signal,
120                       std::vector<std::vector<float>>* capture_block) override {
121     std::vector<std::vector<float>> render_block =
122         received_render_blocks_.front();
123     received_render_blocks_.pop_front();
124     capture_block->swap(render_block);
125   }
126 
BufferRender(const std::vector<std::vector<float>> & block)127   void BufferRender(const std::vector<std::vector<float>>& block) override {
128     received_render_blocks_.push_back(block);
129   }
130 
UpdateEchoLeakageStatus(bool leakage_detected)131   void UpdateEchoLeakageStatus(bool leakage_detected) override {}
132 
GetMetrics(EchoControl::Metrics * metrics) const133   void GetMetrics(EchoControl::Metrics* metrics) const override {}
134 
135  private:
136   std::deque<std::vector<std::vector<float>>> received_render_blocks_;
137   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderTransportVerificationProcessor);
138 };
139 
140 class EchoCanceller3Tester {
141  public:
EchoCanceller3Tester(int sample_rate_hz)142   explicit EchoCanceller3Tester(int sample_rate_hz)
143       : sample_rate_hz_(sample_rate_hz),
144         num_bands_(NumBandsForRate(sample_rate_hz_)),
145         frame_length_(sample_rate_hz_ == 8000 ? 80 : 160),
146         fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
147         capture_buffer_(fullband_frame_length_,
148                         1,
149                         fullband_frame_length_,
150                         1,
151                         fullband_frame_length_),
152         render_buffer_(fullband_frame_length_,
153                        1,
154                        fullband_frame_length_,
155                        1,
156                        fullband_frame_length_) {}
157 
158   // Verifies that the capture data is properly received by the block processor
159   // and that the processor data is properly passed to the EchoCanceller3
160   // output.
RunCaptureTransportVerificationTest()161   void RunCaptureTransportVerificationTest() {
162     EchoCanceller3 aec3(
163         sample_rate_hz_, false,
164         std::unique_ptr<BlockProcessor>(
165             new CaptureTransportVerificationProcessor(num_bands_)));
166 
167     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
168          ++frame_index) {
169       aec3.AnalyzeCapture(&capture_buffer_);
170       OptionalBandSplit();
171       PopulateInputFrame(frame_length_, num_bands_, frame_index,
172                          &capture_buffer_.split_bands_f(0)[0], 0);
173       PopulateInputFrame(frame_length_, frame_index,
174                          &render_buffer_.channels_f()[0][0], 0);
175 
176       aec3.AnalyzeRender(&render_buffer_);
177       aec3.ProcessCapture(&capture_buffer_, false);
178       EXPECT_TRUE(VerifyOutputFrameBitexactness(
179           frame_length_, num_bands_, frame_index,
180           &capture_buffer_.split_bands_f(0)[0], -64));
181     }
182   }
183 
184   // Test method for testing that the render data is properly received by the
185   // block processor.
RunRenderTransportVerificationTest()186   void RunRenderTransportVerificationTest() {
187     EchoCanceller3 aec3(
188         sample_rate_hz_, false,
189         std::unique_ptr<BlockProcessor>(
190             new RenderTransportVerificationProcessor(num_bands_)));
191 
192     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
193          ++frame_index) {
194       aec3.AnalyzeCapture(&capture_buffer_);
195       OptionalBandSplit();
196       PopulateInputFrame(frame_length_, num_bands_, frame_index,
197                          &capture_buffer_.split_bands_f(0)[0], 100);
198       PopulateInputFrame(frame_length_, num_bands_, frame_index,
199                          &render_buffer_.split_bands_f(0)[0], 0);
200 
201       aec3.AnalyzeRender(&render_buffer_);
202       aec3.ProcessCapture(&capture_buffer_, false);
203       EXPECT_TRUE(VerifyOutputFrameBitexactness(
204           frame_length_, num_bands_, frame_index,
205           &capture_buffer_.split_bands_f(0)[0], -64));
206     }
207   }
208 
209   // Verifies that information about echo path changes are properly propagated
210   // to the block processor.
211   // The cases tested are:
212   // -That no set echo path change flags are received when there is no echo path
213   // change.
214   // -That set echo path change flags are received and continues to be received
215   // as long as echo path changes are flagged.
216   // -That set echo path change flags are no longer received when echo path
217   // change events stop being flagged.
218   enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };
219 
RunEchoPathChangeVerificationTest(EchoPathChangeTestVariant echo_path_change_test_variant)220   void RunEchoPathChangeVerificationTest(
221       EchoPathChangeTestVariant echo_path_change_test_variant) {
222     const size_t num_full_blocks_per_frame =
223         rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100) / kBlockSize;
224     const size_t expected_num_block_to_process =
225         (kNumFramesToProcess *
226          rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)) /
227         kBlockSize;
228     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
229         block_processor_mock(
230             new StrictMock<webrtc::test::MockBlockProcessor>());
231     EXPECT_CALL(*block_processor_mock, BufferRender(_))
232         .Times(expected_num_block_to_process);
233     EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
234 
235     switch (echo_path_change_test_variant) {
236       case EchoPathChangeTestVariant::kNone:
237         EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _))
238             .Times(expected_num_block_to_process);
239         break;
240       case EchoPathChangeTestVariant::kOneSticky:
241         EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _))
242             .Times(expected_num_block_to_process);
243         break;
244       case EchoPathChangeTestVariant::kOneNonSticky:
245         EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _))
246             .Times(num_full_blocks_per_frame);
247         EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _))
248             .Times(expected_num_block_to_process - num_full_blocks_per_frame);
249         break;
250     }
251 
252     EchoCanceller3 aec3(sample_rate_hz_, false,
253                         std::move(block_processor_mock));
254 
255     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
256          ++frame_index) {
257       bool echo_path_change = false;
258       switch (echo_path_change_test_variant) {
259         case EchoPathChangeTestVariant::kNone:
260           break;
261         case EchoPathChangeTestVariant::kOneSticky:
262           echo_path_change = true;
263           break;
264         case EchoPathChangeTestVariant::kOneNonSticky:
265           if (frame_index == 0) {
266             echo_path_change = true;
267           }
268           break;
269       }
270 
271       aec3.AnalyzeCapture(&capture_buffer_);
272       OptionalBandSplit();
273 
274       PopulateInputFrame(frame_length_, num_bands_, frame_index,
275                          &capture_buffer_.split_bands_f(0)[0], 0);
276       PopulateInputFrame(frame_length_, frame_index,
277                          &render_buffer_.channels_f()[0][0], 0);
278 
279       aec3.AnalyzeRender(&render_buffer_);
280       aec3.ProcessCapture(&capture_buffer_, echo_path_change);
281     }
282   }
283 
284   // Test for verifying that echo leakage information is being properly passed
285   // to the processor.
286   // The cases tested are:
287   // -That no method calls are received when they should not.
288   // -That false values are received each time they are flagged.
289   // -That true values are received each time they are flagged.
290   // -That a false value is received when flagged after a true value has been
291   // flagged.
292   enum class EchoLeakageTestVariant {
293     kNone,
294     kFalseSticky,
295     kTrueSticky,
296     kTrueNonSticky
297   };
298 
RunEchoLeakageVerificationTest(EchoLeakageTestVariant leakage_report_variant)299   void RunEchoLeakageVerificationTest(
300       EchoLeakageTestVariant leakage_report_variant) {
301     const size_t expected_num_block_to_process =
302         (kNumFramesToProcess *
303          rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)) /
304         kBlockSize;
305     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
306         block_processor_mock(
307             new StrictMock<webrtc::test::MockBlockProcessor>());
308     EXPECT_CALL(*block_processor_mock, BufferRender(_))
309         .Times(expected_num_block_to_process);
310     EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _))
311         .Times(expected_num_block_to_process);
312 
313     switch (leakage_report_variant) {
314       case EchoLeakageTestVariant::kNone:
315         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
316         break;
317       case EchoLeakageTestVariant::kFalseSticky:
318         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
319             .Times(1);
320         break;
321       case EchoLeakageTestVariant::kTrueSticky:
322         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
323             .Times(1);
324         break;
325       case EchoLeakageTestVariant::kTrueNonSticky: {
326         testing::InSequence s;
327         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
328             .Times(1);
329         EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
330             .Times(kNumFramesToProcess - 1);
331       } break;
332     }
333 
334     EchoCanceller3 aec3(sample_rate_hz_, false,
335                         std::move(block_processor_mock));
336 
337     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
338          ++frame_index) {
339       switch (leakage_report_variant) {
340         case EchoLeakageTestVariant::kNone:
341           break;
342         case EchoLeakageTestVariant::kFalseSticky:
343           if (frame_index == 0) {
344             aec3.UpdateEchoLeakageStatus(false);
345           }
346           break;
347         case EchoLeakageTestVariant::kTrueSticky:
348           if (frame_index == 0) {
349             aec3.UpdateEchoLeakageStatus(true);
350           }
351           break;
352         case EchoLeakageTestVariant::kTrueNonSticky:
353           if (frame_index == 0) {
354             aec3.UpdateEchoLeakageStatus(true);
355           } else {
356             aec3.UpdateEchoLeakageStatus(false);
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_f(0)[0], 0);
366       PopulateInputFrame(frame_length_, frame_index,
367                          &render_buffer_.channels_f()[0][0], 0);
368 
369       aec3.AnalyzeRender(&render_buffer_);
370       aec3.ProcessCapture(&capture_buffer_, false);
371     }
372   }
373 
374   // This verifies that saturation information is properly passed to the
375   // BlockProcessor.
376   // The cases tested are:
377   // -That no saturation event is passed to the processor if there is no
378   // saturation.
379   // -That one frame with one negative saturated sample value is reported to be
380   // saturated and that following non-saturated frames are properly reported as
381   // not being saturated.
382   // -That one frame with one positive saturated sample value is reported to be
383   // saturated and that following non-saturated frames are properly reported as
384   // not being saturated.
385   enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };
386 
RunCaptureSaturationVerificationTest(SaturationTestVariant saturation_variant)387   void RunCaptureSaturationVerificationTest(
388       SaturationTestVariant saturation_variant) {
389     const size_t num_full_blocks_per_frame =
390         rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100) / kBlockSize;
391     const size_t expected_num_block_to_process =
392         (kNumFramesToProcess *
393          rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)) /
394         kBlockSize;
395     std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
396         block_processor_mock(
397             new StrictMock<webrtc::test::MockBlockProcessor>());
398     EXPECT_CALL(*block_processor_mock, BufferRender(_))
399         .Times(expected_num_block_to_process);
400     EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
401 
402     switch (saturation_variant) {
403       case SaturationTestVariant::kNone:
404         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _))
405             .Times(expected_num_block_to_process);
406         break;
407       case SaturationTestVariant::kOneNegative: {
408         testing::InSequence s;
409         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _))
410             .Times(num_full_blocks_per_frame);
411         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _))
412             .Times(expected_num_block_to_process - num_full_blocks_per_frame);
413       } break;
414       case SaturationTestVariant::kOnePositive: {
415         testing::InSequence s;
416         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _))
417             .Times(num_full_blocks_per_frame);
418         EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _))
419             .Times(expected_num_block_to_process - num_full_blocks_per_frame);
420       } break;
421     }
422 
423     EchoCanceller3 aec3(sample_rate_hz_, false,
424                         std::move(block_processor_mock));
425     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
426          ++frame_index) {
427       for (int k = 0; k < fullband_frame_length_; ++k) {
428         capture_buffer_.channels_f()[0][k] = 0.f;
429       }
430       switch (saturation_variant) {
431         case SaturationTestVariant::kNone:
432           break;
433         case SaturationTestVariant::kOneNegative:
434           if (frame_index == 0) {
435             capture_buffer_.channels_f()[0][10] = -32768.f;
436           }
437           break;
438         case SaturationTestVariant::kOnePositive:
439           if (frame_index == 0) {
440             capture_buffer_.channels_f()[0][10] = 32767.f;
441           }
442           break;
443       }
444 
445       aec3.AnalyzeCapture(&capture_buffer_);
446       OptionalBandSplit();
447 
448       PopulateInputFrame(frame_length_, num_bands_, frame_index,
449                          &capture_buffer_.split_bands_f(0)[0], 0);
450       PopulateInputFrame(frame_length_, num_bands_, frame_index,
451                          &render_buffer_.split_bands_f(0)[0], 0);
452 
453       aec3.AnalyzeRender(&render_buffer_);
454       aec3.ProcessCapture(&capture_buffer_, false);
455     }
456   }
457 
458   // This test verifies that the swapqueue is able to handle jitter in the
459   // capture and render API calls.
RunRenderSwapQueueVerificationTest()460   void RunRenderSwapQueueVerificationTest() {
461     EchoCanceller3 aec3(
462         sample_rate_hz_, false,
463         std::unique_ptr<BlockProcessor>(
464             new RenderTransportVerificationProcessor(num_bands_)));
465 
466     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
467          ++frame_index) {
468       if (sample_rate_hz_ > 16000) {
469         render_buffer_.SplitIntoFrequencyBands();
470       }
471       PopulateInputFrame(frame_length_, num_bands_, frame_index,
472                          &render_buffer_.split_bands_f(0)[0], 0);
473 
474       if (sample_rate_hz_ > 16000) {
475         render_buffer_.SplitIntoFrequencyBands();
476       }
477 
478       aec3.AnalyzeRender(&render_buffer_);
479     }
480 
481     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
482          ++frame_index) {
483       aec3.AnalyzeCapture(&capture_buffer_);
484       if (sample_rate_hz_ > 16000) {
485         capture_buffer_.SplitIntoFrequencyBands();
486       }
487 
488       PopulateInputFrame(frame_length_, num_bands_, frame_index,
489                          &capture_buffer_.split_bands_f(0)[0], 0);
490 
491       aec3.ProcessCapture(&capture_buffer_, false);
492       EXPECT_TRUE(VerifyOutputFrameBitexactness(
493           frame_length_, num_bands_, frame_index,
494           &capture_buffer_.split_bands_f(0)[0], -64));
495     }
496   }
497 
498   // This test verifies that a buffer overrun in the render swapqueue is
499   // properly reported.
RunRenderPipelineSwapQueueOverrunReturnValueTest()500   void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
501     EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, false);
502 
503     constexpr size_t kRenderTransferQueueSize = 30;
504     for (size_t k = 0; k < 2; ++k) {
505       for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
506            ++frame_index) {
507         if (sample_rate_hz_ > 16000) {
508           render_buffer_.SplitIntoFrequencyBands();
509         }
510         PopulateInputFrame(frame_length_, frame_index,
511                            &render_buffer_.channels_f()[0][0], 0);
512 
513         if (k == 0) {
514           aec3.AnalyzeRender(&render_buffer_);
515         } else {
516           aec3.AnalyzeRender(&render_buffer_);
517         }
518       }
519     }
520   }
521 
522 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
523   // Verifies the that the check for the number of bands in the AnalyzeRender
524   // input is correct by adjusting the sample rates of EchoCanceller3 and the
525   // input AudioBuffer to have a different number of bands.
RunAnalyzeRenderNumBandsCheckVerification()526   void RunAnalyzeRenderNumBandsCheckVerification() {
527     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
528     // way that the number of bands for the rates are different.
529     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
530     EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false);
531     PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
532 
533     EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
534   }
535 
536   // Verifies the that the check for the number of bands in the ProcessCapture
537   // input is correct by adjusting the sample rates of EchoCanceller3 and the
538   // input AudioBuffer to have a different number of bands.
RunProcessCaptureNumBandsCheckVerification()539   void RunProcessCaptureNumBandsCheckVerification() {
540     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
541     // way that the number of bands for the rates are different.
542     const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
543     EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false);
544     PopulateInputFrame(frame_length_, num_bands_, 0,
545                        &capture_buffer_.split_bands_f(0)[0], 100);
546     EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
547   }
548 
549   // Verifies the that the check for the frame length in the AnalyzeRender input
550   // is correct by adjusting the sample rates of EchoCanceller3 and the input
551   // AudioBuffer to have a different frame lengths.
RunAnalyzeRenderFrameLengthCheckVerification()552   void RunAnalyzeRenderFrameLengthCheckVerification() {
553     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
554     // way that the band frame lengths are different.
555     const int aec3_sample_rate_hz = sample_rate_hz_ == 8000 ? 16000 : 8000;
556     EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false);
557 
558     OptionalBandSplit();
559     PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
560 
561     EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
562   }
563 
564   // Verifies the that the check for the frame length in the AnalyzeRender input
565   // is correct by adjusting the sample rates of EchoCanceller3 and the input
566   // AudioBuffer to have a different frame lengths.
RunProcessCaptureFrameLengthCheckVerification()567   void RunProcessCaptureFrameLengthCheckVerification() {
568     // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
569     // way that the band frame lengths are different.
570     const int aec3_sample_rate_hz = sample_rate_hz_ == 8000 ? 16000 : 8000;
571     EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false);
572 
573     OptionalBandSplit();
574     PopulateInputFrame(frame_length_, num_bands_, 0,
575                        &capture_buffer_.split_bands_f(0)[0], 100);
576 
577     EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
578   }
579 
580 #endif
581 
582  private:
OptionalBandSplit()583   void OptionalBandSplit() {
584     if (sample_rate_hz_ > 16000) {
585       capture_buffer_.SplitIntoFrequencyBands();
586       render_buffer_.SplitIntoFrequencyBands();
587     }
588   }
589 
590   static constexpr size_t kNumFramesToProcess = 20;
591   const int sample_rate_hz_;
592   const size_t num_bands_;
593   const size_t frame_length_;
594   const int fullband_frame_length_;
595   AudioBuffer capture_buffer_;
596   AudioBuffer render_buffer_;
597 
598   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCanceller3Tester);
599 };
600 
ProduceDebugText(int sample_rate_hz)601 std::string ProduceDebugText(int sample_rate_hz) {
602   std::ostringstream ss;
603   ss << "Sample rate: " << sample_rate_hz;
604   return ss.str();
605 }
606 
ProduceDebugText(int sample_rate_hz,int variant)607 std::string ProduceDebugText(int sample_rate_hz, int variant) {
608   std::ostringstream ss;
609   ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
610   return ss.str();
611 }
612 
613 }  // namespace
614 
TEST(EchoCanceller3Buffering,CaptureBitexactness)615 TEST(EchoCanceller3Buffering, CaptureBitexactness) {
616   for (auto rate : {8000, 16000, 32000, 48000}) {
617     SCOPED_TRACE(ProduceDebugText(rate));
618     EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
619   }
620 }
621 
TEST(EchoCanceller3Buffering,RenderBitexactness)622 TEST(EchoCanceller3Buffering, RenderBitexactness) {
623   for (auto rate : {8000, 16000, 32000, 48000}) {
624     SCOPED_TRACE(ProduceDebugText(rate));
625     EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
626   }
627 }
628 
TEST(EchoCanceller3Buffering,RenderSwapQueue)629 TEST(EchoCanceller3Buffering, RenderSwapQueue) {
630   for (auto rate : {8000, 16000}) {
631     SCOPED_TRACE(ProduceDebugText(rate));
632     EchoCanceller3Tester(rate).RunRenderSwapQueueVerificationTest();
633   }
634 }
635 
TEST(EchoCanceller3Buffering,RenderSwapQueueOverrunReturnValue)636 TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
637   for (auto rate : {8000, 16000, 32000, 48000}) {
638     SCOPED_TRACE(ProduceDebugText(rate));
639     EchoCanceller3Tester(rate)
640         .RunRenderPipelineSwapQueueOverrunReturnValueTest();
641   }
642 }
643 
TEST(EchoCanceller3Messaging,CaptureSaturation)644 TEST(EchoCanceller3Messaging, CaptureSaturation) {
645   auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
646                    EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
647                    EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
648   for (auto rate : {8000, 16000, 32000, 48000}) {
649     for (auto variant : variants) {
650       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
651       EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
652     }
653   }
654 }
655 
TEST(EchoCanceller3Messaging,EchoPathChange)656 TEST(EchoCanceller3Messaging, EchoPathChange) {
657   auto variants = {
658       EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
659       EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
660       EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
661   for (auto rate : {8000, 16000, 32000, 48000}) {
662     for (auto variant : variants) {
663       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
664       EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
665     }
666   }
667 }
668 
TEST(EchoCanceller3Messaging,EchoLeakage)669 TEST(EchoCanceller3Messaging, EchoLeakage) {
670   auto variants = {
671       EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
672       EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
673       EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
674       EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
675   for (auto rate : {8000, 16000, 32000, 48000}) {
676     for (auto variant : variants) {
677       SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
678       EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
679     }
680   }
681 }
682 
TEST(EchoCanceller3,ConfigValidation)683 TEST(EchoCanceller3, ConfigValidation) {
684   EchoCanceller3Config config;
685   EXPECT_TRUE(EchoCanceller3::Validate(config));
686 }
687 
688 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
689 
TEST(EchoCanceller3InputCheck,WrongCaptureNumBandsCheckVerification)690 TEST(EchoCanceller3InputCheck, WrongCaptureNumBandsCheckVerification) {
691   for (auto rate : {8000, 16000, 32000, 48000}) {
692     SCOPED_TRACE(ProduceDebugText(rate));
693     EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
694   }
695 }
696 
697 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
698 // tests on test bots has been fixed.
TEST(EchoCanceller3InputCheck,DISABLED_WrongRenderFrameLengthCheckVerification)699 TEST(EchoCanceller3InputCheck,
700      DISABLED_WrongRenderFrameLengthCheckVerification) {
701   for (auto rate : {8000, 16000}) {
702     SCOPED_TRACE(ProduceDebugText(rate));
703     EchoCanceller3Tester(rate).RunAnalyzeRenderFrameLengthCheckVerification();
704   }
705 }
706 
TEST(EchoCanceller3InputCheck,WrongCaptureFrameLengthCheckVerification)707 TEST(EchoCanceller3InputCheck, WrongCaptureFrameLengthCheckVerification) {
708   for (auto rate : {8000, 16000}) {
709     SCOPED_TRACE(ProduceDebugText(rate));
710     EchoCanceller3Tester(rate).RunProcessCaptureFrameLengthCheckVerification();
711   }
712 }
713 
714 // Verifiers that the verification for null input to the render analysis api
715 // call works.
TEST(EchoCanceller3InputCheck,NullRenderAnalysisParameter)716 TEST(EchoCanceller3InputCheck, NullRenderAnalysisParameter) {
717   EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8000, false)
718                    .AnalyzeRender(nullptr),
719                "");
720 }
721 
722 // Verifiers that the verification for null input to the capture analysis api
723 // call works.
TEST(EchoCanceller3InputCheck,NullCaptureAnalysisParameter)724 TEST(EchoCanceller3InputCheck, NullCaptureAnalysisParameter) {
725   EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8000, false)
726                    .AnalyzeCapture(nullptr),
727                "");
728 }
729 
730 // Verifiers that the verification for null input to the capture processing api
731 // call works.
TEST(EchoCanceller3InputCheck,NullCaptureProcessingParameter)732 TEST(EchoCanceller3InputCheck, NullCaptureProcessingParameter) {
733   EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8000, false)
734                    .ProcessCapture(nullptr, false),
735                "");
736 }
737 
738 // Verifies the check for correct sample rate.
739 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
740 // tests on test bots has been fixed.
TEST(EchoCanceller3InputCheck,DISABLED_WrongSampleRate)741 TEST(EchoCanceller3InputCheck, DISABLED_WrongSampleRate) {
742   ApmDataDumper data_dumper(0);
743   EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001, false), "");
744 }
745 
746 #endif
747 
748 }  // namespace webrtc
749