Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1095)

Side by Side Diff: webrtc/modules/audio_processing/aec3/aec_state_unittest.cc

Issue 2782423003: Major updates to the echo removal functionality in AEC3 (Closed)
Patch Set: Added initialization of uninitialized vector Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_processing/aec3/aec_state.h" 11 #include "webrtc/modules/audio_processing/aec3/aec_state.h"
12 12
13 // TODO(peah): Reactivate once the next CL has landed.
14 #if 0
15
16 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" 13 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h"
17 #include "webrtc/test/gtest.h" 14 #include "webrtc/test/gtest.h"
18 15
19 namespace webrtc { 16 namespace webrtc {
20 17
21 // Verify the general functionality of AecState 18 // Verify the general functionality of AecState
22 TEST(AecState, NormalUsage) { 19 TEST(AecState, NormalUsage) {
23 ApmDataDumper data_dumper(42); 20 ApmDataDumper data_dumper(42);
24 AecState state; 21 AecState state;
25 FftBuffer X_buffer(Aec3Optimization::kNone, 30, std::vector<size_t>(1, 30)); 22 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
26 std::array<float, kFftLengthBy2Plus1> E2_main; 23 std::vector<size_t>(1, 30));
27 std::array<float, kFftLengthBy2Plus1> E2_shadow; 24 std::array<float, kFftLengthBy2Plus1> E2_main = {};
28 std::array<float, kFftLengthBy2Plus1> Y2; 25 std::array<float, kFftLengthBy2Plus1> Y2 = {};
29 std::array<float, kBlockSize> x; 26 std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
30 EchoPathVariability echo_path_variability(false, false); 27 EchoPathVariability echo_path_variability(false, false);
31 x.fill(0.f);
32 28
33 std::vector<std::array<float, kFftLengthBy2Plus1>> 29 std::vector<std::array<float, kFftLengthBy2Plus1>>
34 converged_filter_frequency_response(10); 30 converged_filter_frequency_response(10);
35 for (auto& v : converged_filter_frequency_response) { 31 for (auto& v : converged_filter_frequency_response) {
36 v.fill(0.01f); 32 v.fill(0.01f);
37 } 33 }
38 std::vector<std::array<float, kFftLengthBy2Plus1>> 34 std::vector<std::array<float, kFftLengthBy2Plus1>>
39 diverged_filter_frequency_response = converged_filter_frequency_response; 35 diverged_filter_frequency_response = converged_filter_frequency_response;
40 converged_filter_frequency_response[2].fill(100.f); 36 converged_filter_frequency_response[2].fill(100.f);
37 converged_filter_frequency_response[2][0] = 1.f;
41 38
42 // Verify that model based aec feasibility and linear AEC usability are false 39 // Verify that linear AEC usability is false when the filter is diverged and
43 // when the filter is diverged and there is no external delay reported. 40 // there is no external delay reported.
44 state.Update(diverged_filter_frequency_response, rtc::Optional<size_t>(), 41 state.Update(diverged_filter_frequency_response, rtc::Optional<size_t>(),
45 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 42 render_buffer, E2_main, Y2, x[0], false);
46 false);
47 EXPECT_FALSE(state.ModelBasedAecFeasible());
48 EXPECT_FALSE(state.UsableLinearEstimate());
49
50 // Verify that model based aec feasibility is true and that linear AEC
51 // usability is false when the filter is diverged and there is an external
52 // delay reported.
53 state.Update(diverged_filter_frequency_response, rtc::Optional<size_t>(),
54 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability,
55 false);
56 EXPECT_FALSE(state.ModelBasedAecFeasible());
57 for (int k = 0; k < 50; ++k) {
58 state.Update(diverged_filter_frequency_response, rtc::Optional<size_t>(2),
59 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability,
60 false);
61 }
62 EXPECT_TRUE(state.ModelBasedAecFeasible());
63 EXPECT_FALSE(state.UsableLinearEstimate()); 43 EXPECT_FALSE(state.UsableLinearEstimate());
64 44
65 // Verify that linear AEC usability is true when the filter is converged 45 // Verify that linear AEC usability is true when the filter is converged
66 for (int k = 0; k < 50; ++k) { 46 std::fill(x[0].begin(), x[0].end(), 101.f);
47 for (int k = 0; k < 3000; ++k) {
67 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 48 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
68 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 49 render_buffer, E2_main, Y2, x[0], false);
69 false);
70 } 50 }
71 EXPECT_TRUE(state.UsableLinearEstimate()); 51 EXPECT_TRUE(state.UsableLinearEstimate());
72 52
73 // Verify that linear AEC usability becomes false after an echo path change is 53 // Verify that linear AEC usability becomes false after an echo path change is
74 // reported 54 // reported
75 echo_path_variability = EchoPathVariability(true, false); 55 state.HandleEchoPathChange(EchoPathVariability(true, false));
76 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 56 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
77 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 57 render_buffer, E2_main, Y2, x[0], false);
78 false);
79 EXPECT_FALSE(state.UsableLinearEstimate()); 58 EXPECT_FALSE(state.UsableLinearEstimate());
80 59
81 // Verify that the active render detection works as intended. 60 // Verify that the active render detection works as intended.
82 x.fill(101.f); 61 std::fill(x[0].begin(), x[0].end(), 101.f);
62 state.HandleEchoPathChange(EchoPathVariability(true, true));
83 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 63 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
84 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 64 render_buffer, E2_main, Y2, x[0], false);
85 false);
86 EXPECT_TRUE(state.ActiveRender());
87
88 x.fill(0.f);
89 for (int k = 0; k < 200; ++k) {
90 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
91 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability,
92 false);
93 }
94 EXPECT_FALSE(state.ActiveRender()); 65 EXPECT_FALSE(state.ActiveRender());
95 66
96 x.fill(101.f); 67 for (int k = 0; k < 1000; ++k) {
97 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 68 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
98 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 69 render_buffer, E2_main, Y2, x[0], false);
99 false); 70 }
100 EXPECT_TRUE(state.ActiveRender()); 71 EXPECT_TRUE(state.ActiveRender());
101 72
102 // Verify that echo leakage is properly reported. 73 // Verify that echo leakage is properly reported.
103 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 74 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
104 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 75 render_buffer, E2_main, Y2, x[0], false);
105 false);
106 EXPECT_FALSE(state.EchoLeakageDetected()); 76 EXPECT_FALSE(state.EchoLeakageDetected());
107 77
108 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 78 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
109 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 79 render_buffer, E2_main, Y2, x[0], true);
110 true);
111 EXPECT_TRUE(state.EchoLeakageDetected()); 80 EXPECT_TRUE(state.EchoLeakageDetected());
112 81
113 // Verify that the bands containing reliable filter estimates are properly 82 // Verify that the ERL is properly estimated
114 // reported. 83 for (auto& x_k : x) {
115 echo_path_variability = EchoPathVariability(false, false); 84 x_k = std::vector<float>(kBlockSize, 0.f);
116 for (int k = 0; k < 200; ++k) {
117 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
118 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability,
119 false);
120 } 85 }
121 86
122 FftData X; 87 x[0][0] = 5000.f;
123 X.re.fill(10000.f); 88 for (size_t k = 0; k < render_buffer.Buffer().size(); ++k) {
124 X.im.fill(0.f); 89 render_buffer.Insert(x);
125 for (size_t k = 0; k < X_buffer.Buffer().size(); ++k) {
126 X_buffer.Insert(X);
127 } 90 }
128 91
129 Y2.fill(10.f * 1000.f * 1000.f); 92 Y2.fill(10.f * 10000.f * 10000.f);
130 E2_main.fill(100.f * Y2[0]); 93 for (size_t k = 0; k < 1000; ++k) {
131 E2_shadow.fill(100.f * Y2[0]);
132 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
133 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability,
134 false);
135
136 E2_main.fill(0.1f * Y2[0]);
137 E2_shadow.fill(E2_main[0]);
138 for (size_t k = 0; k < Y2.size(); k += 2) {
139 E2_main[k] = Y2[k];
140 E2_shadow[k] = Y2[k];
141 }
142 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
143 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability,
144 false);
145
146 const std::array<bool, kFftLengthBy2Plus1>& reliable_bands =
147 state.BandsWithReliableFilter();
148
149 EXPECT_EQ(reliable_bands[0], reliable_bands[1]);
150 for (size_t k = 1; k < kFftLengthBy2 - 5; ++k) {
151 EXPECT_TRUE(reliable_bands[k]);
152 }
153 for (size_t k = kFftLengthBy2 - 5; k < reliable_bands.size(); ++k) {
154 EXPECT_EQ(reliable_bands[kFftLengthBy2 - 6], reliable_bands[k]);
155 }
156
157 // Verify that the ERL is properly estimated
158 Y2.fill(10.f * X.re[0] * X.re[0]);
159 for (size_t k = 0; k < 100000; ++k) {
160 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 94 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
161 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 95 render_buffer, E2_main, Y2, x[0], false);
162 false);
163 } 96 }
164 97
165 ASSERT_TRUE(state.UsableLinearEstimate()); 98 ASSERT_TRUE(state.UsableLinearEstimate());
166 const std::array<float, kFftLengthBy2Plus1>& erl = state.Erl(); 99 const std::array<float, kFftLengthBy2Plus1>& erl = state.Erl();
167 std::for_each(erl.begin(), erl.end(), 100 EXPECT_EQ(erl[0], erl[1]);
168 [](float a) { EXPECT_NEAR(10.f, a, 0.1); }); 101 for (size_t k = 1; k < erl.size() - 1; ++k) {
102 EXPECT_NEAR(k % 2 == 0 ? 10.f : 1000.f, erl[k], 0.1);
103 }
104 EXPECT_EQ(erl[erl.size() - 2], erl[erl.size() - 1]);
169 105
170 // Verify that the ERLE is properly estimated 106 // Verify that the ERLE is properly estimated
171 E2_main.fill(1.f * X.re[0] * X.re[0]); 107 E2_main.fill(1.f * 10000.f * 10000.f);
172 Y2.fill(10.f * E2_main[0]); 108 Y2.fill(10.f * E2_main[0]);
173 for (size_t k = 0; k < 10000; ++k) { 109 for (size_t k = 0; k < 1000; ++k) {
174 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 110 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
175 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 111 render_buffer, E2_main, Y2, x[0], false);
176 false);
177 } 112 }
178 ASSERT_TRUE(state.UsableLinearEstimate()); 113 ASSERT_TRUE(state.UsableLinearEstimate());
179 std::for_each(state.Erle().begin(), state.Erle().end(), 114 {
180 [](float a) { EXPECT_NEAR(8.f, a, 0.1); }); 115 const auto& erle = state.Erle();
116 EXPECT_EQ(erle[0], erle[1]);
117 for (size_t k = 1; k < erle.size() - 1; ++k) {
118 EXPECT_NEAR(k % 2 == 0 ? 8.f : 1.f, erle[k], 0.1);
119 }
120 EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]);
121 }
181 122
182 E2_main.fill(1.f * X.re[0] * X.re[0]); 123 E2_main.fill(1.f * 10000.f * 10000.f);
183 Y2.fill(5.f * E2_main[0]); 124 Y2.fill(5.f * E2_main[0]);
184 for (size_t k = 0; k < 10000; ++k) { 125 for (size_t k = 0; k < 1000; ++k) {
185 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), 126 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2),
186 X_buffer, E2_main, E2_shadow, Y2, x, echo_path_variability, 127 render_buffer, E2_main, Y2, x[0], false);
187 false);
188 } 128 }
129
189 ASSERT_TRUE(state.UsableLinearEstimate()); 130 ASSERT_TRUE(state.UsableLinearEstimate());
190 std::for_each(state.Erle().begin(), state.Erle().end(), 131 {
191 [](float a) { EXPECT_NEAR(5.f, a, 0.1); }); 132 const auto& erle = state.Erle();
133 EXPECT_EQ(erle[0], erle[1]);
134 for (size_t k = 1; k < erle.size() - 1; ++k) {
135 EXPECT_NEAR(k % 2 == 0 ? 5.f : 1.f, erle[k], 0.1);
136 }
137 EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]);
138 }
192 } 139 }
193 140
194 // Verifies the a non-significant delay is correctly identified. 141 // Verifies the a non-significant delay is correctly identified.
195 TEST(AecState, NonSignificantDelay) { 142 TEST(AecState, NonSignificantDelay) {
196 AecState state; 143 AecState state;
197 FftBuffer X_buffer(Aec3Optimization::kNone, 30, std::vector<size_t>(1, 30)); 144 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
145 std::vector<size_t>(1, 30));
198 std::array<float, kFftLengthBy2Plus1> E2_main; 146 std::array<float, kFftLengthBy2Plus1> E2_main;
199 std::array<float, kFftLengthBy2Plus1> E2_shadow;
200 std::array<float, kFftLengthBy2Plus1> Y2; 147 std::array<float, kFftLengthBy2Plus1> Y2;
201 std::array<float, kBlockSize> x; 148 std::array<float, kBlockSize> x;
202 EchoPathVariability echo_path_variability(false, false); 149 EchoPathVariability echo_path_variability(false, false);
203 x.fill(0.f); 150 x.fill(0.f);
204 151
205 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30); 152 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30);
206 for (auto& v : frequency_response) { 153 for (auto& v : frequency_response) {
207 v.fill(0.01f); 154 v.fill(0.01f);
208 } 155 }
209 156
210 // Verify that a non-significant filter delay is identified correctly. 157 // Verify that a non-significant filter delay is identified correctly.
211 state.Update(frequency_response, rtc::Optional<size_t>(), X_buffer, E2_main, 158 state.HandleEchoPathChange(echo_path_variability);
212 E2_shadow, Y2, x, echo_path_variability, false); 159 state.Update(frequency_response, rtc::Optional<size_t>(), render_buffer,
160 E2_main, Y2, x, false);
213 EXPECT_FALSE(state.FilterDelay()); 161 EXPECT_FALSE(state.FilterDelay());
214 } 162 }
215 163
216 // Verifies the delay for a converged filter is correctly identified. 164 // Verifies the delay for a converged filter is correctly identified.
217 TEST(AecState, ConvergedFilterDelay) { 165 TEST(AecState, ConvergedFilterDelay) {
218 constexpr int kFilterLength = 10; 166 constexpr int kFilterLength = 10;
219 AecState state; 167 AecState state;
220 FftBuffer X_buffer(Aec3Optimization::kNone, 30, std::vector<size_t>(1, 30)); 168 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
169 std::vector<size_t>(1, 30));
221 std::array<float, kFftLengthBy2Plus1> E2_main; 170 std::array<float, kFftLengthBy2Plus1> E2_main;
222 std::array<float, kFftLengthBy2Plus1> E2_shadow;
223 std::array<float, kFftLengthBy2Plus1> Y2; 171 std::array<float, kFftLengthBy2Plus1> Y2;
224 std::array<float, kBlockSize> x; 172 std::array<float, kBlockSize> x;
225 EchoPathVariability echo_path_variability(false, false); 173 EchoPathVariability echo_path_variability(false, false);
226 x.fill(0.f); 174 x.fill(0.f);
227 175
228 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response( 176 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(
229 kFilterLength); 177 kFilterLength);
230 178
231 // Verify that the filter delay for a converged filter is properly identified. 179 // Verify that the filter delay for a converged filter is properly identified.
232 for (int k = 0; k < kFilterLength; ++k) { 180 for (int k = 0; k < kFilterLength; ++k) {
233 for (auto& v : frequency_response) { 181 for (auto& v : frequency_response) {
234 v.fill(0.01f); 182 v.fill(0.01f);
235 } 183 }
236 frequency_response[k].fill(100.f); 184 frequency_response[k].fill(100.f);
237 185 frequency_response[k][0] = 0.f;
238 state.Update(frequency_response, rtc::Optional<size_t>(), X_buffer, E2_main, 186 state.HandleEchoPathChange(echo_path_variability);
239 E2_shadow, Y2, x, echo_path_variability, false); 187 state.Update(frequency_response, rtc::Optional<size_t>(), render_buffer,
188 E2_main, Y2, x, false);
240 EXPECT_TRUE(k == (kFilterLength - 1) || state.FilterDelay()); 189 EXPECT_TRUE(k == (kFilterLength - 1) || state.FilterDelay());
241 if (k != (kFilterLength - 1)) { 190 if (k != (kFilterLength - 1)) {
242 EXPECT_EQ(k, state.FilterDelay()); 191 EXPECT_EQ(k, state.FilterDelay());
243 } 192 }
244 } 193 }
245 } 194 }
246 195
247 // Verify that the externally reported delay is properly reported and converted. 196 // Verify that the externally reported delay is properly reported and converted.
248 TEST(AecState, ExternalDelay) { 197 TEST(AecState, ExternalDelay) {
249 AecState state; 198 AecState state;
250 std::array<float, kFftLengthBy2Plus1> E2_main; 199 std::array<float, kFftLengthBy2Plus1> E2_main;
251 std::array<float, kFftLengthBy2Plus1> E2_shadow; 200 std::array<float, kFftLengthBy2Plus1> E2_shadow;
252 std::array<float, kFftLengthBy2Plus1> Y2; 201 std::array<float, kFftLengthBy2Plus1> Y2;
253 std::array<float, kBlockSize> x; 202 std::array<float, kBlockSize> x;
254 E2_main.fill(0.f); 203 E2_main.fill(0.f);
255 E2_shadow.fill(0.f); 204 E2_shadow.fill(0.f);
256 Y2.fill(0.f); 205 Y2.fill(0.f);
257 x.fill(0.f); 206 x.fill(0.f);
258 FftBuffer X_buffer(Aec3Optimization::kNone, 30, std::vector<size_t>(1, 30)); 207 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30,
208 std::vector<size_t>(1, 30));
259 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30); 209 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30);
260 for (auto& v : frequency_response) { 210 for (auto& v : frequency_response) {
261 v.fill(0.01f); 211 v.fill(0.01f);
262 } 212 }
263 213
264 for (size_t k = 0; k < frequency_response.size() - 1; ++k) { 214 for (size_t k = 0; k < frequency_response.size() - 1; ++k) {
215 state.HandleEchoPathChange(EchoPathVariability(false, false));
265 state.Update(frequency_response, rtc::Optional<size_t>(k * kBlockSize + 5), 216 state.Update(frequency_response, rtc::Optional<size_t>(k * kBlockSize + 5),
266 X_buffer, E2_main, E2_shadow, Y2, x, 217 render_buffer, E2_main, Y2, x, false);
267 EchoPathVariability(false, false), false);
268 EXPECT_TRUE(state.ExternalDelay()); 218 EXPECT_TRUE(state.ExternalDelay());
269 EXPECT_EQ(k, state.ExternalDelay()); 219 EXPECT_EQ(k, state.ExternalDelay());
270 } 220 }
271 221
272 // Verify that the externally reported delay is properly unset when it is no 222 // Verify that the externally reported delay is properly unset when it is no
273 // longer present. 223 // longer present.
274 state.Update(frequency_response, rtc::Optional<size_t>(), X_buffer, E2_main, 224 state.HandleEchoPathChange(EchoPathVariability(false, false));
275 E2_shadow, Y2, x, EchoPathVariability(false, false), false); 225 state.Update(frequency_response, rtc::Optional<size_t>(), render_buffer,
226 E2_main, Y2, x, false);
276 EXPECT_FALSE(state.ExternalDelay()); 227 EXPECT_FALSE(state.ExternalDelay());
277 } 228 }
278 229
279 } // namespace webrtc 230 } // namespace webrtc
280
281 #endif
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec3/aec_state.cc ('k') | webrtc/modules/audio_processing/aec3/comfort_noise_generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698