OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2017 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 "webrtc/modules/audio_processing/aec3/correlator.h" | |
12 | |
13 #include <algorithm> | |
14 #include <sstream> | |
15 #include <string> | |
16 | |
17 #include "webrtc/modules/audio_processing/aec3/aec3_constants.h" | |
18 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" | |
19 #include "webrtc/modules/audio_processing/test/echo_canceller_test_tools.h" | |
20 #include "webrtc/test/gtest.h" | |
21 | |
22 namespace webrtc { | |
23 namespace { | |
24 | |
25 std::string ProduceDebugText(size_t delay) { | |
26 std::ostringstream ss; | |
27 ss << "Delay: " << delay; | |
28 return ss.str(); | |
29 } | |
30 | |
31 } // namespace | |
32 | |
33 // Verifies that the correlator produces proper lag estimates for artificially | |
34 // delayed signals. | |
35 TEST(Correlator, LagEstimation) { | |
36 Random random_generator(42U); | |
37 std::vector<float> render(kSubBlockSize, 0.f); | |
38 std::vector<float> capture(kSubBlockSize, 0.f); | |
39 ApmDataDumper data_dumper(0); | |
40 for (size_t delay_samples : {0, 64, 150, 200, 800, 1000}) { | |
41 SCOPED_TRACE(ProduceDebugText(delay_samples)); | |
42 DelayBuffer<float> signal_delay_buffer(delay_samples); | |
43 constexpr size_t kWindowSizeSubBlocks = 32; | |
44 constexpr size_t kAlignmentShiftSubBlocks = kWindowSizeSubBlocks * 3 / 4; | |
45 constexpr size_t kNumAlignmentShifts = 3; | |
46 Correlator correlator(&data_dumper, kWindowSizeSubBlocks, | |
47 kNumAlignmentShifts, kAlignmentShiftSubBlocks); | |
48 | |
49 // Analyze the correlation between render and capture. | |
50 for (size_t k = 0; k < (100 + delay_samples / kSubBlockSize); ++k) { | |
51 RandomizeSampleVector(&random_generator, render); | |
52 signal_delay_buffer.Delay(render, capture); | |
53 correlator.Update(render, capture); | |
54 } | |
55 | |
56 // Obtain the lag estimates. | |
57 rtc::ArrayView<const Correlator::LagEstimate> lag_estimates = | |
hlundin-webrtc
2017/02/01 08:30:01
auto
peah-webrtc
2017/02/02 14:04:46
Done.
| |
58 correlator.GetLagEstimates(); | |
59 EXPECT_EQ(kNumAlignmentShifts + 1, lag_estimates.size()); | |
hlundin-webrtc
2017/02/01 08:30:01
You are already checking this explicitly in a test
peah-webrtc
2017/02/02 14:04:46
Done.
| |
60 | |
61 // Find which lag estimate should be the most accurate. | |
62 rtc::Optional<size_t> expected_most_accurate_lag_estimate; | |
63 size_t alignment_shift_sub_blocks = 0; | |
64 for (size_t k = 0; k < kNumAlignmentShifts; ++k) { | |
65 if ((alignment_shift_sub_blocks + kWindowSizeSubBlocks / 2) * | |
66 kSubBlockSize > | |
67 delay_samples) { | |
68 expected_most_accurate_lag_estimate = rtc::Optional<size_t>(k); | |
69 break; | |
70 } | |
71 alignment_shift_sub_blocks += kAlignmentShiftSubBlocks; | |
72 } | |
73 RTC_DCHECK(expected_most_accurate_lag_estimate); | |
hlundin-webrtc
2017/02/01 08:30:01
ASSERT_TRUE
peah-webrtc
2017/02/02 14:04:46
Done.
| |
74 | |
75 // Verify that the expected most accurate lag estimate is the most accurate | |
76 // estimate. | |
77 for (size_t k = 0; k < kNumAlignmentShifts; ++k) { | |
78 if (k != static_cast<size_t>(*expected_most_accurate_lag_estimate)) { | |
hlundin-webrtc
2017/02/01 08:30:01
Why the cast?
peah-webrtc
2017/02/02 14:04:46
Done.
| |
79 EXPECT_GT(lag_estimates[*expected_most_accurate_lag_estimate].accuracy, | |
80 lag_estimates[k].accuracy); | |
81 } | |
82 } | |
83 | |
84 // Verify that all lag estimates are updated as expected for signals | |
85 // containing strong noise. | |
86 for (size_t k = 0; k < kNumAlignmentShifts; ++k) { | |
87 EXPECT_TRUE(lag_estimates[k].updated); | |
88 } | |
89 | |
90 // Verify that the expected most accurate lag estimate is reliable. | |
91 EXPECT_TRUE(lag_estimates[*expected_most_accurate_lag_estimate].reliable); | |
92 | |
93 // Verify that the expected most accurate lag estimate is correct. | |
94 EXPECT_EQ(delay_samples, | |
95 lag_estimates[*expected_most_accurate_lag_estimate].lag); | |
96 } | |
97 } | |
98 | |
99 // Verifies that the correlator does not produce reliable and accurate estimates | |
100 // for uncorrelated render and capture signals. | |
101 TEST(Correlator, LagNotUpdatedForLowLevelRender) { | |
102 Random random_generator(42U); | |
103 std::vector<float> render(kSubBlockSize, 0.f); | |
104 std::vector<float> capture(kSubBlockSize, 0.f); | |
105 ApmDataDumper data_dumper(0); | |
106 constexpr size_t kWindowSizeSubBlocks = 32; | |
107 constexpr size_t kAlignmentShiftSubBlocks = kWindowSizeSubBlocks * 3 / 4; | |
108 constexpr size_t kNumAlignmentShifts = 3; | |
109 Correlator correlator(&data_dumper, kWindowSizeSubBlocks, kNumAlignmentShifts, | |
110 kAlignmentShiftSubBlocks); | |
111 | |
112 // Analyze the correlation between render and capture. | |
113 for (size_t k = 0; k < 100; ++k) { | |
114 RandomizeSampleVector(&random_generator, render); | |
115 RandomizeSampleVector(&random_generator, capture); | |
116 correlator.Update(render, capture); | |
117 } | |
118 | |
119 // Obtain the lag estimates. | |
120 rtc::ArrayView<const Correlator::LagEstimate> lag_estimates = | |
121 correlator.GetLagEstimates(); | |
122 EXPECT_EQ(kNumAlignmentShifts + 1, lag_estimates.size()); | |
123 | |
124 // Verify that no lag estimates are reliable. | |
125 for (size_t k = 0; k < kNumAlignmentShifts; ++k) { | |
hlundin-webrtc
2017/02/01 08:30:01
for (auto le : lag_estimates) {
EXPECT_FALSE(le.
peah-webrtc
2017/02/02 14:04:46
Done.
aleloi
2017/02/02 16:33:11
That's not equivalent. lag_estimates has kNumAlign
peah-webrtc
2017/02/03 06:59:59
You are correct. I mixed this up. It is now correc
| |
126 EXPECT_FALSE(lag_estimates[k].reliable); | |
127 } | |
128 } | |
129 | |
130 // Verifies that the correlator does not produce updated lag estimates for | |
131 // render signals of low level. | |
132 TEST(Correlator, LagNotReliableForUncorrelatedRenderAndCapture) { | |
133 Random random_generator(42U); | |
134 std::vector<float> render(kSubBlockSize, 0.f); | |
135 std::vector<float> capture(kSubBlockSize, 0.f); | |
136 ApmDataDumper data_dumper(0); | |
137 constexpr size_t kWindowSizeSubBlocks = 32; | |
hlundin-webrtc
2017/02/01 08:30:01
These constexprs are the same for all tests. Consi
peah-webrtc
2017/02/02 14:04:46
Done.
| |
138 constexpr size_t kAlignmentShiftSubBlocks = kWindowSizeSubBlocks * 3 / 4; | |
139 constexpr size_t kNumAlignmentShifts = 3; | |
140 Correlator correlator(&data_dumper, kWindowSizeSubBlocks, kNumAlignmentShifts, | |
141 kAlignmentShiftSubBlocks); | |
142 | |
143 // Analyze the correlation between render and capture. | |
144 for (size_t k = 0; k < 100; ++k) { | |
145 RandomizeSampleVector(&random_generator, render); | |
146 for (auto& render_k : render) { | |
147 render_k *= 149.f / 32767.f; | |
148 } | |
149 std::copy(render.begin(), render.end(), capture.begin()); | |
150 correlator.Update(render, capture); | |
151 } | |
152 | |
153 // Obtain the lag estimates. | |
154 rtc::ArrayView<const Correlator::LagEstimate> lag_estimates = | |
155 correlator.GetLagEstimates(); | |
156 EXPECT_EQ(kNumAlignmentShifts + 1, lag_estimates.size()); | |
157 | |
158 // Verify that no lag estimates are updated. | |
159 for (size_t k = 0; k < kNumAlignmentShifts; ++k) { | |
hlundin-webrtc
2017/02/01 08:30:01
Consider range-based. Also, you can merge this and
peah-webrtc
2017/02/02 14:04:46
Done.
| |
160 EXPECT_FALSE(lag_estimates[k].updated); | |
161 } | |
162 | |
163 // Verify that no lag estimates are reliable. | |
164 for (size_t k = 0; k < kNumAlignmentShifts; ++k) { | |
165 EXPECT_FALSE(lag_estimates[k].reliable); | |
166 } | |
167 } | |
168 | |
169 // Verifies that the correct number of lag estimates are produced for a certain | |
170 // number of alignment shifts. | |
171 TEST(Correlator, NumberOfLagEstimates) { | |
172 ApmDataDumper data_dumper(0); | |
173 for (size_t num_alignment_shifts = 0; num_alignment_shifts < 10; | |
174 ++num_alignment_shifts) { | |
175 Correlator correlator(&data_dumper, 32, num_alignment_shifts, 1); | |
176 EXPECT_EQ(num_alignment_shifts + 1, correlator.GetLagEstimates().size()); | |
177 } | |
178 } | |
179 | |
180 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
181 | |
182 // Verifies the check for the render signal sub block size. | |
183 TEST(Correlator, WrongRenderSize) { | |
184 std::vector<float> render(kSubBlockSize - 1, 0.f); | |
185 std::vector<float> capture(kSubBlockSize, 0.f); | |
186 ApmDataDumper data_dumper(0); | |
187 Correlator correlator(&data_dumper, 1, 1, 1); | |
188 EXPECT_DEATH(correlator.Update(render, capture), ""); | |
189 } | |
190 | |
191 // Verifies the check for the capture signal sub block size. | |
192 TEST(Correlator, WrongCaptureSize) { | |
193 std::vector<float> render(kSubBlockSize, 0.f); | |
194 std::vector<float> capture(kSubBlockSize - 1, 0.f); | |
195 ApmDataDumper data_dumper(0); | |
196 Correlator correlator(&data_dumper, 1, 1, 1); | |
197 EXPECT_DEATH(correlator.Update(render, capture), ""); | |
198 } | |
199 | |
200 // Verifies the check for non-zero windows size. | |
201 TEST(Correlator, ZeroWindowSize) { | |
202 ApmDataDumper data_dumper(0); | |
203 EXPECT_DEATH(Correlator(&data_dumper, 0, 1, 1), ""); | |
204 } | |
205 | |
206 // Verifies the check for non-null data dumper. | |
207 TEST(Correlator, NullDataDumper) { | |
208 EXPECT_DEATH(Correlator(nullptr, 1, 1, 1), ""); | |
209 } | |
210 | |
211 #endif | |
212 | |
213 } // namespace webrtc | |
OLD | NEW |