1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/audio_processing/residual_echo_detector.h"
12
13 #include <vector>
14
15 #include "api/make_ref_counted.h"
16 #include "test/gtest.h"
17
18 namespace webrtc {
19
TEST(ResidualEchoDetectorTests,Echo)20 TEST(ResidualEchoDetectorTests, Echo) {
21 auto echo_detector = rtc::make_ref_counted<ResidualEchoDetector>();
22 echo_detector->SetReliabilityForTest(1.0f);
23 std::vector<float> ones(160, 1.f);
24 std::vector<float> zeros(160, 0.f);
25
26 // In this test the capture signal has a delay of 10 frames w.r.t. the render
27 // signal, but is otherwise identical. Both signals are periodic with a 20
28 // frame interval.
29 for (int i = 0; i < 1000; i++) {
30 if (i % 20 == 0) {
31 echo_detector->AnalyzeRenderAudio(ones);
32 echo_detector->AnalyzeCaptureAudio(zeros);
33 } else if (i % 20 == 10) {
34 echo_detector->AnalyzeRenderAudio(zeros);
35 echo_detector->AnalyzeCaptureAudio(ones);
36 } else {
37 echo_detector->AnalyzeRenderAudio(zeros);
38 echo_detector->AnalyzeCaptureAudio(zeros);
39 }
40 }
41 // We expect to detect echo with near certain likelihood.
42 auto ed_metrics = echo_detector->GetMetrics();
43 ASSERT_TRUE(ed_metrics.echo_likelihood);
44 EXPECT_NEAR(1.f, ed_metrics.echo_likelihood.value(), 0.01f);
45 }
46
TEST(ResidualEchoDetectorTests,NoEcho)47 TEST(ResidualEchoDetectorTests, NoEcho) {
48 auto echo_detector = rtc::make_ref_counted<ResidualEchoDetector>();
49 echo_detector->SetReliabilityForTest(1.0f);
50 std::vector<float> ones(160, 1.f);
51 std::vector<float> zeros(160, 0.f);
52
53 // In this test the capture signal is always zero, so no echo should be
54 // detected.
55 for (int i = 0; i < 1000; i++) {
56 if (i % 20 == 0) {
57 echo_detector->AnalyzeRenderAudio(ones);
58 } else {
59 echo_detector->AnalyzeRenderAudio(zeros);
60 }
61 echo_detector->AnalyzeCaptureAudio(zeros);
62 }
63 // We expect to not detect any echo.
64 auto ed_metrics = echo_detector->GetMetrics();
65 ASSERT_TRUE(ed_metrics.echo_likelihood);
66 EXPECT_NEAR(0.f, ed_metrics.echo_likelihood.value(), 0.01f);
67 }
68
TEST(ResidualEchoDetectorTests,EchoWithRenderClockDrift)69 TEST(ResidualEchoDetectorTests, EchoWithRenderClockDrift) {
70 auto echo_detector = rtc::make_ref_counted<ResidualEchoDetector>();
71 echo_detector->SetReliabilityForTest(1.0f);
72 std::vector<float> ones(160, 1.f);
73 std::vector<float> zeros(160, 0.f);
74
75 // In this test the capture signal has a delay of 10 frames w.r.t. the render
76 // signal, but is otherwise identical. Both signals are periodic with a 20
77 // frame interval. There is a simulated clock drift of 1% in this test, with
78 // the render side producing data slightly faster.
79 for (int i = 0; i < 1000; i++) {
80 if (i % 20 == 0) {
81 echo_detector->AnalyzeRenderAudio(ones);
82 echo_detector->AnalyzeCaptureAudio(zeros);
83 } else if (i % 20 == 10) {
84 echo_detector->AnalyzeRenderAudio(zeros);
85 echo_detector->AnalyzeCaptureAudio(ones);
86 } else {
87 echo_detector->AnalyzeRenderAudio(zeros);
88 echo_detector->AnalyzeCaptureAudio(zeros);
89 }
90 if (i % 100 == 0) {
91 // This is causing the simulated clock drift.
92 echo_detector->AnalyzeRenderAudio(zeros);
93 }
94 }
95 // We expect to detect echo with high likelihood. Clock drift is harder to
96 // correct on the render side than on the capture side. This is due to the
97 // render buffer, clock drift can only be discovered after a certain delay.
98 // A growing buffer can be caused by jitter or clock drift and it's not
99 // possible to make this decision right away. For this reason we only expect
100 // an echo likelihood of 75% in this test.
101 auto ed_metrics = echo_detector->GetMetrics();
102 ASSERT_TRUE(ed_metrics.echo_likelihood);
103 EXPECT_GT(ed_metrics.echo_likelihood.value(), 0.75f);
104 }
105
TEST(ResidualEchoDetectorTests,EchoWithCaptureClockDrift)106 TEST(ResidualEchoDetectorTests, EchoWithCaptureClockDrift) {
107 auto echo_detector = rtc::make_ref_counted<ResidualEchoDetector>();
108 echo_detector->SetReliabilityForTest(1.0f);
109 std::vector<float> ones(160, 1.f);
110 std::vector<float> zeros(160, 0.f);
111
112 // In this test the capture signal has a delay of 10 frames w.r.t. the render
113 // signal, but is otherwise identical. Both signals are periodic with a 20
114 // frame interval. There is a simulated clock drift of 1% in this test, with
115 // the capture side producing data slightly faster.
116 for (int i = 0; i < 1000; i++) {
117 if (i % 20 == 0) {
118 echo_detector->AnalyzeRenderAudio(ones);
119 echo_detector->AnalyzeCaptureAudio(zeros);
120 } else if (i % 20 == 10) {
121 echo_detector->AnalyzeRenderAudio(zeros);
122 echo_detector->AnalyzeCaptureAudio(ones);
123 } else {
124 echo_detector->AnalyzeRenderAudio(zeros);
125 echo_detector->AnalyzeCaptureAudio(zeros);
126 }
127 if (i % 100 == 0) {
128 // This is causing the simulated clock drift.
129 echo_detector->AnalyzeCaptureAudio(zeros);
130 }
131 }
132 // We expect to detect echo with near certain likelihood.
133 auto ed_metrics = echo_detector->GetMetrics();
134 ASSERT_TRUE(ed_metrics.echo_likelihood);
135 EXPECT_NEAR(1.f, ed_metrics.echo_likelihood.value(), 0.01f);
136 }
137
138 } // namespace webrtc
139