blob: 4a3c4667123db97f47a4a68e1dc695f2776c3756 [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) {}
Niels Möllerde953292020-09-29 09:46:21 +0200111
112 CaptureTransportVerificationProcessor() = delete;
113 CaptureTransportVerificationProcessor(
114 const CaptureTransportVerificationProcessor&) = delete;
115 CaptureTransportVerificationProcessor& operator=(
116 const CaptureTransportVerificationProcessor&) = delete;
117
peahd0263542017-01-03 04:20:34 -0800118 ~CaptureTransportVerificationProcessor() override = default;
119
Per Åhgrence202a02019-09-02 17:01:19 +0200120 void ProcessCapture(
121 bool level_change,
122 bool saturated_microphone_signal,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100123 std::vector<std::vector<std::vector<float>>>* linear_output,
Per Åhgrence202a02019-09-02 17:01:19 +0200124 std::vector<std::vector<std::vector<float>>>* capture_block) override {}
peahd0263542017-01-03 04:20:34 -0800125
Per Åhgrence202a02019-09-02 17:01:19 +0200126 void BufferRender(
127 const std::vector<std::vector<std::vector<float>>>& block) override {}
peahd0263542017-01-03 04:20:34 -0800128
peah69221db2017-01-27 03:28:19 -0800129 void UpdateEchoLeakageStatus(bool leakage_detected) override {}
peahd0263542017-01-03 04:20:34 -0800130
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100131 void GetMetrics(EchoControl::Metrics* metrics) const override {}
132
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200133 void SetAudioBufferDelay(int delay_ms) override {}
Per Åhgren8ee1ec82021-03-11 06:33:45 +0000134
135 void SetCaptureOutputUsage(bool capture_output_used) {}
peahd0263542017-01-03 04:20:34 -0800136};
137
138// Class for testing that the render data is properly received by the block
139// processor.
140class RenderTransportVerificationProcessor : public BlockProcessor {
141 public:
142 explicit RenderTransportVerificationProcessor(size_t num_bands) {}
Niels Möllerde953292020-09-29 09:46:21 +0200143
144 RenderTransportVerificationProcessor() = delete;
145 RenderTransportVerificationProcessor(
146 const RenderTransportVerificationProcessor&) = delete;
147 RenderTransportVerificationProcessor& operator=(
148 const RenderTransportVerificationProcessor&) = delete;
149
peahd0263542017-01-03 04:20:34 -0800150 ~RenderTransportVerificationProcessor() override = default;
151
Per Åhgrence202a02019-09-02 17:01:19 +0200152 void ProcessCapture(
153 bool level_change,
154 bool saturated_microphone_signal,
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100155 std::vector<std::vector<std::vector<float>>>* linear_output,
Per Åhgrence202a02019-09-02 17:01:19 +0200156 std::vector<std::vector<std::vector<float>>>* capture_block) override {
157 std::vector<std::vector<std::vector<float>>> render_block =
peahd0263542017-01-03 04:20:34 -0800158 received_render_blocks_.front();
159 received_render_blocks_.pop_front();
160 capture_block->swap(render_block);
161 }
162
Per Åhgrence202a02019-09-02 17:01:19 +0200163 void BufferRender(
164 const std::vector<std::vector<std::vector<float>>>& block) override {
peahcf02cf12017-04-05 14:18:07 -0700165 received_render_blocks_.push_back(block);
peahd0263542017-01-03 04:20:34 -0800166 }
167
peah69221db2017-01-27 03:28:19 -0800168 void UpdateEchoLeakageStatus(bool leakage_detected) override {}
peahd0263542017-01-03 04:20:34 -0800169
Gustaf Ullberg332150d2017-11-22 14:17:39 +0100170 void GetMetrics(EchoControl::Metrics* metrics) const override {}
171
Gustaf Ullberg3cb61042019-10-24 15:52:10 +0200172 void SetAudioBufferDelay(int delay_ms) override {}
Per Åhgrend0fa8202018-04-18 09:35:13 +0200173
Per Åhgren8ee1ec82021-03-11 06:33:45 +0000174 void SetCaptureOutputUsage(bool capture_output_used) {}
175
peahd0263542017-01-03 04:20:34 -0800176 private:
Per Åhgrence202a02019-09-02 17:01:19 +0200177 std::deque<std::vector<std::vector<std::vector<float>>>>
178 received_render_blocks_;
peahd0263542017-01-03 04:20:34 -0800179};
180
181class EchoCanceller3Tester {
182 public:
183 explicit EchoCanceller3Tester(int sample_rate_hz)
184 : sample_rate_hz_(sample_rate_hz),
185 num_bands_(NumBandsForRate(sample_rate_hz_)),
Per Åhgrence202a02019-09-02 17:01:19 +0200186 frame_length_(160),
peahd0263542017-01-03 04:20:34 -0800187 fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
Per Åhgrend47941e2019-08-22 11:51:13 +0200188 capture_buffer_(fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800189 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200190 fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800191 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200192 fullband_frame_length_ * 100,
193 1),
194 render_buffer_(fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800195 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200196 fullband_frame_length_ * 100,
peahd0263542017-01-03 04:20:34 -0800197 1,
Per Åhgrend47941e2019-08-22 11:51:13 +0200198 fullband_frame_length_ * 100,
199 1) {}
peahd0263542017-01-03 04:20:34 -0800200
Niels Möllerde953292020-09-29 09:46:21 +0200201 EchoCanceller3Tester() = delete;
202 EchoCanceller3Tester(const EchoCanceller3Tester&) = delete;
203 EchoCanceller3Tester& operator=(const EchoCanceller3Tester&) = delete;
204
peahd0263542017-01-03 04:20:34 -0800205 // Verifies that the capture data is properly received by the block processor
206 // and that the processor data is properly passed to the EchoCanceller3
207 // output.
208 void RunCaptureTransportVerificationTest() {
209 EchoCanceller3 aec3(
Per Åhgrence202a02019-09-02 17:01:19 +0200210 EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800211 std::unique_ptr<BlockProcessor>(
212 new CaptureTransportVerificationProcessor(num_bands_)));
213
214 for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
215 ++frame_index) {
216 aec3.AnalyzeCapture(&capture_buffer_);
217 OptionalBandSplit();
218 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200219 &capture_buffer_.split_bands(0)[0], 0);
peah522d71b2017-02-23 05:16:26 -0800220 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200221 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800222
peahcf02cf12017-04-05 14:18:07 -0700223 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800224 aec3.ProcessCapture(&capture_buffer_, false);
225 EXPECT_TRUE(VerifyOutputFrameBitexactness(
226 frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200227 &capture_buffer_.split_bands(0)[0], -64));
peahd0263542017-01-03 04:20:34 -0800228 }
229 }
230
231 // Test method for testing that the render data is properly received by the
232 // block processor.
233 void RunRenderTransportVerificationTest() {
234 EchoCanceller3 aec3(
Per Åhgrence202a02019-09-02 17:01:19 +0200235 EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800236 std::unique_ptr<BlockProcessor>(
237 new RenderTransportVerificationProcessor(num_bands_)));
238
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200239 std::vector<std::vector<float>> render_input(1);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200240 std::vector<float> capture_output;
peahd0263542017-01-03 04:20:34 -0800241 for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
242 ++frame_index) {
243 aec3.AnalyzeCapture(&capture_buffer_);
244 OptionalBandSplit();
245 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200246 &capture_buffer_.split_bands(0)[0], 100);
peahcf02cf12017-04-05 14:18:07 -0700247 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200248 &render_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800249
Per Åhgren0aefbf02019-08-23 21:29:17 +0200250 for (size_t k = 0; k < frame_length_; ++k) {
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200251 render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200252 }
peahcf02cf12017-04-05 14:18:07 -0700253 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800254 aec3.ProcessCapture(&capture_buffer_, false);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200255 for (size_t k = 0; k < frame_length_; ++k) {
256 capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
257 }
peahd0263542017-01-03 04:20:34 -0800258 }
Per Åhgren0aefbf02019-08-23 21:29:17 +0200259
260 EXPECT_TRUE(
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200261 VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
peahd0263542017-01-03 04:20:34 -0800262 }
263
264 // Verifies that information about echo path changes are properly propagated
265 // to the block processor.
266 // The cases tested are:
267 // -That no set echo path change flags are received when there is no echo path
268 // change.
269 // -That set echo path change flags are received and continues to be received
270 // as long as echo path changes are flagged.
271 // -That set echo path change flags are no longer received when echo path
272 // change events stop being flagged.
273 enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };
274
275 void RunEchoPathChangeVerificationTest(
276 EchoPathChangeTestVariant echo_path_change_test_variant) {
Per Åhgrence202a02019-09-02 17:01:19 +0200277 constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
278 constexpr size_t kExpectedNumBlocksToProcess =
279 (kNumFramesToProcess * 160) / kBlockSize;
peahd0263542017-01-03 04:20:34 -0800280 std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
281 block_processor_mock(
282 new StrictMock<webrtc::test::MockBlockProcessor>());
283 EXPECT_CALL(*block_processor_mock, BufferRender(_))
Per Åhgrence202a02019-09-02 17:01:19 +0200284 .Times(kExpectedNumBlocksToProcess);
peah69221db2017-01-27 03:28:19 -0800285 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
peahd0263542017-01-03 04:20:34 -0800286
287 switch (echo_path_change_test_variant) {
288 case EchoPathChangeTestVariant::kNone:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100289 EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200290 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800291 break;
292 case EchoPathChangeTestVariant::kOneSticky:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100293 EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200294 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800295 break;
296 case EchoPathChangeTestVariant::kOneNonSticky:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100297 EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200298 .Times(kNumFullBlocksPerFrame);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100299 EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200300 .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
peahd0263542017-01-03 04:20:34 -0800301 break;
302 }
303
Per Åhgrence202a02019-09-02 17:01:19 +0200304 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800305 std::move(block_processor_mock));
306
307 for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
308 ++frame_index) {
309 bool echo_path_change = false;
310 switch (echo_path_change_test_variant) {
311 case EchoPathChangeTestVariant::kNone:
312 break;
313 case EchoPathChangeTestVariant::kOneSticky:
314 echo_path_change = true;
315 break;
316 case EchoPathChangeTestVariant::kOneNonSticky:
317 if (frame_index == 0) {
318 echo_path_change = true;
319 }
320 break;
321 }
322
323 aec3.AnalyzeCapture(&capture_buffer_);
324 OptionalBandSplit();
325
326 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200327 &capture_buffer_.split_bands(0)[0], 0);
peah522d71b2017-02-23 05:16:26 -0800328 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200329 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800330
peahcf02cf12017-04-05 14:18:07 -0700331 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800332 aec3.ProcessCapture(&capture_buffer_, echo_path_change);
333 }
334 }
335
336 // Test for verifying that echo leakage information is being properly passed
337 // to the processor.
338 // The cases tested are:
339 // -That no method calls are received when they should not.
340 // -That false values are received each time they are flagged.
341 // -That true values are received each time they are flagged.
342 // -That a false value is received when flagged after a true value has been
343 // flagged.
344 enum class EchoLeakageTestVariant {
345 kNone,
346 kFalseSticky,
347 kTrueSticky,
348 kTrueNonSticky
349 };
350
351 void RunEchoLeakageVerificationTest(
352 EchoLeakageTestVariant leakage_report_variant) {
Per Åhgrence202a02019-09-02 17:01:19 +0200353 constexpr size_t kExpectedNumBlocksToProcess =
354 (kNumFramesToProcess * 160) / kBlockSize;
peahd0263542017-01-03 04:20:34 -0800355 std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
356 block_processor_mock(
357 new StrictMock<webrtc::test::MockBlockProcessor>());
358 EXPECT_CALL(*block_processor_mock, BufferRender(_))
Per Åhgrence202a02019-09-02 17:01:19 +0200359 .Times(kExpectedNumBlocksToProcess);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100360 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200361 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800362
363 switch (leakage_report_variant) {
364 case EchoLeakageTestVariant::kNone:
peah69221db2017-01-27 03:28:19 -0800365 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
peahd0263542017-01-03 04:20:34 -0800366 break;
367 case EchoLeakageTestVariant::kFalseSticky:
peah69221db2017-01-27 03:28:19 -0800368 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
369 .Times(1);
peahd0263542017-01-03 04:20:34 -0800370 break;
371 case EchoLeakageTestVariant::kTrueSticky:
peah69221db2017-01-27 03:28:19 -0800372 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
373 .Times(1);
peahd0263542017-01-03 04:20:34 -0800374 break;
375 case EchoLeakageTestVariant::kTrueNonSticky: {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200376 ::testing::InSequence s;
peah69221db2017-01-27 03:28:19 -0800377 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
378 .Times(1);
379 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
peahd0263542017-01-03 04:20:34 -0800380 .Times(kNumFramesToProcess - 1);
381 } break;
382 }
383
Per Åhgrence202a02019-09-02 17:01:19 +0200384 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800385 std::move(block_processor_mock));
386
387 for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
388 ++frame_index) {
389 switch (leakage_report_variant) {
390 case EchoLeakageTestVariant::kNone:
391 break;
392 case EchoLeakageTestVariant::kFalseSticky:
393 if (frame_index == 0) {
peah69221db2017-01-27 03:28:19 -0800394 aec3.UpdateEchoLeakageStatus(false);
peahd0263542017-01-03 04:20:34 -0800395 }
396 break;
397 case EchoLeakageTestVariant::kTrueSticky:
398 if (frame_index == 0) {
peah69221db2017-01-27 03:28:19 -0800399 aec3.UpdateEchoLeakageStatus(true);
peahd0263542017-01-03 04:20:34 -0800400 }
401 break;
402 case EchoLeakageTestVariant::kTrueNonSticky:
403 if (frame_index == 0) {
peah69221db2017-01-27 03:28:19 -0800404 aec3.UpdateEchoLeakageStatus(true);
peahd0263542017-01-03 04:20:34 -0800405 } else {
peah69221db2017-01-27 03:28:19 -0800406 aec3.UpdateEchoLeakageStatus(false);
peahd0263542017-01-03 04:20:34 -0800407 }
408 break;
409 }
410
411 aec3.AnalyzeCapture(&capture_buffer_);
412 OptionalBandSplit();
413
414 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200415 &capture_buffer_.split_bands(0)[0], 0);
peah522d71b2017-02-23 05:16:26 -0800416 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200417 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800418
peahcf02cf12017-04-05 14:18:07 -0700419 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800420 aec3.ProcessCapture(&capture_buffer_, false);
421 }
422 }
423
424 // This verifies that saturation information is properly passed to the
425 // BlockProcessor.
426 // The cases tested are:
427 // -That no saturation event is passed to the processor if there is no
428 // saturation.
429 // -That one frame with one negative saturated sample value is reported to be
430 // saturated and that following non-saturated frames are properly reported as
431 // not being saturated.
432 // -That one frame with one positive saturated sample value is reported to be
433 // saturated and that following non-saturated frames are properly reported as
434 // not being saturated.
435 enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };
436
437 void RunCaptureSaturationVerificationTest(
438 SaturationTestVariant saturation_variant) {
Per Åhgrence202a02019-09-02 17:01:19 +0200439 const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
440 const size_t kExpectedNumBlocksToProcess =
441 (kNumFramesToProcess * 160) / kBlockSize;
peahd0263542017-01-03 04:20:34 -0800442 std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
443 block_processor_mock(
444 new StrictMock<webrtc::test::MockBlockProcessor>());
445 EXPECT_CALL(*block_processor_mock, BufferRender(_))
Per Åhgrence202a02019-09-02 17:01:19 +0200446 .Times(kExpectedNumBlocksToProcess);
peah69221db2017-01-27 03:28:19 -0800447 EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
peahd0263542017-01-03 04:20:34 -0800448
449 switch (saturation_variant) {
450 case SaturationTestVariant::kNone:
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100451 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200452 .Times(kExpectedNumBlocksToProcess);
peahd0263542017-01-03 04:20:34 -0800453 break;
454 case SaturationTestVariant::kOneNegative: {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200455 ::testing::InSequence s;
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100456 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200457 .Times(kNumFullBlocksPerFrame);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100458 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200459 .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
peahd0263542017-01-03 04:20:34 -0800460 } break;
461 case SaturationTestVariant::kOnePositive: {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200462 ::testing::InSequence s;
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100463 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200464 .Times(kNumFullBlocksPerFrame);
Per Åhgrenc20a19c2019-11-13 11:12:29 +0100465 EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
Per Åhgrence202a02019-09-02 17:01:19 +0200466 .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
peahd0263542017-01-03 04:20:34 -0800467 } break;
468 }
469
Per Åhgrence202a02019-09-02 17:01:19 +0200470 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800471 std::move(block_processor_mock));
peahd0263542017-01-03 04:20:34 -0800472 for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
473 ++frame_index) {
474 for (int k = 0; k < fullband_frame_length_; ++k) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200475 capture_buffer_.channels()[0][k] = 0.f;
peahd0263542017-01-03 04:20:34 -0800476 }
477 switch (saturation_variant) {
478 case SaturationTestVariant::kNone:
479 break;
480 case SaturationTestVariant::kOneNegative:
481 if (frame_index == 0) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200482 capture_buffer_.channels()[0][10] = -32768.f;
peahd0263542017-01-03 04:20:34 -0800483 }
484 break;
485 case SaturationTestVariant::kOnePositive:
486 if (frame_index == 0) {
Per Åhgrend47941e2019-08-22 11:51:13 +0200487 capture_buffer_.channels()[0][10] = 32767.f;
peahd0263542017-01-03 04:20:34 -0800488 }
489 break;
490 }
491
492 aec3.AnalyzeCapture(&capture_buffer_);
493 OptionalBandSplit();
494
495 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200496 &capture_buffer_.split_bands(0)[0], 0);
peahcf02cf12017-04-05 14:18:07 -0700497 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200498 &render_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800499
peahcf02cf12017-04-05 14:18:07 -0700500 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800501 aec3.ProcessCapture(&capture_buffer_, false);
502 }
503 }
504
505 // This test verifies that the swapqueue is able to handle jitter in the
506 // capture and render API calls.
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000507 void RunRenderSwapQueueVerificationTest() {
Per Åhgren8ba58612017-12-01 23:01:44 +0100508 const EchoCanceller3Config config;
peahd0263542017-01-03 04:20:34 -0800509 EchoCanceller3 aec3(
Per Åhgrence202a02019-09-02 17:01:19 +0200510 config, sample_rate_hz_, 1, 1,
peahd0263542017-01-03 04:20:34 -0800511 std::unique_ptr<BlockProcessor>(
512 new RenderTransportVerificationProcessor(num_bands_)));
513
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200514 std::vector<std::vector<float>> render_input(1);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200515 std::vector<float> capture_output;
516
Per Åhgren8ba58612017-12-01 23:01:44 +0100517 for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
peahd0263542017-01-03 04:20:34 -0800518 ++frame_index) {
519 if (sample_rate_hz_ > 16000) {
520 render_buffer_.SplitIntoFrequencyBands();
521 }
peahcf02cf12017-04-05 14:18:07 -0700522 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200523 &render_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800524
peahcf02cf12017-04-05 14:18:07 -0700525 if (sample_rate_hz_ > 16000) {
526 render_buffer_.SplitIntoFrequencyBands();
527 }
528
Per Åhgren0aefbf02019-08-23 21:29:17 +0200529 for (size_t k = 0; k < frame_length_; ++k) {
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200530 render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200531 }
peahcf02cf12017-04-05 14:18:07 -0700532 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800533 }
534
Per Åhgren8ba58612017-12-01 23:01:44 +0100535 for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
peahd0263542017-01-03 04:20:34 -0800536 ++frame_index) {
537 aec3.AnalyzeCapture(&capture_buffer_);
538 if (sample_rate_hz_ > 16000) {
539 capture_buffer_.SplitIntoFrequencyBands();
540 }
541
542 PopulateInputFrame(frame_length_, num_bands_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200543 &capture_buffer_.split_bands(0)[0], 0);
peahd0263542017-01-03 04:20:34 -0800544
545 aec3.ProcessCapture(&capture_buffer_, false);
Per Åhgren0aefbf02019-08-23 21:29:17 +0200546 for (size_t k = 0; k < frame_length_; ++k) {
547 capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
548 }
peahd0263542017-01-03 04:20:34 -0800549 }
Per Åhgren0aefbf02019-08-23 21:29:17 +0200550
551 EXPECT_TRUE(
Sam Zackrissonfeee1e42019-09-20 07:50:35 +0200552 VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
peahd0263542017-01-03 04:20:34 -0800553 }
554
555 // This test verifies that a buffer overrun in the render swapqueue is
556 // properly reported.
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000557 void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
Per Åhgrence202a02019-09-02 17:01:19 +0200558 EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1);
peahd0263542017-01-03 04:20:34 -0800559
peahcf02cf12017-04-05 14:18:07 -0700560 constexpr size_t kRenderTransferQueueSize = 30;
peahd0263542017-01-03 04:20:34 -0800561 for (size_t k = 0; k < 2; ++k) {
peahcf02cf12017-04-05 14:18:07 -0700562 for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
peahd0263542017-01-03 04:20:34 -0800563 ++frame_index) {
564 if (sample_rate_hz_ > 16000) {
565 render_buffer_.SplitIntoFrequencyBands();
566 }
peah522d71b2017-02-23 05:16:26 -0800567 PopulateInputFrame(frame_length_, frame_index,
Per Åhgrend47941e2019-08-22 11:51:13 +0200568 &render_buffer_.channels()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800569
Per Åhgren0aefbf02019-08-23 21:29:17 +0200570 aec3.AnalyzeRender(&render_buffer_);
peahd0263542017-01-03 04:20:34 -0800571 }
572 }
573 }
574
575#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
576 // Verifies the that the check for the number of bands in the AnalyzeRender
577 // input is correct by adjusting the sample rates of EchoCanceller3 and the
578 // input AudioBuffer to have a different number of bands.
579 void RunAnalyzeRenderNumBandsCheckVerification() {
580 // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
581 // way that the number of bands for the rates are different.
582 const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
Per Åhgrence202a02019-09-02 17:01:19 +0200583 EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
peah522d71b2017-02-23 05:16:26 -0800584 PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);
peahd0263542017-01-03 04:20:34 -0800585
586 EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
587 }
588
589 // Verifies the that the check for the number of bands in the ProcessCapture
590 // input is correct by adjusting the sample rates of EchoCanceller3 and the
591 // input AudioBuffer to have a different number of bands.
592 void RunProcessCaptureNumBandsCheckVerification() {
593 // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
594 // way that the number of bands for the rates are different.
595 const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
Per Åhgrence202a02019-09-02 17:01:19 +0200596 EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
peahd0263542017-01-03 04:20:34 -0800597 PopulateInputFrame(frame_length_, num_bands_, 0,
598 &capture_buffer_.split_bands_f(0)[0], 100);
599 EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
600 }
601
peahd0263542017-01-03 04:20:34 -0800602#endif
603
604 private:
605 void OptionalBandSplit() {
606 if (sample_rate_hz_ > 16000) {
607 capture_buffer_.SplitIntoFrequencyBands();
608 render_buffer_.SplitIntoFrequencyBands();
609 }
610 }
611
612 static constexpr size_t kNumFramesToProcess = 20;
613 const int sample_rate_hz_;
614 const size_t num_bands_;
615 const size_t frame_length_;
616 const int fullband_frame_length_;
617 AudioBuffer capture_buffer_;
618 AudioBuffer render_buffer_;
peahd0263542017-01-03 04:20:34 -0800619};
620
621std::string ProduceDebugText(int sample_rate_hz) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200622 rtc::StringBuilder ss;
peahd0263542017-01-03 04:20:34 -0800623 ss << "Sample rate: " << sample_rate_hz;
Jonas Olsson84df1c72018-09-14 16:59:32 +0200624 return ss.Release();
peahd0263542017-01-03 04:20:34 -0800625}
626
627std::string ProduceDebugText(int sample_rate_hz, int variant) {
Jonas Olsson366a50c2018-09-06 13:41:30 +0200628 rtc::StringBuilder ss;
peahd0263542017-01-03 04:20:34 -0800629 ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
Jonas Olsson84df1c72018-09-14 16:59:32 +0200630 return ss.Release();
peahd0263542017-01-03 04:20:34 -0800631}
632
633} // namespace
634
635TEST(EchoCanceller3Buffering, CaptureBitexactness) {
Per Åhgrence202a02019-09-02 17:01:19 +0200636 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800637 SCOPED_TRACE(ProduceDebugText(rate));
638 EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
639 }
640}
641
642TEST(EchoCanceller3Buffering, RenderBitexactness) {
Per Åhgrence202a02019-09-02 17:01:19 +0200643 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800644 SCOPED_TRACE(ProduceDebugText(rate));
645 EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
646 }
647}
648
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000649TEST(EchoCanceller3Buffering, RenderSwapQueue) {
Per Åhgrence202a02019-09-02 17:01:19 +0200650 EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
peahd0263542017-01-03 04:20:34 -0800651}
652
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000653TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
Per Åhgrence202a02019-09-02 17:01:19 +0200654 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800655 SCOPED_TRACE(ProduceDebugText(rate));
656 EchoCanceller3Tester(rate)
Mirko Bonadeif0d9cda2019-01-17 20:43:58 +0000657 .RunRenderPipelineSwapQueueOverrunReturnValueTest();
peahd0263542017-01-03 04:20:34 -0800658 }
659}
660
661TEST(EchoCanceller3Messaging, CaptureSaturation) {
662 auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
663 EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
664 EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
Per Åhgrence202a02019-09-02 17:01:19 +0200665 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800666 for (auto variant : variants) {
667 SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
668 EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
669 }
670 }
671}
672
673TEST(EchoCanceller3Messaging, EchoPathChange) {
674 auto variants = {
675 EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
676 EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
677 EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
Per Åhgrence202a02019-09-02 17:01:19 +0200678 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800679 for (auto variant : variants) {
680 SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
681 EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
682 }
683 }
684}
685
686TEST(EchoCanceller3Messaging, EchoLeakage) {
687 auto variants = {
688 EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
689 EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
690 EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
691 EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
Per Åhgrence202a02019-09-02 17:01:19 +0200692 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800693 for (auto variant : variants) {
694 SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
695 EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
696 }
697 }
698}
699
Per Åhgren80e52162020-04-06 14:57:52 +0200700// Tests the parameter functionality for the field trial override for the
701// default_len parameter.
702TEST(EchoCanceller3FieldTrials, Aec3SuppressorEpStrengthDefaultLenOverride) {
703 EchoCanceller3Config default_config;
704 EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
705 ASSERT_EQ(default_config.ep_strength.default_len,
706 adjusted_config.ep_strength.default_len);
707
708 webrtc::test::ScopedFieldTrials field_trials(
709 "WebRTC-Aec3SuppressorEpStrengthDefaultLenOverride/-0.02/");
710 adjusted_config = AdjustConfig(default_config);
711
712 ASSERT_NE(default_config.ep_strength.default_len,
713 adjusted_config.ep_strength.default_len);
714 EXPECT_FLOAT_EQ(-0.02f, adjusted_config.ep_strength.default_len);
715}
716
717// Tests the parameter functionality for the field trial override for the
718// anti-howling gain.
719TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
720 EchoCanceller3Config default_config;
721 EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
722 ASSERT_EQ(
723 default_config.suppressor.high_bands_suppression.anti_howling_gain,
724 adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
725
726 webrtc::test::ScopedFieldTrials field_trials(
727 "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
728 adjusted_config = AdjustConfig(default_config);
729
730 ASSERT_NE(
731 default_config.suppressor.high_bands_suppression.anti_howling_gain,
732 adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
733 EXPECT_FLOAT_EQ(
734 0.02f,
735 adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
736}
737
738// Tests the field trial override for the enforcement of a low active render
739// limit.
740TEST(EchoCanceller3FieldTrials, Aec3EnforceLowActiveRenderLimit) {
741 EchoCanceller3Config default_config;
742 EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
743 ASSERT_EQ(default_config.render_levels.active_render_limit,
744 adjusted_config.render_levels.active_render_limit);
745
746 webrtc::test::ScopedFieldTrials field_trials(
747 "WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
748 adjusted_config = AdjustConfig(default_config);
749
750 ASSERT_NE(default_config.render_levels.active_render_limit,
751 adjusted_config.render_levels.active_render_limit);
752 EXPECT_FLOAT_EQ(50.f, adjusted_config.render_levels.active_render_limit);
753}
754
755// Testing the field trial-based override of the suppressor parameters for a
756// joint passing of all parameters.
757TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideAllParams) {
758 webrtc::test::ScopedFieldTrials field_trials(
759 "WebRTC-Aec3SuppressorTuningOverride/"
760 "nearend_tuning_mask_lf_enr_transparent:0.1,nearend_tuning_mask_lf_enr_"
761 "suppress:0.2,nearend_tuning_mask_hf_enr_transparent:0.3,nearend_tuning_"
762 "mask_hf_enr_suppress:0.4,nearend_tuning_max_inc_factor:0.5,nearend_"
763 "tuning_max_dec_factor_lf:0.6,normal_tuning_mask_lf_enr_transparent:0.7,"
764 "normal_tuning_mask_lf_enr_suppress:0.8,normal_tuning_mask_hf_enr_"
765 "transparent:0.9,normal_tuning_mask_hf_enr_suppress:1.0,normal_tuning_"
766 "max_inc_factor:1.1,normal_tuning_max_dec_factor_lf:1.2,dominant_nearend_"
767 "detection_enr_threshold:1.3,dominant_nearend_detection_enr_exit_"
768 "threshold:1.4,dominant_nearend_detection_snr_threshold:1.5,dominant_"
769 "nearend_detection_hold_duration:10,dominant_nearend_detection_trigger_"
770 "threshold:11,ep_strength_default_len:1.6/");
771
772 EchoCanceller3Config default_config;
773 EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
774
775 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
776 default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
777 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
778 default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
779 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
780 default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
781 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
782 default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
783 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
784 default_config.suppressor.nearend_tuning.max_inc_factor);
785 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
786 default_config.suppressor.nearend_tuning.max_dec_factor_lf);
787 ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
788 default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
789 ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
790 default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
791 ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
792 default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
793 ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
794 default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
795 ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_inc_factor,
796 default_config.suppressor.normal_tuning.max_inc_factor);
797 ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
798 default_config.suppressor.normal_tuning.max_dec_factor_lf);
799 ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
800 default_config.suppressor.dominant_nearend_detection.enr_threshold);
801 ASSERT_NE(
802 adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
803 default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
804 ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
805 default_config.suppressor.dominant_nearend_detection.snr_threshold);
806 ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
807 default_config.suppressor.dominant_nearend_detection.hold_duration);
808 ASSERT_NE(
809 adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
810 default_config.suppressor.dominant_nearend_detection.trigger_threshold);
811 ASSERT_NE(adjusted_config.ep_strength.default_len,
812 default_config.ep_strength.default_len);
813
814 EXPECT_FLOAT_EQ(
815 adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent, 0.1);
816 EXPECT_FLOAT_EQ(
817 adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress, 0.2);
818 EXPECT_FLOAT_EQ(
819 adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent, 0.3);
820 EXPECT_FLOAT_EQ(
821 adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress, 0.4);
822 EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
823 0.5);
824 EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
825 0.6);
826 EXPECT_FLOAT_EQ(
827 adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent, 0.7);
828 EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
829 0.8);
830 EXPECT_FLOAT_EQ(
831 adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent, 0.9);
832 EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
833 1.0);
834 EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor, 1.1);
835 EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
836 1.2);
837 EXPECT_FLOAT_EQ(
838 adjusted_config.suppressor.dominant_nearend_detection.enr_threshold, 1.3);
839 EXPECT_FLOAT_EQ(
840 adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
841 1.4);
842 EXPECT_FLOAT_EQ(
843 adjusted_config.suppressor.dominant_nearend_detection.snr_threshold, 1.5);
844 EXPECT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
845 10);
846 EXPECT_EQ(
847 adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
848 11);
849 EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 1.6);
850}
851
852// Testing the field trial-based override of the suppressor parameters for
853// passing one parameter.
854TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideOneParam) {
855 webrtc::test::ScopedFieldTrials field_trials(
856 "WebRTC-Aec3SuppressorTuningOverride/nearend_tuning_max_inc_factor:0.5/");
857
858 EchoCanceller3Config default_config;
859 EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
860
861 ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
862 default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
863 ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
864 default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
865 ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
866 default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
867 ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
868 default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
869 ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
870 default_config.suppressor.nearend_tuning.max_dec_factor_lf);
871 ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
872 default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
873 ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
874 default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
875 ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
876 default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
877 ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
878 default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
879 ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor,
880 default_config.suppressor.normal_tuning.max_inc_factor);
881 ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
882 default_config.suppressor.normal_tuning.max_dec_factor_lf);
883 ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
884 default_config.suppressor.dominant_nearend_detection.enr_threshold);
885 ASSERT_EQ(
886 adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
887 default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
888 ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
889 default_config.suppressor.dominant_nearend_detection.snr_threshold);
890 ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
891 default_config.suppressor.dominant_nearend_detection.hold_duration);
892 ASSERT_EQ(
893 adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
894 default_config.suppressor.dominant_nearend_detection.trigger_threshold);
895
896 ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
897 default_config.suppressor.nearend_tuning.max_inc_factor);
898
899 EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
900 0.5);
901}
902
peahd0263542017-01-03 04:20:34 -0800903#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
peahd0263542017-01-03 04:20:34 -0800904
Tommia5e07cc2020-05-26 21:40:37 +0200905TEST(EchoCanceller3InputCheckDeathTest, WrongCaptureNumBandsCheckVerification) {
Per Åhgrence202a02019-09-02 17:01:19 +0200906 for (auto rate : {16000, 32000, 48000}) {
peahd0263542017-01-03 04:20:34 -0800907 SCOPED_TRACE(ProduceDebugText(rate));
908 EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
909 }
910}
911
peahd0263542017-01-03 04:20:34 -0800912// Verifiers that the verification for null input to the capture processing api
913// call works.
Tommia5e07cc2020-05-26 21:40:37 +0200914TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
Per Åhgrence202a02019-09-02 17:01:19 +0200915 EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 16000, 1, 1)
Gustaf Ullbergbd83b912017-10-18 12:32:42 +0200916 .ProcessCapture(nullptr, false),
917 "");
peahd0263542017-01-03 04:20:34 -0800918}
919
peah21920892017-02-08 05:08:56 -0800920// Verifies the check for correct sample rate.
peahcf02cf12017-04-05 14:18:07 -0700921// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
922// tests on test bots has been fixed.
Tommia5e07cc2020-05-26 21:40:37 +0200923TEST(EchoCanceller3InputCheckDeathTest, DISABLED_WrongSampleRate) {
peah21920892017-02-08 05:08:56 -0800924 ApmDataDumper data_dumper(0);
Per Åhgrence202a02019-09-02 17:01:19 +0200925 EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001, 1, 1), "");
peah21920892017-02-08 05:08:56 -0800926}
927
peahd0263542017-01-03 04:20:34 -0800928#endif
929
930} // namespace webrtc