OLD | NEW |
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 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" | 13 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" |
14 #include "webrtc/test/gtest.h" | 14 #include "webrtc/test/gtest.h" |
15 | 15 |
16 namespace webrtc { | 16 namespace webrtc { |
17 | 17 |
18 // Verify the general functionality of AecState | 18 // Verify the general functionality of AecState |
19 TEST(AecState, NormalUsage) { | 19 TEST(AecState, NormalUsage) { |
20 ApmDataDumper data_dumper(42); | 20 ApmDataDumper data_dumper(42); |
21 AecState state(0.f); | 21 AecState state(0.f); |
22 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, | 22 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, |
23 std::vector<size_t>(1, 30)); | 23 std::vector<size_t>(1, 30)); |
24 std::array<float, kFftLengthBy2Plus1> E2_main = {}; | 24 std::array<float, kFftLengthBy2Plus1> E2_main = {}; |
25 std::array<float, kFftLengthBy2Plus1> Y2 = {}; | 25 std::array<float, kFftLengthBy2Plus1> Y2 = {}; |
26 std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f)); | 26 std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f)); |
27 EchoPathVariability echo_path_variability(false, false); | 27 EchoPathVariability echo_path_variability(false, false); |
| 28 std::array<float, kBlockSize> s; |
| 29 s.fill(100.f); |
28 | 30 |
29 std::vector<std::array<float, kFftLengthBy2Plus1>> | 31 std::vector<std::array<float, kFftLengthBy2Plus1>> |
30 converged_filter_frequency_response(10); | 32 converged_filter_frequency_response(10); |
31 for (auto& v : converged_filter_frequency_response) { | 33 for (auto& v : converged_filter_frequency_response) { |
32 v.fill(0.01f); | 34 v.fill(0.01f); |
33 } | 35 } |
34 std::vector<std::array<float, kFftLengthBy2Plus1>> | 36 std::vector<std::array<float, kFftLengthBy2Plus1>> |
35 diverged_filter_frequency_response = converged_filter_frequency_response; | 37 diverged_filter_frequency_response = converged_filter_frequency_response; |
36 converged_filter_frequency_response[2].fill(100.f); | 38 converged_filter_frequency_response[2].fill(100.f); |
37 converged_filter_frequency_response[2][0] = 1.f; | 39 converged_filter_frequency_response[2][0] = 1.f; |
38 | 40 |
| 41 std::array<float, kAdaptiveFilterTimeDomainLength> impulse_response; |
| 42 impulse_response.fill(0.f); |
| 43 |
39 // Verify that linear AEC usability is false when the filter is diverged and | 44 // Verify that linear AEC usability is false when the filter is diverged and |
40 // there is no external delay reported. | 45 // there is no external delay reported. |
41 state.Update(diverged_filter_frequency_response, rtc::Optional<size_t>(), | 46 state.Update(diverged_filter_frequency_response, impulse_response, |
42 render_buffer, E2_main, Y2, x[0], false); | 47 rtc::Optional<size_t>(), render_buffer, E2_main, Y2, x[0], s, |
| 48 false); |
43 EXPECT_FALSE(state.UsableLinearEstimate()); | 49 EXPECT_FALSE(state.UsableLinearEstimate()); |
44 | 50 |
45 // Verify that linear AEC usability is true when the filter is converged | 51 // Verify that linear AEC usability is true when the filter is converged |
46 std::fill(x[0].begin(), x[0].end(), 101.f); | 52 std::fill(x[0].begin(), x[0].end(), 101.f); |
47 for (int k = 0; k < 3000; ++k) { | 53 for (int k = 0; k < 3000; ++k) { |
48 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 54 state.Update(converged_filter_frequency_response, impulse_response, |
49 render_buffer, E2_main, Y2, x[0], false); | 55 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 56 false); |
50 } | 57 } |
51 EXPECT_TRUE(state.UsableLinearEstimate()); | 58 EXPECT_TRUE(state.UsableLinearEstimate()); |
52 | 59 |
53 // Verify that linear AEC usability becomes false after an echo path change is | 60 // Verify that linear AEC usability becomes false after an echo path change is |
54 // reported | 61 // reported |
55 state.HandleEchoPathChange(EchoPathVariability(true, false)); | 62 state.HandleEchoPathChange(EchoPathVariability(true, false)); |
56 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 63 state.Update(converged_filter_frequency_response, impulse_response, |
57 render_buffer, E2_main, Y2, x[0], false); | 64 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 65 false); |
58 EXPECT_FALSE(state.UsableLinearEstimate()); | 66 EXPECT_FALSE(state.UsableLinearEstimate()); |
59 | 67 |
60 // Verify that the active render detection works as intended. | 68 // Verify that the active render detection works as intended. |
61 std::fill(x[0].begin(), x[0].end(), 101.f); | 69 std::fill(x[0].begin(), x[0].end(), 101.f); |
62 state.HandleEchoPathChange(EchoPathVariability(true, true)); | 70 state.HandleEchoPathChange(EchoPathVariability(true, true)); |
63 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 71 state.Update(converged_filter_frequency_response, impulse_response, |
64 render_buffer, E2_main, Y2, x[0], false); | 72 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 73 false); |
65 EXPECT_FALSE(state.ActiveRender()); | 74 EXPECT_FALSE(state.ActiveRender()); |
66 | 75 |
67 for (int k = 0; k < 1000; ++k) { | 76 for (int k = 0; k < 1000; ++k) { |
68 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 77 state.Update(converged_filter_frequency_response, impulse_response, |
69 render_buffer, E2_main, Y2, x[0], false); | 78 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 79 false); |
70 } | 80 } |
71 EXPECT_TRUE(state.ActiveRender()); | 81 EXPECT_TRUE(state.ActiveRender()); |
72 | 82 |
73 // Verify that echo leakage is properly reported. | 83 // Verify that echo leakage is properly reported. |
74 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 84 state.Update(converged_filter_frequency_response, impulse_response, |
75 render_buffer, E2_main, Y2, x[0], false); | 85 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 86 false); |
76 EXPECT_FALSE(state.EchoLeakageDetected()); | 87 EXPECT_FALSE(state.EchoLeakageDetected()); |
77 | 88 |
78 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 89 state.Update(converged_filter_frequency_response, impulse_response, |
79 render_buffer, E2_main, Y2, x[0], true); | 90 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 91 true); |
80 EXPECT_TRUE(state.EchoLeakageDetected()); | 92 EXPECT_TRUE(state.EchoLeakageDetected()); |
81 | 93 |
82 // Verify that the ERL is properly estimated | 94 // Verify that the ERL is properly estimated |
83 for (auto& x_k : x) { | 95 for (auto& x_k : x) { |
84 x_k = std::vector<float>(kBlockSize, 0.f); | 96 x_k = std::vector<float>(kBlockSize, 0.f); |
85 } | 97 } |
86 | 98 |
87 x[0][0] = 5000.f; | 99 x[0][0] = 5000.f; |
88 for (size_t k = 0; k < render_buffer.Buffer().size(); ++k) { | 100 for (size_t k = 0; k < render_buffer.Buffer().size(); ++k) { |
89 render_buffer.Insert(x); | 101 render_buffer.Insert(x); |
90 } | 102 } |
91 | 103 |
92 Y2.fill(10.f * 10000.f * 10000.f); | 104 Y2.fill(10.f * 10000.f * 10000.f); |
93 for (size_t k = 0; k < 1000; ++k) { | 105 for (size_t k = 0; k < 1000; ++k) { |
94 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 106 state.Update(converged_filter_frequency_response, impulse_response, |
95 render_buffer, E2_main, Y2, x[0], false); | 107 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 108 false); |
96 } | 109 } |
97 | 110 |
98 ASSERT_TRUE(state.UsableLinearEstimate()); | 111 ASSERT_TRUE(state.UsableLinearEstimate()); |
99 const std::array<float, kFftLengthBy2Plus1>& erl = state.Erl(); | 112 const std::array<float, kFftLengthBy2Plus1>& erl = state.Erl(); |
100 EXPECT_EQ(erl[0], erl[1]); | 113 EXPECT_EQ(erl[0], erl[1]); |
101 for (size_t k = 1; k < erl.size() - 1; ++k) { | 114 for (size_t k = 1; k < erl.size() - 1; ++k) { |
102 EXPECT_NEAR(k % 2 == 0 ? 10.f : 1000.f, erl[k], 0.1); | 115 EXPECT_NEAR(k % 2 == 0 ? 10.f : 1000.f, erl[k], 0.1); |
103 } | 116 } |
104 EXPECT_EQ(erl[erl.size() - 2], erl[erl.size() - 1]); | 117 EXPECT_EQ(erl[erl.size() - 2], erl[erl.size() - 1]); |
105 | 118 |
106 // Verify that the ERLE is properly estimated | 119 // Verify that the ERLE is properly estimated |
107 E2_main.fill(1.f * 10000.f * 10000.f); | 120 E2_main.fill(1.f * 10000.f * 10000.f); |
108 Y2.fill(10.f * E2_main[0]); | 121 Y2.fill(10.f * E2_main[0]); |
109 for (size_t k = 0; k < 1000; ++k) { | 122 for (size_t k = 0; k < 1000; ++k) { |
110 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 123 state.Update(converged_filter_frequency_response, impulse_response, |
111 render_buffer, E2_main, Y2, x[0], false); | 124 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 125 false); |
112 } | 126 } |
113 ASSERT_TRUE(state.UsableLinearEstimate()); | 127 ASSERT_TRUE(state.UsableLinearEstimate()); |
114 { | 128 { |
115 const auto& erle = state.Erle(); | 129 const auto& erle = state.Erle(); |
116 EXPECT_EQ(erle[0], erle[1]); | 130 EXPECT_EQ(erle[0], erle[1]); |
117 constexpr size_t kLowFrequencyLimit = 32; | 131 constexpr size_t kLowFrequencyLimit = 32; |
118 for (size_t k = 1; k < kLowFrequencyLimit; ++k) { | 132 for (size_t k = 1; k < kLowFrequencyLimit; ++k) { |
119 EXPECT_NEAR(k % 2 == 0 ? 8.f : 1.f, erle[k], 0.1); | 133 EXPECT_NEAR(k % 2 == 0 ? 8.f : 1.f, erle[k], 0.1); |
120 } | 134 } |
121 for (size_t k = kLowFrequencyLimit; k < erle.size() - 1; ++k) { | 135 for (size_t k = kLowFrequencyLimit; k < erle.size() - 1; ++k) { |
122 EXPECT_NEAR(k % 2 == 0 ? 1.5f : 1.f, erle[k], 0.1); | 136 EXPECT_NEAR(k % 2 == 0 ? 1.5f : 1.f, erle[k], 0.1); |
123 } | 137 } |
124 EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]); | 138 EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]); |
125 } | 139 } |
126 | 140 |
127 E2_main.fill(1.f * 10000.f * 10000.f); | 141 E2_main.fill(1.f * 10000.f * 10000.f); |
128 Y2.fill(5.f * E2_main[0]); | 142 Y2.fill(5.f * E2_main[0]); |
129 for (size_t k = 0; k < 1000; ++k) { | 143 for (size_t k = 0; k < 1000; ++k) { |
130 state.Update(converged_filter_frequency_response, rtc::Optional<size_t>(2), | 144 state.Update(converged_filter_frequency_response, impulse_response, |
131 render_buffer, E2_main, Y2, x[0], false); | 145 rtc::Optional<size_t>(2), render_buffer, E2_main, Y2, x[0], s, |
| 146 false); |
132 } | 147 } |
133 | 148 |
134 ASSERT_TRUE(state.UsableLinearEstimate()); | 149 ASSERT_TRUE(state.UsableLinearEstimate()); |
135 { | 150 { |
136 const auto& erle = state.Erle(); | 151 const auto& erle = state.Erle(); |
137 EXPECT_EQ(erle[0], erle[1]); | 152 EXPECT_EQ(erle[0], erle[1]); |
138 constexpr size_t kLowFrequencyLimit = 32; | 153 constexpr size_t kLowFrequencyLimit = 32; |
139 for (size_t k = 1; k < kLowFrequencyLimit; ++k) { | 154 for (size_t k = 1; k < kLowFrequencyLimit; ++k) { |
140 EXPECT_NEAR(k % 2 == 0 ? 5.f : 1.f, erle[k], 0.1); | 155 EXPECT_NEAR(k % 2 == 0 ? 5.f : 1.f, erle[k], 0.1); |
141 } | 156 } |
142 for (size_t k = kLowFrequencyLimit; k < erle.size() - 1; ++k) { | 157 for (size_t k = kLowFrequencyLimit; k < erle.size() - 1; ++k) { |
143 EXPECT_NEAR(k % 2 == 0 ? 1.5f : 1.f, erle[k], 0.1); | 158 EXPECT_NEAR(k % 2 == 0 ? 1.5f : 1.f, erle[k], 0.1); |
144 } | 159 } |
145 EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]); | 160 EXPECT_EQ(erle[erle.size() - 2], erle[erle.size() - 1]); |
146 } | 161 } |
147 } | 162 } |
148 | 163 |
149 // Verifies the a non-significant delay is correctly identified. | 164 // Verifies the a non-significant delay is correctly identified. |
150 TEST(AecState, NonSignificantDelay) { | 165 TEST(AecState, NonSignificantDelay) { |
151 AecState state(0.f); | 166 AecState state(0.f); |
152 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, | 167 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, |
153 std::vector<size_t>(1, 30)); | 168 std::vector<size_t>(1, 30)); |
154 std::array<float, kFftLengthBy2Plus1> E2_main; | 169 std::array<float, kFftLengthBy2Plus1> E2_main; |
155 std::array<float, kFftLengthBy2Plus1> Y2; | 170 std::array<float, kFftLengthBy2Plus1> Y2; |
156 std::array<float, kBlockSize> x; | 171 std::array<float, kBlockSize> x; |
157 EchoPathVariability echo_path_variability(false, false); | 172 EchoPathVariability echo_path_variability(false, false); |
| 173 std::array<float, kBlockSize> s; |
| 174 s.fill(100.f); |
158 x.fill(0.f); | 175 x.fill(0.f); |
159 | 176 |
160 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30); | 177 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30); |
161 for (auto& v : frequency_response) { | 178 for (auto& v : frequency_response) { |
162 v.fill(0.01f); | 179 v.fill(0.01f); |
163 } | 180 } |
164 | 181 |
| 182 std::array<float, kAdaptiveFilterTimeDomainLength> impulse_response; |
| 183 impulse_response.fill(0.f); |
| 184 |
165 // Verify that a non-significant filter delay is identified correctly. | 185 // Verify that a non-significant filter delay is identified correctly. |
166 state.HandleEchoPathChange(echo_path_variability); | 186 state.HandleEchoPathChange(echo_path_variability); |
167 state.Update(frequency_response, rtc::Optional<size_t>(), render_buffer, | 187 state.Update(frequency_response, impulse_response, rtc::Optional<size_t>(), |
168 E2_main, Y2, x, false); | 188 render_buffer, E2_main, Y2, x, s, false); |
169 EXPECT_FALSE(state.FilterDelay()); | 189 EXPECT_FALSE(state.FilterDelay()); |
170 } | 190 } |
171 | 191 |
172 // Verifies the delay for a converged filter is correctly identified. | 192 // Verifies the delay for a converged filter is correctly identified. |
173 TEST(AecState, ConvergedFilterDelay) { | 193 TEST(AecState, ConvergedFilterDelay) { |
174 constexpr int kFilterLength = 10; | 194 constexpr int kFilterLength = 10; |
175 AecState state(0.f); | 195 AecState state(0.f); |
176 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, | 196 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, |
177 std::vector<size_t>(1, 30)); | 197 std::vector<size_t>(1, 30)); |
178 std::array<float, kFftLengthBy2Plus1> E2_main; | 198 std::array<float, kFftLengthBy2Plus1> E2_main; |
179 std::array<float, kFftLengthBy2Plus1> Y2; | 199 std::array<float, kFftLengthBy2Plus1> Y2; |
180 std::array<float, kBlockSize> x; | 200 std::array<float, kBlockSize> x; |
181 EchoPathVariability echo_path_variability(false, false); | 201 EchoPathVariability echo_path_variability(false, false); |
| 202 std::array<float, kBlockSize> s; |
| 203 s.fill(100.f); |
182 x.fill(0.f); | 204 x.fill(0.f); |
183 | 205 |
184 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response( | 206 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response( |
185 kFilterLength); | 207 kFilterLength); |
186 | 208 |
| 209 std::array<float, kAdaptiveFilterTimeDomainLength> impulse_response; |
| 210 impulse_response.fill(0.f); |
| 211 |
187 // Verify that the filter delay for a converged filter is properly identified. | 212 // Verify that the filter delay for a converged filter is properly identified. |
188 for (int k = 0; k < kFilterLength; ++k) { | 213 for (int k = 0; k < kFilterLength; ++k) { |
189 for (auto& v : frequency_response) { | 214 for (auto& v : frequency_response) { |
190 v.fill(0.01f); | 215 v.fill(0.01f); |
191 } | 216 } |
192 frequency_response[k].fill(100.f); | 217 frequency_response[k].fill(100.f); |
193 frequency_response[k][0] = 0.f; | 218 frequency_response[k][0] = 0.f; |
194 state.HandleEchoPathChange(echo_path_variability); | 219 state.HandleEchoPathChange(echo_path_variability); |
195 state.Update(frequency_response, rtc::Optional<size_t>(), render_buffer, | 220 state.Update(frequency_response, impulse_response, rtc::Optional<size_t>(), |
196 E2_main, Y2, x, false); | 221 render_buffer, E2_main, Y2, x, s, false); |
197 EXPECT_TRUE(k == (kFilterLength - 1) || state.FilterDelay()); | 222 EXPECT_TRUE(k == (kFilterLength - 1) || state.FilterDelay()); |
198 if (k != (kFilterLength - 1)) { | 223 if (k != (kFilterLength - 1)) { |
199 EXPECT_EQ(k, state.FilterDelay()); | 224 EXPECT_EQ(k, state.FilterDelay()); |
200 } | 225 } |
201 } | 226 } |
202 } | 227 } |
203 | 228 |
204 // Verify that the externally reported delay is properly reported and converted. | 229 // Verify that the externally reported delay is properly reported and converted. |
205 TEST(AecState, ExternalDelay) { | 230 TEST(AecState, ExternalDelay) { |
206 AecState state(0.f); | 231 AecState state(0.f); |
207 std::array<float, kFftLengthBy2Plus1> E2_main; | 232 std::array<float, kFftLengthBy2Plus1> E2_main; |
208 std::array<float, kFftLengthBy2Plus1> E2_shadow; | 233 std::array<float, kFftLengthBy2Plus1> E2_shadow; |
209 std::array<float, kFftLengthBy2Plus1> Y2; | 234 std::array<float, kFftLengthBy2Plus1> Y2; |
210 std::array<float, kBlockSize> x; | 235 std::array<float, kBlockSize> x; |
| 236 std::array<float, kBlockSize> s; |
| 237 s.fill(100.f); |
211 E2_main.fill(0.f); | 238 E2_main.fill(0.f); |
212 E2_shadow.fill(0.f); | 239 E2_shadow.fill(0.f); |
213 Y2.fill(0.f); | 240 Y2.fill(0.f); |
214 x.fill(0.f); | 241 x.fill(0.f); |
215 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, | 242 RenderBuffer render_buffer(Aec3Optimization::kNone, 3, 30, |
216 std::vector<size_t>(1, 30)); | 243 std::vector<size_t>(1, 30)); |
217 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30); | 244 std::vector<std::array<float, kFftLengthBy2Plus1>> frequency_response(30); |
218 for (auto& v : frequency_response) { | 245 for (auto& v : frequency_response) { |
219 v.fill(0.01f); | 246 v.fill(0.01f); |
220 } | 247 } |
221 | 248 |
| 249 std::array<float, kAdaptiveFilterTimeDomainLength> impulse_response; |
| 250 impulse_response.fill(0.f); |
| 251 |
222 for (size_t k = 0; k < frequency_response.size() - 1; ++k) { | 252 for (size_t k = 0; k < frequency_response.size() - 1; ++k) { |
223 state.HandleEchoPathChange(EchoPathVariability(false, false)); | 253 state.HandleEchoPathChange(EchoPathVariability(false, false)); |
224 state.Update(frequency_response, rtc::Optional<size_t>(k * kBlockSize + 5), | 254 state.Update(frequency_response, impulse_response, |
225 render_buffer, E2_main, Y2, x, false); | 255 rtc::Optional<size_t>(k * kBlockSize + 5), render_buffer, |
| 256 E2_main, Y2, x, s, false); |
226 EXPECT_TRUE(state.ExternalDelay()); | 257 EXPECT_TRUE(state.ExternalDelay()); |
227 EXPECT_EQ(k, state.ExternalDelay()); | 258 EXPECT_EQ(k, state.ExternalDelay()); |
228 } | 259 } |
229 | 260 |
230 // Verify that the externally reported delay is properly unset when it is no | 261 // Verify that the externally reported delay is properly unset when it is no |
231 // longer present. | 262 // longer present. |
232 state.HandleEchoPathChange(EchoPathVariability(false, false)); | 263 state.HandleEchoPathChange(EchoPathVariability(false, false)); |
233 state.Update(frequency_response, rtc::Optional<size_t>(), render_buffer, | 264 state.Update(frequency_response, impulse_response, rtc::Optional<size_t>(), |
234 E2_main, Y2, x, false); | 265 render_buffer, E2_main, Y2, x, s, false); |
235 EXPECT_FALSE(state.ExternalDelay()); | 266 EXPECT_FALSE(state.ExternalDelay()); |
236 } | 267 } |
237 | 268 |
238 } // namespace webrtc | 269 } // namespace webrtc |
OLD | NEW |