blob: 21255f192e12f4a7e2c07195cc6c298d60076815 [file] [log] [blame]
peahd0263542017-01-03 04:20:34 -08001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/aec3/echo_canceller3.h"
peahd0263542017-01-03 04:20:34 -080012
13#include <deque>
14#include <memory>
peahd0263542017-01-03 04:20:34 -080015#include <string>
16#include <utility>
17#include <vector>
18
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#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"
Per Åhgren0aefbf02019-08-23 21:29:17 +020024#include "modules/audio_processing/high_pass_filter.h"
25#include "modules/audio_processing/utility/cascaded_biquad_filter.h"
Jonas Olsson366a50c2018-09-06 13:41:30 +020026#include "rtc_base/strings/string_builder.h"
Per Åhgren80e52162020-04-06 14:57:52 +020027#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "test/gmock.h"
29#include "test/gtest.h"
peahd0263542017-01-03 04:20:34 -080030
31namespace webrtc {
32namespace {
33
Mirko Bonadei6a489f22019-04-09 15:11:12 +020034using ::testing::_;
35using ::testing::StrictMock;
peahd0263542017-01-03 04:20:34 -080036
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.
40void 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
peah522d71b2017-02-23 05:16:26 -080053// Populates the frame with linearly increasing sample values.
54void 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
peahd0263542017-01-03 04:20:34 -080064// 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.
67bool 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
Per Åhgren0aefbf02019-08-23 21:29:17 +020091bool 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
peahd0263542017-01-03 04:20:34 -0800105// 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.
108class CaptureTransportVerificationProcessor : public BlockProcessor {
109 public:
110 explicit CaptureTransportVerificationProcessor(size_t num_bands) {}
111 ~CaptureTransportVerificationProcessor() override = default;
112
Per Åhgrence202a02019-09-02 17:01:19 +0200113 void ProcessCapture(
114 bool level_change,
115 bool saturated_microphone_signal,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100116 std::vector<std::vector<std::vector<float>>>* linear_output,
Per Åhgrence202a02019-09-02 17:01:19 +0200117 std::vector<std::vector<std::vector<float>>>* capture_block) override {}
peahd0263542017-01-03 04:20:34 -0800118
Per Åhgrence202a02019-09-02 17:01:19 +0200119 void BufferRender(
120 const std::vector<std::vector<std::vector<float>>>& block) override {}
peahd0263542017-01-03 04:20:34 -0800121
peah69221db2017-01-27 03:28:19 -0800122 void UpdateEchoLeakageStatus(bool leakage_detected) override {}
peahd0263542017-01-03 04:20:34 -0800123
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100124 void GetMetrics(EchoControl::Metrics* metrics) const override {}
125
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200126 void SetAudioBufferDelay(int delay_ms) override {}
Per Åhgrend0fa8202018-04-18 09:35:13 +0200127
peahd0263542017-01-03 04:20:34 -0800128 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.
134class RenderTransportVerificationProcessor : public BlockProcessor {
135 public:
136 explicit RenderTransportVerificationProcessor(size_t num_bands) {}
137 ~RenderTransportVerificationProcessor() override = default;
138
Per Åhgrence202a02019-09-02 17:01:19 +0200139 void ProcessCapture(
140 bool level_change,
141 bool saturated_microphone_signal,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100142 std::vector<std::vector<std::vector<float>>>* linear_output,
Per Åhgrence202a02019-09-02 17:01:19 +0200143 std::vector<std::vector<std::vector<float>>>* capture_block) override {
144 std::vector<std::vector<std::vector<float>>> render_block =
peahd0263542017-01-03 04:20:34 -0800145 received_render_blocks_.front();
146 received_render_blocks_.pop_front();
147 capture_block->swap(render_block);
148 }
149
Per Åhgrence202a02019-09-02 17:01:19 +0200150 void BufferRender(
151 const std::vector<std::vector<std::vector<float>>>& block) override {
peahcf02cf12017-04-05 14:18:07 -0700152 received_render_blocks_.push_back(block);
peahd0263542017-01-03 04:20:34 -0800153 }
154
peah69221db2017-01-27 03:28:19 -0800155 void UpdateEchoLeakageStatus(bool leakage_detected) override {}
peahd0263542017-01-03 04:20:34 -0800156
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100157 void GetMetrics(EchoControl::Metrics* metrics) const override {}
158
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200159 void SetAudioBufferDelay(int delay_ms) override {}
Per Åhgrend0fa8202018-04-18 09:35:13 +0200160
peahd0263542017-01-03 04:20:34 -0800161 private:
Per Åhgrence202a02019-09-02 17:01:19 +0200162 std::deque<std::vector<std::vector<std::vector<float>>>>
163 received_render_blocks_;
peahd0263542017-01-03 04:20:34 -0800164 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderTransportVerificationProcessor);
165};
166
167class EchoCanceller3Tester {
168 public:
169 explicit EchoCanceller3Tester(int sample_rate_hz)
170 : sample_rate_hz_(sample_rate_hz),
171 num_bands_(NumBandsForRate(sample_rate_hz_)),
Per Åhgrence202a02019-09-02 17:01:19 +0200172 frame_length_(160),
peahd0263542017-01-03 04:20:34 -0800173 fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
Per Åhgrend47941e2019-08-22 11:51:13 +0200174 capture_buffer_(fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800175 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200176 fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800177 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200178 fullband_frame_length_ * 100,
179 1),
180 render_buffer_(fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800181 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200182 fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800183 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200184 fullband_frame_length_ * 100,
185 1) {}
peahd0263542017-01-03 04:20:34 -0800186
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.
190 void RunCaptureTransportVerificationTest() {
191 EchoCanceller3 aec3(
Per Åhgrence202a02019-09-02 17:01:19 +0200192 EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800193 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,
Per Åhgrend47941e2019-08-22 11:51:13 +0200201 &capture_buffer_.split_bands(0)[0], 0);
peah522d71b2017-02-23 05:16:26 -0800202 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200203 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800204
peahcf02cf12017-04-05 14:18:07 -0700205 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800206 aec3.ProcessCapture(&capture_buffer_, false);
207 EXPECT_TRUE(VerifyOutputFrameBitexactness(
208 frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200209 &capture_buffer_.split_bands(0)[0], -64));
peahd0263542017-01-03 04:20:34 -0800210 }
211 }
212
213 // Test method for testing that the render data is properly received by the
214 // block processor.
215 void RunRenderTransportVerificationTest() {
216 EchoCanceller3 aec3(
Per Åhgrence202a02019-09-02 17:01:19 +0200217 EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800218 std::unique_ptr<BlockProcessor>(
219 new RenderTransportVerificationProcessor(num_bands_)));
220
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200221 std::vector<std::vector<float>> render_input(1);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200222 std::vector<float> capture_output;
peahd0263542017-01-03 04:20:34 -0800223 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,
Per Åhgrend47941e2019-08-22 11:51:13 +0200228 &capture_buffer_.split_bands(0)[0], 100);
peahcf02cf12017-04-05 14:18:07 -0700229 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200230 &render_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800231
Per Åhgren0aefbf02019-08-23 21:29:17 +0200232 for (size_t k = 0; k < frame_length_; ++k) {
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200233 render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200234 }
peahcf02cf12017-04-05 14:18:07 -0700235 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800236 aec3.ProcessCapture(&capture_buffer_, false);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200237 for (size_t k = 0; k < frame_length_; ++k) {
238 capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
239 }
peahd0263542017-01-03 04:20:34 -0800240 }
Per Åhgrenc0424252019-12-10 13:04:15 +0100241 HighPassFilter hp_filter(16000, 1);
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200242 hp_filter.Process(&render_input);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200243
244 EXPECT_TRUE(
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200245 VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
peahd0263542017-01-03 04:20:34 -0800246 }
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
259 void RunEchoPathChangeVerificationTest(
260 EchoPathChangeTestVariant echo_path_change_test_variant) {
Per Åhgrence202a02019-09-02 17:01:19 +0200261 constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
262 constexpr size_t kExpectedNumBlocksToProcess =
263 (kNumFramesToProcess * 160) / kBlockSize;
peahd0263542017-01-03 04:20:34 -0800264 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(_))
Per Åhgrence202a02019-09-02 17:01:19 +0200268 .Times(kExpectedNumBlocksToProcess);
peah69221db2017-01-27 03:28:19 -0800269 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
peahd0263542017-01-03 04:20:34 -0800270
271 switch (echo_path_change_test_variant) {
272 case EchoPathChangeTestVariant::kNone:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100273 EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200274 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800275 break;
276 case EchoPathChangeTestVariant::kOneSticky:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100277 EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200278 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800279 break;
280 case EchoPathChangeTestVariant::kOneNonSticky:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100281 EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200282 .Times(kNumFullBlocksPerFrame);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100283 EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200284 .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
peahd0263542017-01-03 04:20:34 -0800285 break;
286 }
287
Per Åhgrence202a02019-09-02 17:01:19 +0200288 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800289 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,
Per Åhgrend47941e2019-08-22 11:51:13 +0200311 &capture_buffer_.split_bands(0)[0], 0);
peah522d71b2017-02-23 05:16:26 -0800312 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200313 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800314
peahcf02cf12017-04-05 14:18:07 -0700315 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800316 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
335 void RunEchoLeakageVerificationTest(
336 EchoLeakageTestVariant leakage_report_variant) {
Per Åhgrence202a02019-09-02 17:01:19 +0200337 constexpr size_t kExpectedNumBlocksToProcess =
338 (kNumFramesToProcess * 160) / kBlockSize;
peahd0263542017-01-03 04:20:34 -0800339 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(_))
Per Åhgrence202a02019-09-02 17:01:19 +0200343 .Times(kExpectedNumBlocksToProcess);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100344 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200345 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800346
347 switch (leakage_report_variant) {
348 case EchoLeakageTestVariant::kNone:
peah69221db2017-01-27 03:28:19 -0800349 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
peahd0263542017-01-03 04:20:34 -0800350 break;
351 case EchoLeakageTestVariant::kFalseSticky:
peah69221db2017-01-27 03:28:19 -0800352 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
353 .Times(1);
peahd0263542017-01-03 04:20:34 -0800354 break;
355 case EchoLeakageTestVariant::kTrueSticky:
peah69221db2017-01-27 03:28:19 -0800356 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
357 .Times(1);
peahd0263542017-01-03 04:20:34 -0800358 break;
359 case EchoLeakageTestVariant::kTrueNonSticky: {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200360 ::testing::InSequence s;
peah69221db2017-01-27 03:28:19 -0800361 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
362 .Times(1);
363 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
peahd0263542017-01-03 04:20:34 -0800364 .Times(kNumFramesToProcess - 1);
365 } break;
366 }
367
Per Åhgrence202a02019-09-02 17:01:19 +0200368 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800369 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) {
peah69221db2017-01-27 03:28:19 -0800378 aec3.UpdateEchoLeakageStatus(false);
peahd0263542017-01-03 04:20:34 -0800379 }
380 break;
381 case EchoLeakageTestVariant::kTrueSticky:
382 if (frame_index == 0) {
peah69221db2017-01-27 03:28:19 -0800383 aec3.UpdateEchoLeakageStatus(true);
peahd0263542017-01-03 04:20:34 -0800384 }
385 break;
386 case EchoLeakageTestVariant::kTrueNonSticky:
387 if (frame_index == 0) {
peah69221db2017-01-27 03:28:19 -0800388 aec3.UpdateEchoLeakageStatus(true);
peahd0263542017-01-03 04:20:34 -0800389 } else {
peah69221db2017-01-27 03:28:19 -0800390 aec3.UpdateEchoLeakageStatus(false);
peahd0263542017-01-03 04:20:34 -0800391 }
392 break;
393 }
394
395 aec3.AnalyzeCapture(&capture_buffer_);
396 OptionalBandSplit();
397
398 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200399 &capture_buffer_.split_bands(0)[0], 0);
peah522d71b2017-02-23 05:16:26 -0800400 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200401 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800402
peahcf02cf12017-04-05 14:18:07 -0700403 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800404 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
421 void RunCaptureSaturationVerificationTest(
422 SaturationTestVariant saturation_variant) {
Per Åhgrence202a02019-09-02 17:01:19 +0200423 const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
424 const size_t kExpectedNumBlocksToProcess =
425 (kNumFramesToProcess * 160) / kBlockSize;
peahd0263542017-01-03 04:20:34 -0800426 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(_))
Per Åhgrence202a02019-09-02 17:01:19 +0200430 .Times(kExpectedNumBlocksToProcess);
peah69221db2017-01-27 03:28:19 -0800431 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
peahd0263542017-01-03 04:20:34 -0800432
433 switch (saturation_variant) {
434 case SaturationTestVariant::kNone:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100435 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200436 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800437 break;
438 case SaturationTestVariant::kOneNegative: {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200439 ::testing::InSequence s;
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100440 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200441 .Times(kNumFullBlocksPerFrame);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100442 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200443 .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
peahd0263542017-01-03 04:20:34 -0800444 } break;
445 case SaturationTestVariant::kOnePositive: {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200446 ::testing::InSequence s;
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100447 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200448 .Times(kNumFullBlocksPerFrame);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100449 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200450 .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
peahd0263542017-01-03 04:20:34 -0800451 } break;
452 }
453
Per Åhgrence202a02019-09-02 17:01:19 +0200454 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800455 std::move(block_processor_mock));
peahd0263542017-01-03 04:20:34 -0800456 for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
457 ++frame_index) {
458 for (int k = 0; k < fullband_frame_length_; ++k) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200459 capture_buffer_.channels()[0][k] = 0.f;
peahd0263542017-01-03 04:20:34 -0800460 }
461 switch (saturation_variant) {
462 case SaturationTestVariant::kNone:
463 break;
464 case SaturationTestVariant::kOneNegative:
465 if (frame_index == 0) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200466 capture_buffer_.channels()[0][10] = -32768.f;
peahd0263542017-01-03 04:20:34 -0800467 }
468 break;
469 case SaturationTestVariant::kOnePositive:
470 if (frame_index == 0) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200471 capture_buffer_.channels()[0][10] = 32767.f;
peahd0263542017-01-03 04:20:34 -0800472 }
473 break;
474 }
475
476 aec3.AnalyzeCapture(&capture_buffer_);
477 OptionalBandSplit();
478
479 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200480 &capture_buffer_.split_bands(0)[0], 0);
peahcf02cf12017-04-05 14:18:07 -0700481 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200482 &render_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800483
peahcf02cf12017-04-05 14:18:07 -0700484 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800485 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.
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000491 void RunRenderSwapQueueVerificationTest() {
Per Åhgren8ba58612017-12-01 23:01:44 +0100492 const EchoCanceller3Config config;
peahd0263542017-01-03 04:20:34 -0800493 EchoCanceller3 aec3(
Per Åhgrence202a02019-09-02 17:01:19 +0200494 config, sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800495 std::unique_ptr<BlockProcessor>(
496 new RenderTransportVerificationProcessor(num_bands_)));
497
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200498 std::vector<std::vector<float>> render_input(1);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200499 std::vector<float> capture_output;
500
Per Åhgren8ba58612017-12-01 23:01:44 +0100501 for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
peahd0263542017-01-03 04:20:34 -0800502 ++frame_index) {
503 if (sample_rate_hz_ > 16000) {
504 render_buffer_.SplitIntoFrequencyBands();
505 }
peahcf02cf12017-04-05 14:18:07 -0700506 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200507 &render_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800508
peahcf02cf12017-04-05 14:18:07 -0700509 if (sample_rate_hz_ > 16000) {
510 render_buffer_.SplitIntoFrequencyBands();
511 }
512
Per Åhgren0aefbf02019-08-23 21:29:17 +0200513 for (size_t k = 0; k < frame_length_; ++k) {
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200514 render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200515 }
peahcf02cf12017-04-05 14:18:07 -0700516 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800517 }
518
Per Åhgren8ba58612017-12-01 23:01:44 +0100519 for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
peahd0263542017-01-03 04:20:34 -0800520 ++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,
Per Åhgrend47941e2019-08-22 11:51:13 +0200527 &capture_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800528
529 aec3.ProcessCapture(&capture_buffer_, false);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200530 for (size_t k = 0; k < frame_length_; ++k) {
531 capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
532 }
peahd0263542017-01-03 04:20:34 -0800533 }
Per Åhgrenc0424252019-12-10 13:04:15 +0100534 HighPassFilter hp_filter(16000, 1);
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200535 hp_filter.Process(&render_input);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200536
537 EXPECT_TRUE(
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200538 VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
peahd0263542017-01-03 04:20:34 -0800539 }
540
541 // This test verifies that a buffer overrun in the render swapqueue is
542 // properly reported.
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000543 void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
Per Åhgrence202a02019-09-02 17:01:19 +0200544 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1);
peahd0263542017-01-03 04:20:34 -0800545
peahcf02cf12017-04-05 14:18:07 -0700546 constexpr size_t kRenderTransferQueueSize = 30;
peahd0263542017-01-03 04:20:34 -0800547 for (size_t k = 0; k < 2; ++k) {
peahcf02cf12017-04-05 14:18:07 -0700548 for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
peahd0263542017-01-03 04:20:34 -0800549 ++frame_index) {
550 if (sample_rate_hz_ > 16000) {
551 render_buffer_.SplitIntoFrequencyBands();
552 }
peah522d71b2017-02-23 05:16:26 -0800553 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200554 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800555
Per Åhgren0aefbf02019-08-23 21:29:17 +0200556 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800557 }
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.
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;
Per Åhgrence202a02019-09-02 17:01:19 +0200569 EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
peah522d71b2017-02-23 05:16:26 -0800570 PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800571
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.
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;
Per Åhgrence202a02019-09-02 17:01:19 +0200582 EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
peahd0263542017-01-03 04:20:34 -0800583 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
peahd0263542017-01-03 04:20:34 -0800588#endif
589
590 private:
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
609std::string ProduceDebugText(int sample_rate_hz) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200610 rtc::StringBuilder ss;
peahd0263542017-01-03 04:20:34 -0800611 ss << "Sample rate: " << sample_rate_hz;
Jonas Olsson84df1c72018-09-14 16:59:32 +0200612 return ss.Release();
peahd0263542017-01-03 04:20:34 -0800613}
614
615std::string ProduceDebugText(int sample_rate_hz, int variant) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200616 rtc::StringBuilder ss;
peahd0263542017-01-03 04:20:34 -0800617 ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
Jonas Olsson84df1c72018-09-14 16:59:32 +0200618 return ss.Release();
peahd0263542017-01-03 04:20:34 -0800619}
620
621} // namespace
622
623TEST(EchoCanceller3Buffering, CaptureBitexactness) {
Per Åhgrence202a02019-09-02 17:01:19 +0200624 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800625 SCOPED_TRACE(ProduceDebugText(rate));
626 EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
627 }
628}
629
630TEST(EchoCanceller3Buffering, RenderBitexactness) {
Per Åhgrence202a02019-09-02 17:01:19 +0200631 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800632 SCOPED_TRACE(ProduceDebugText(rate));
633 EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
634 }
635}
636
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000637TEST(EchoCanceller3Buffering, RenderSwapQueue) {
Per Åhgrence202a02019-09-02 17:01:19 +0200638 EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
peahd0263542017-01-03 04:20:34 -0800639}
640
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000641TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
Per Åhgrence202a02019-09-02 17:01:19 +0200642 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800643 SCOPED_TRACE(ProduceDebugText(rate));
644 EchoCanceller3Tester(rate)
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000645 .RunRenderPipelineSwapQueueOverrunReturnValueTest();
peahd0263542017-01-03 04:20:34 -0800646 }
647}
648
649TEST(EchoCanceller3Messaging, CaptureSaturation) {
650 auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
651 EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
652 EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
Per Åhgrence202a02019-09-02 17:01:19 +0200653 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800654 for (auto variant : variants) {
655 SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
656 EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
657 }
658 }
659}
660
661TEST(EchoCanceller3Messaging, EchoPathChange) {
662 auto variants = {
663 EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
664 EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
665 EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
Per Åhgrence202a02019-09-02 17:01:19 +0200666 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800667 for (auto variant : variants) {
668 SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
669 EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
670 }
671 }
672}
673
674TEST(EchoCanceller3Messaging, EchoLeakage) {
675 auto variants = {
676 EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
677 EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
678 EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
679 EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
Per Åhgrence202a02019-09-02 17:01:19 +0200680 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800681 for (auto variant : variants) {
682 SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
683 EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
684 }
685 }
686}
687
Per Åhgren80e52162020-04-06 14:57:52 +0200688// Tests the parameter functionality for the field trial override for the
689// default_len parameter.
690TEST(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.
707TEST(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.
728TEST(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.
745TEST(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.
842TEST(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
peahd0263542017-01-03 04:20:34 -0800891#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
peahd0263542017-01-03 04:20:34 -0800892
893TEST(EchoCanceller3InputCheck, WrongCaptureNumBandsCheckVerification) {
Per Åhgrence202a02019-09-02 17:01:19 +0200894 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800895 SCOPED_TRACE(ProduceDebugText(rate));
896 EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
897 }
898}
899
peahd0263542017-01-03 04:20:34 -0800900// Verifiers that the verification for null input to the capture processing api
901// call works.
902TEST(EchoCanceller3InputCheck, NullCaptureProcessingParameter) {
Per Åhgrence202a02019-09-02 17:01:19 +0200903 EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 16000, 1, 1)
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200904 .ProcessCapture(nullptr, false),
905 "");
peahd0263542017-01-03 04:20:34 -0800906}
907
peah21920892017-02-08 05:08:56 -0800908// Verifies the check for correct sample rate.
peahcf02cf12017-04-05 14:18:07 -0700909// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
910// tests on test bots has been fixed.
911TEST(EchoCanceller3InputCheck, DISABLED_WrongSampleRate) {
peah21920892017-02-08 05:08:56 -0800912 ApmDataDumper data_dumper(0);
Per Åhgrence202a02019-09-02 17:01:19 +0200913 EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001, 1, 1), "");
peah21920892017-02-08 05:08:56 -0800914}
915
peahd0263542017-01-03 04:20:34 -0800916#endif
917
918} // namespace webrtc