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/render_delay_controller.h" | 11 #include "webrtc/modules/audio_processing/aec3/render_delay_controller.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <memory> | 14 #include <memory> |
15 #include <sstream> | 15 #include <sstream> |
16 #include <string> | 16 #include <string> |
17 #include <vector> | 17 #include <vector> |
18 | 18 |
19 #include "webrtc/base/random.h" | 19 #include "webrtc/base/random.h" |
20 #include "webrtc/modules/audio_processing/aec3/aec3_common.h" | 20 #include "webrtc/modules/audio_processing/aec3/aec3_common.h" |
| 21 #include "webrtc/modules/audio_processing/aec3/block_processor.h" |
| 22 #include "webrtc/modules/audio_processing/aec3/decimator_by_4.h" |
21 #include "webrtc/modules/audio_processing/aec3/render_delay_buffer.h" | 23 #include "webrtc/modules/audio_processing/aec3/render_delay_buffer.h" |
22 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" | 24 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" |
23 #include "webrtc/modules/audio_processing/test/echo_canceller_test_tools.h" | 25 #include "webrtc/modules/audio_processing/test/echo_canceller_test_tools.h" |
24 #include "webrtc/test/gtest.h" | 26 #include "webrtc/test/gtest.h" |
25 | 27 |
26 namespace webrtc { | 28 namespace webrtc { |
27 namespace { | 29 namespace { |
28 | 30 |
29 std::string ProduceDebugText(int sample_rate_hz) { | 31 std::string ProduceDebugText(int sample_rate_hz) { |
30 std::ostringstream ss; | 32 std::ostringstream ss; |
31 ss << "Sample rate: " << sample_rate_hz; | 33 ss << "Sample rate: " << sample_rate_hz; |
32 return ss.str(); | 34 return ss.str(); |
33 } | 35 } |
34 | 36 |
35 std::string ProduceDebugText(int sample_rate_hz, size_t delay) { | 37 std::string ProduceDebugText(int sample_rate_hz, size_t delay) { |
36 std::ostringstream ss; | 38 std::ostringstream ss; |
37 ss << ProduceDebugText(sample_rate_hz) << ", Delay: " << delay; | 39 ss << ProduceDebugText(sample_rate_hz) << ", Delay: " << delay; |
38 return ss.str(); | 40 return ss.str(); |
39 } | 41 } |
40 | 42 |
41 std::string ProduceDebugText(int sample_rate_hz, | |
42 size_t delay, | |
43 size_t max_jitter) { | |
44 std::ostringstream ss; | |
45 ss << ProduceDebugText(sample_rate_hz, delay) | |
46 << ", Max Api call jitter: " << max_jitter; | |
47 return ss.str(); | |
48 } | |
49 | |
50 constexpr size_t kMaxApiCallJitter = 30; | |
51 | |
52 } // namespace | 43 } // namespace |
53 | 44 |
54 // Verifies the output of GetDelay when there are no AnalyzeRender calls. | 45 // Verifies the output of GetDelay when there are no AnalyzeRender calls. |
55 TEST(RenderDelayController, NoRenderSignal) { | 46 TEST(RenderDelayController, NoRenderSignal) { |
56 std::vector<float> block(kBlockSize, 0.f); | 47 std::vector<float> block(kBlockSize, 0.f); |
57 for (auto rate : {8000, 16000, 32000, 48000}) { | 48 for (auto rate : {8000, 16000, 32000, 48000}) { |
58 SCOPED_TRACE(ProduceDebugText(rate)); | 49 SCOPED_TRACE(ProduceDebugText(rate)); |
59 std::unique_ptr<RenderDelayBuffer> delay_buffer(RenderDelayBuffer::Create( | 50 std::unique_ptr<RenderDelayBuffer> delay_buffer( |
60 250, NumBandsForRate(rate), kMaxApiCallJitter)); | 51 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
61 std::unique_ptr<RenderDelayController> delay_controller( | 52 std::unique_ptr<RenderDelayController> delay_controller( |
62 RenderDelayController::Create(rate, *delay_buffer)); | 53 RenderDelayController::Create(rate)); |
63 for (size_t k = 0; k < 100; ++k) { | 54 for (size_t k = 0; k < 100; ++k) { |
64 EXPECT_EQ(0u, delay_controller->GetDelay(block)); | 55 EXPECT_EQ(0u, delay_controller->GetDelay( |
| 56 delay_buffer->GetDownsampledRenderBuffer(), block)); |
65 } | 57 } |
66 } | 58 } |
67 } | 59 } |
68 | 60 |
69 // Verifies the behavior when there are too many AnalyzeRender calls. | |
70 TEST(RenderDelayController, RenderOverflow) { | |
71 std::vector<float> block(kBlockSize, 0.f); | |
72 for (auto rate : {8000, 16000, 32000, 48000}) { | |
73 SCOPED_TRACE(ProduceDebugText(rate)); | |
74 std::unique_ptr<RenderDelayBuffer> delay_buffer(RenderDelayBuffer::Create( | |
75 250, NumBandsForRate(rate), kMaxApiCallJitter)); | |
76 std::unique_ptr<RenderDelayController> delay_controller( | |
77 RenderDelayController::Create(rate, *delay_buffer)); | |
78 for (size_t k = 0; k < kMaxApiCallJitter; ++k) { | |
79 EXPECT_TRUE(delay_controller->AnalyzeRender(block)); | |
80 } | |
81 EXPECT_FALSE(delay_controller->AnalyzeRender(block)); | |
82 delay_controller->GetDelay(block); | |
83 EXPECT_TRUE(delay_controller->AnalyzeRender(block)); | |
84 } | |
85 } | |
86 | |
87 // Verifies the basic API call sequence. | 61 // Verifies the basic API call sequence. |
88 TEST(RenderDelayController, BasicApiCalls) { | 62 TEST(RenderDelayController, BasicApiCalls) { |
89 std::vector<float> render_block(kBlockSize, 0.f); | |
90 std::vector<float> capture_block(kBlockSize, 0.f); | 63 std::vector<float> capture_block(kBlockSize, 0.f); |
91 size_t delay_blocks = 0; | 64 size_t delay_blocks = 0; |
92 for (auto rate : {8000, 16000, 32000, 48000}) { | 65 for (auto rate : {8000, 16000, 32000, 48000}) { |
| 66 std::vector<std::vector<float>> render_block( |
| 67 NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f)); |
93 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | 68 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( |
94 RenderDelayBuffer::Create(50, NumBandsForRate(rate), | 69 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
95 kMaxApiCallJitter)); | |
96 std::unique_ptr<RenderDelayController> delay_controller( | 70 std::unique_ptr<RenderDelayController> delay_controller( |
97 RenderDelayController::Create(rate, *render_delay_buffer)); | 71 RenderDelayController::Create(rate)); |
98 for (size_t k = 0; k < 10; ++k) { | 72 for (size_t k = 0; k < 10; ++k) { |
99 EXPECT_TRUE(delay_controller->AnalyzeRender(render_block)); | 73 render_delay_buffer->Insert(&render_block); |
100 delay_blocks = delay_controller->GetDelay(capture_block); | 74 render_delay_buffer->UpdateBuffers(); |
| 75 delay_blocks = delay_controller->GetDelay( |
| 76 render_delay_buffer->GetDownsampledRenderBuffer(), capture_block); |
101 } | 77 } |
102 EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples()); | 78 EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples()); |
103 EXPECT_EQ(0u, delay_blocks); | 79 EXPECT_EQ(0u, delay_blocks); |
104 } | 80 } |
105 } | 81 } |
106 | 82 |
107 // Verifies that the RenderDelayController is able to align the signals for | 83 // Verifies that the RenderDelayController is able to align the signals for |
108 // simple timeshifts between the signals. | 84 // simple timeshifts between the signals. |
109 TEST(RenderDelayController, Alignment) { | 85 TEST(RenderDelayController, Alignment) { |
110 Random random_generator(42U); | 86 Random random_generator(42U); |
111 std::vector<float> render_block(kBlockSize, 0.f); | |
112 std::vector<float> capture_block(kBlockSize, 0.f); | 87 std::vector<float> capture_block(kBlockSize, 0.f); |
113 size_t delay_blocks = 0; | 88 size_t delay_blocks = 0; |
114 for (auto rate : {8000, 16000, 32000, 48000}) { | 89 for (auto rate : {8000, 16000, 32000, 48000}) { |
| 90 std::vector<std::vector<float>> render_block( |
| 91 NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f)); |
| 92 |
115 for (size_t delay_samples : {15, 50, 150, 200, 800, 4000}) { | 93 for (size_t delay_samples : {15, 50, 150, 200, 800, 4000}) { |
116 SCOPED_TRACE(ProduceDebugText(rate, delay_samples)); | 94 SCOPED_TRACE(ProduceDebugText(rate, delay_samples)); |
117 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | 95 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( |
118 RenderDelayBuffer::Create(250, NumBandsForRate(rate), | 96 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
119 kMaxApiCallJitter)); | |
120 std::unique_ptr<RenderDelayController> delay_controller( | 97 std::unique_ptr<RenderDelayController> delay_controller( |
121 RenderDelayController::Create(rate, *render_delay_buffer)); | 98 RenderDelayController::Create(rate)); |
122 DelayBuffer<float> signal_delay_buffer(delay_samples); | 99 DelayBuffer<float> signal_delay_buffer(delay_samples); |
123 for (size_t k = 0; k < (400 + delay_samples / kBlockSize); ++k) { | 100 for (size_t k = 0; k < (400 + delay_samples / kBlockSize); ++k) { |
124 RandomizeSampleVector(&random_generator, render_block); | 101 RandomizeSampleVector(&random_generator, render_block[0]); |
125 signal_delay_buffer.Delay(render_block, capture_block); | 102 signal_delay_buffer.Delay(render_block[0], capture_block); |
126 EXPECT_TRUE(delay_controller->AnalyzeRender(render_block)); | 103 render_delay_buffer->Insert(&render_block); |
127 delay_blocks = delay_controller->GetDelay(capture_block); | 104 render_delay_buffer->UpdateBuffers(); |
| 105 delay_blocks = delay_controller->GetDelay( |
| 106 render_delay_buffer->GetDownsampledRenderBuffer(), capture_block); |
128 } | 107 } |
129 | 108 |
130 constexpr int kDelayHeadroomBlocks = 1; | 109 constexpr int kDelayHeadroomBlocks = 1; |
131 size_t expected_delay_blocks = | 110 size_t expected_delay_blocks = |
132 std::max(0, static_cast<int>(delay_samples / kBlockSize) - | 111 std::max(0, static_cast<int>(delay_samples / kBlockSize) - |
133 kDelayHeadroomBlocks); | 112 kDelayHeadroomBlocks); |
134 if (expected_delay_blocks < 2) { | 113 if (expected_delay_blocks < 2) { |
135 expected_delay_blocks = 0; | 114 expected_delay_blocks = 0; |
136 } | 115 } |
137 | 116 |
138 EXPECT_EQ(expected_delay_blocks, delay_blocks); | 117 EXPECT_EQ(expected_delay_blocks, delay_blocks); |
139 | 118 |
140 const rtc::Optional<size_t> headroom_samples = | 119 const rtc::Optional<size_t> headroom_samples = |
141 delay_controller->AlignmentHeadroomSamples(); | 120 delay_controller->AlignmentHeadroomSamples(); |
142 ASSERT_TRUE(headroom_samples); | 121 ASSERT_TRUE(headroom_samples); |
143 EXPECT_NEAR(delay_samples - delay_blocks * kBlockSize, *headroom_samples, | 122 EXPECT_NEAR(delay_samples - delay_blocks * kBlockSize, *headroom_samples, |
144 4); | 123 4); |
145 } | 124 } |
146 } | 125 } |
147 } | 126 } |
148 | 127 |
149 // Verifies that the RenderDelayController is able to align the signals for | 128 // Verifies that the RenderDelayController is able to align the signals for |
150 // simple timeshifts between the signals when there is jitter in the API calls. | 129 // simple timeshifts between the signals when there is jitter in the API calls. |
151 TEST(RenderDelayController, AlignmentWithJitter) { | 130 TEST(RenderDelayController, AlignmentWithJitter) { |
152 Random random_generator(42U); | 131 Random random_generator(42U); |
153 std::vector<float> render_block(kBlockSize, 0.f); | |
154 std::vector<float> capture_block(kBlockSize, 0.f); | 132 std::vector<float> capture_block(kBlockSize, 0.f); |
155 for (auto rate : {8000, 16000, 32000, 48000}) { | 133 for (auto rate : {8000, 16000, 32000, 48000}) { |
156 for (size_t delay_samples : {15, 50, 800}) { | 134 std::vector<std::vector<float>> render_block( |
157 for (size_t max_jitter : {1, 9, 20}) { | 135 NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f)); |
158 size_t delay_blocks = 0; | 136 for (size_t delay_samples : {15, 50, 300, 800}) { |
159 SCOPED_TRACE(ProduceDebugText(rate, delay_samples, max_jitter)); | 137 size_t delay_blocks = 0; |
160 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | 138 SCOPED_TRACE(ProduceDebugText(rate, delay_samples)); |
161 RenderDelayBuffer::Create(250, NumBandsForRate(rate), max_jitter)); | 139 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( |
162 std::unique_ptr<RenderDelayController> delay_controller( | 140 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
163 RenderDelayController::Create(rate, *render_delay_buffer)); | 141 std::unique_ptr<RenderDelayController> delay_controller( |
164 DelayBuffer<float> signal_delay_buffer(delay_samples); | 142 RenderDelayController::Create(rate)); |
165 for (size_t j = 0; | 143 DelayBuffer<float> signal_delay_buffer(delay_samples); |
166 j < (300 + delay_samples / kBlockSize) / max_jitter + 1; ++j) { | 144 for (size_t j = 0; |
167 std::vector<std::vector<float>> capture_block_buffer; | 145 j < |
168 for (size_t k = 0; k < max_jitter; ++k) { | 146 (1000 + delay_samples / kBlockSize) / kMaxApiCallsJitterBlocks + 1; |
169 RandomizeSampleVector(&random_generator, render_block); | 147 ++j) { |
170 signal_delay_buffer.Delay(render_block, capture_block); | 148 std::vector<std::vector<float>> capture_block_buffer; |
171 capture_block_buffer.push_back(capture_block); | 149 for (size_t k = 0; k < (kMaxApiCallsJitterBlocks - 1); ++k) { |
172 EXPECT_TRUE(delay_controller->AnalyzeRender(render_block)); | 150 RandomizeSampleVector(&random_generator, render_block[0]); |
173 } | 151 signal_delay_buffer.Delay(render_block[0], capture_block); |
174 for (size_t k = 0; k < max_jitter; ++k) { | 152 capture_block_buffer.push_back(capture_block); |
175 delay_blocks = delay_controller->GetDelay(capture_block_buffer[k]); | 153 render_delay_buffer->Insert(&render_block); |
176 } | |
177 } | 154 } |
| 155 for (size_t k = 0; k < (kMaxApiCallsJitterBlocks - 1); ++k) { |
| 156 render_delay_buffer->UpdateBuffers(); |
| 157 delay_blocks = delay_controller->GetDelay( |
| 158 render_delay_buffer->GetDownsampledRenderBuffer(), |
| 159 capture_block_buffer[k]); |
| 160 } |
| 161 } |
178 | 162 |
179 constexpr int kDelayHeadroomBlocks = 1; | 163 constexpr int kDelayHeadroomBlocks = 1; |
180 size_t expected_delay_blocks = | 164 size_t expected_delay_blocks = |
181 std::max(0, static_cast<int>(delay_samples / kBlockSize) - | 165 std::max(0, static_cast<int>(delay_samples / kBlockSize) - |
182 kDelayHeadroomBlocks); | 166 kDelayHeadroomBlocks); |
183 if (expected_delay_blocks < 2) { | 167 if (expected_delay_blocks < 2) { |
184 expected_delay_blocks = 0; | 168 expected_delay_blocks = 0; |
185 } | 169 } |
186 | 170 |
187 EXPECT_EQ(expected_delay_blocks, delay_blocks); | 171 EXPECT_EQ(expected_delay_blocks, delay_blocks); |
188 | 172 |
189 const rtc::Optional<size_t> headroom_samples = | 173 const rtc::Optional<size_t> headroom_samples = |
190 delay_controller->AlignmentHeadroomSamples(); | 174 delay_controller->AlignmentHeadroomSamples(); |
191 ASSERT_TRUE(headroom_samples); | 175 ASSERT_TRUE(headroom_samples); |
192 EXPECT_NEAR(delay_samples - delay_blocks * kBlockSize, | 176 EXPECT_NEAR(delay_samples - delay_blocks * kBlockSize, *headroom_samples, |
193 *headroom_samples, 4); | 177 4); |
194 } | 178 } |
195 } | 179 } |
196 } | 180 } |
197 } | |
198 | 181 |
199 // Verifies the initial value for the AlignmentHeadroomSamples. | 182 // Verifies the initial value for the AlignmentHeadroomSamples. |
200 TEST(RenderDelayController, InitialHeadroom) { | 183 TEST(RenderDelayController, InitialHeadroom) { |
201 std::vector<float> render_block(kBlockSize, 0.f); | 184 std::vector<float> render_block(kBlockSize, 0.f); |
202 std::vector<float> capture_block(kBlockSize, 0.f); | 185 std::vector<float> capture_block(kBlockSize, 0.f); |
203 for (auto rate : {8000, 16000, 32000, 48000}) { | 186 for (auto rate : {8000, 16000, 32000, 48000}) { |
204 SCOPED_TRACE(ProduceDebugText(rate)); | 187 SCOPED_TRACE(ProduceDebugText(rate)); |
205 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | 188 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( |
206 RenderDelayBuffer::Create(250, NumBandsForRate(rate), | 189 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
207 kMaxApiCallJitter)); | |
208 std::unique_ptr<RenderDelayController> delay_controller( | 190 std::unique_ptr<RenderDelayController> delay_controller( |
209 RenderDelayController::Create(rate, *render_delay_buffer)); | 191 RenderDelayController::Create(rate)); |
210 EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples()); | 192 EXPECT_FALSE(delay_controller->AlignmentHeadroomSamples()); |
211 } | 193 } |
212 } | 194 } |
213 | 195 |
214 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 196 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
215 | 197 |
216 // Verifies the check for the capture signal block size. | 198 // Verifies the check for the capture signal block size. |
217 TEST(RenderDelayController, WrongCaptureSize) { | 199 TEST(RenderDelayController, WrongCaptureSize) { |
218 std::vector<float> block(kBlockSize - 1, 0.f); | 200 std::vector<float> block(kBlockSize - 1, 0.f); |
219 for (auto rate : {8000, 16000, 32000, 48000}) { | 201 for (auto rate : {8000, 16000, 32000, 48000}) { |
220 SCOPED_TRACE(ProduceDebugText(rate)); | 202 SCOPED_TRACE(ProduceDebugText(rate)); |
221 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | 203 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( |
222 RenderDelayBuffer::Create(250, NumBandsForRate(rate), | 204 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
223 kMaxApiCallJitter)); | 205 EXPECT_DEATH( |
224 EXPECT_DEATH(std::unique_ptr<RenderDelayController>( | 206 std::unique_ptr<RenderDelayController>( |
225 RenderDelayController::Create(rate, *render_delay_buffer)) | 207 RenderDelayController::Create(rate)) |
226 ->GetDelay(block), | 208 ->GetDelay(render_delay_buffer->GetDownsampledRenderBuffer(), |
227 ""); | 209 block), |
| 210 ""); |
228 } | 211 } |
229 } | 212 } |
230 | 213 |
231 // Verifies the check for the render signal block size. | |
232 // TODO(peah): Re-enable the test once the issue with memory leaks during DEATH | |
233 // tests on test bots has been fixed. | |
234 TEST(RenderDelayController, DISABLED_WrongRenderSize) { | |
235 std::vector<float> block(kBlockSize - 1, 0.f); | |
236 for (auto rate : {8000, 16000, 32000, 48000}) { | |
237 SCOPED_TRACE(ProduceDebugText(rate)); | |
238 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | |
239 RenderDelayBuffer::Create(250, NumBandsForRate(rate), | |
240 kMaxApiCallJitter)); | |
241 EXPECT_DEATH(std::unique_ptr<RenderDelayController>( | |
242 RenderDelayController::Create(rate, *render_delay_buffer)) | |
243 ->AnalyzeRender(block), | |
244 ""); | |
245 } | |
246 } | |
247 | |
248 // Verifies the check for correct sample rate. | 214 // Verifies the check for correct sample rate. |
249 TEST(RenderDelayController, WrongSampleRate) { | 215 TEST(RenderDelayController, WrongSampleRate) { |
250 for (auto rate : {-1, 0, 8001, 16001}) { | 216 for (auto rate : {-1, 0, 8001, 16001}) { |
251 SCOPED_TRACE(ProduceDebugText(rate)); | 217 SCOPED_TRACE(ProduceDebugText(rate)); |
252 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( | 218 std::unique_ptr<RenderDelayBuffer> render_delay_buffer( |
253 RenderDelayBuffer::Create(10, NumBandsForRate(rate), | 219 RenderDelayBuffer::Create(NumBandsForRate(rate))); |
254 kMaxApiCallJitter)); | |
255 EXPECT_DEATH(std::unique_ptr<RenderDelayController>( | 220 EXPECT_DEATH(std::unique_ptr<RenderDelayController>( |
256 RenderDelayController::Create(rate, *render_delay_buffer)), | 221 RenderDelayController::Create(rate)), |
257 ""); | 222 ""); |
258 } | 223 } |
259 } | 224 } |
260 | 225 |
261 #endif | 226 #endif |
262 | 227 |
263 } // namespace webrtc | 228 } // namespace webrtc |
OLD | NEW |