OLD | NEW |
| (Empty) |
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 #include <vector> | |
11 | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "webrtc/base/array_view.h" | |
14 #include "webrtc/modules/audio_processing/audio_buffer.h" | |
15 #include "webrtc/modules/audio_processing/gain_control_impl.h" | |
16 #include "webrtc/modules/audio_processing/test/audio_buffer_tools.h" | |
17 #include "webrtc/modules/audio_processing/test/bitexactness_tools.h" | |
18 | |
19 namespace webrtc { | |
20 namespace { | |
21 | |
22 const int kNumFramesToProcess = 1000; | |
23 | |
24 void ProcessOneFrame(int sample_rate_hz, | |
25 AudioBuffer* render_audio_buffer, | |
26 AudioBuffer* capture_audio_buffer, | |
27 GainControlImpl* gain_controller) { | |
28 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) { | |
29 render_audio_buffer->SplitIntoFrequencyBands(); | |
30 capture_audio_buffer->SplitIntoFrequencyBands(); | |
31 } | |
32 | |
33 gain_controller->ProcessRenderAudio(render_audio_buffer); | |
34 gain_controller->AnalyzeCaptureAudio(capture_audio_buffer); | |
35 gain_controller->ProcessCaptureAudio(capture_audio_buffer, false); | |
36 | |
37 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) { | |
38 capture_audio_buffer->MergeFrequencyBands(); | |
39 } | |
40 } | |
41 | |
42 void SetupComponent(int sample_rate_hz, | |
43 GainControl::Mode mode, | |
44 int target_level_dbfs, | |
45 int stream_analog_level, | |
46 int compression_gain_db, | |
47 bool enable_limiter, | |
48 int analog_level_min, | |
49 int analog_level_max, | |
50 GainControlImpl* gain_controller) { | |
51 gain_controller->Initialize(1, sample_rate_hz); | |
52 GainControl* gc = static_cast<GainControl*>(gain_controller); | |
53 gc->Enable(true); | |
54 gc->set_mode(mode); | |
55 gc->set_stream_analog_level(stream_analog_level); | |
56 gc->set_target_level_dbfs(target_level_dbfs); | |
57 gc->set_compression_gain_db(compression_gain_db); | |
58 gc->enable_limiter(enable_limiter); | |
59 gc->set_analog_level_limits(analog_level_min, analog_level_max); | |
60 } | |
61 | |
62 void RunBitExactnessTest(int sample_rate_hz, | |
63 size_t num_channels, | |
64 GainControl::Mode mode, | |
65 int target_level_dbfs, | |
66 int stream_analog_level, | |
67 int compression_gain_db, | |
68 bool enable_limiter, | |
69 int analog_level_min, | |
70 int analog_level_max, | |
71 int achieved_stream_analog_level_reference, | |
72 rtc::ArrayView<const float> output_reference) { | |
73 rtc::CriticalSection crit_render; | |
74 rtc::CriticalSection crit_capture; | |
75 GainControlImpl gain_controller(&crit_render, &crit_capture); | |
76 SetupComponent(sample_rate_hz, mode, target_level_dbfs, stream_analog_level, | |
77 compression_gain_db, enable_limiter, analog_level_min, | |
78 analog_level_max, &gain_controller); | |
79 | |
80 const int samples_per_channel = rtc::CheckedDivExact(sample_rate_hz, 100); | |
81 const StreamConfig render_config(sample_rate_hz, num_channels, false); | |
82 AudioBuffer render_buffer( | |
83 render_config.num_frames(), render_config.num_channels(), | |
84 render_config.num_frames(), 1, render_config.num_frames()); | |
85 test::InputAudioFile render_file( | |
86 test::GetApmRenderTestVectorFileName(sample_rate_hz)); | |
87 std::vector<float> render_input(samples_per_channel * num_channels); | |
88 | |
89 const StreamConfig capture_config(sample_rate_hz, num_channels, false); | |
90 AudioBuffer capture_buffer( | |
91 capture_config.num_frames(), capture_config.num_channels(), | |
92 capture_config.num_frames(), 1, capture_config.num_frames()); | |
93 test::InputAudioFile capture_file( | |
94 test::GetApmCaptureTestVectorFileName(sample_rate_hz)); | |
95 std::vector<float> capture_input(samples_per_channel * num_channels); | |
96 | |
97 for (int frame_no = 0; frame_no < kNumFramesToProcess; ++frame_no) { | |
98 ReadFloatSamplesFromStereoFile(samples_per_channel, num_channels, | |
99 &render_file, render_input); | |
100 ReadFloatSamplesFromStereoFile(samples_per_channel, num_channels, | |
101 &capture_file, capture_input); | |
102 | |
103 test::CopyVectorToAudioBuffer(render_config, render_input, &render_buffer); | |
104 test::CopyVectorToAudioBuffer(capture_config, capture_input, | |
105 &capture_buffer); | |
106 | |
107 ProcessOneFrame(sample_rate_hz, &render_buffer, &capture_buffer, | |
108 &gain_controller); | |
109 } | |
110 | |
111 // Extract and verify the test results. | |
112 std::vector<float> capture_output; | |
113 test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer, | |
114 &capture_output); | |
115 | |
116 EXPECT_EQ(achieved_stream_analog_level_reference, | |
117 gain_controller.stream_analog_level()); | |
118 | |
119 // Compare the output with the reference. Only the first values of the output | |
120 // from last frame processed are compared in order not having to specify all | |
121 // preceeding frames as testvectors. As the algorithm being tested has a | |
122 // memory, testing only the last frame implicitly also tests the preceeding | |
123 // frames. | |
124 const float kTolerance = 1.0f / 32768.0f; | |
125 EXPECT_TRUE(test::BitExactFrame( | |
126 capture_config.num_frames(), capture_config.num_channels(), | |
127 output_reference, capture_output, kTolerance)); | |
128 } | |
129 | |
130 } // namespace | |
131 | |
132 TEST(GainControlBitExactnessTest, | |
133 Mono8kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) { | |
134 const int kStreamAnalogLevelReference = 50; | |
135 const float kOutputReference[] = {-0.004578f, -0.003998f, -0.002991f}; | |
136 RunBitExactnessTest(8000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 50, 5, | |
137 true, 0, 100, kStreamAnalogLevelReference, | |
138 kOutputReference); | |
139 } | |
140 | |
141 TEST(GainControlBitExactnessTest, | |
142 Mono16kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) { | |
143 const int kStreamAnalogLevelReference = 50; | |
144 const float kOutputReference[] = {-0.004303f, -0.004150f, -0.004089f}; | |
145 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 50, 5, | |
146 true, 0, 100, kStreamAnalogLevelReference, | |
147 kOutputReference); | |
148 } | |
149 | |
150 TEST(GainControlBitExactnessTest, | |
151 Stereo16kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) { | |
152 const int kStreamAnalogLevelReference = 50; | |
153 const float kOutputReference[] = {-0.010254f, -0.004761f, -0.009918f, | |
154 -0.010254f, -0.004761f, -0.009918f}; | |
155 RunBitExactnessTest(16000, 2, GainControl::Mode::kAdaptiveAnalog, 10, 50, 5, | |
156 true, 0, 100, kStreamAnalogLevelReference, | |
157 kOutputReference); | |
158 } | |
159 | |
160 TEST(GainControlBitExactnessTest, | |
161 Mono32kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) { | |
162 const int kStreamAnalogLevelReference = 50; | |
163 const float kOutputReference[] = {-0.005554f, -0.005066f, -0.004242f}; | |
164 RunBitExactnessTest(32000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 50, 5, | |
165 true, 0, 100, kStreamAnalogLevelReference, | |
166 kOutputReference); | |
167 } | |
168 | |
169 TEST(GainControlBitExactnessTest, | |
170 Mono48kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) { | |
171 const int kStreamAnalogLevelReference = 50; | |
172 const float kOutputReference[] = {-0.005554f, -0.005066f, -0.004242f}; | |
173 RunBitExactnessTest(32000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 50, 5, | |
174 true, 0, 100, kStreamAnalogLevelReference, | |
175 kOutputReference); | |
176 } | |
177 | |
178 TEST(GainControlBitExactnessTest, | |
179 Mono8kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
180 const int kStreamAnalogLevelReference = 50; | |
181 const float kOutputReference[] = {-0.014221f, -0.012421f, -0.009308f}; | |
182 RunBitExactnessTest(8000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5, | |
183 true, 0, 100, kStreamAnalogLevelReference, | |
184 kOutputReference); | |
185 } | |
186 | |
187 TEST(GainControlBitExactnessTest, | |
188 Mono16kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
189 const int kStreamAnalogLevelReference = 50; | |
190 const float kOutputReference[] = {-0.014923f, -0.014404f, -0.014191f}; | |
191 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5, | |
192 true, 0, 100, kStreamAnalogLevelReference, | |
193 kOutputReference); | |
194 } | |
195 | |
196 TEST(GainControlBitExactnessTest, | |
197 Stereo16kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
198 const int kStreamAnalogLevelReference = 50; | |
199 const float kOutputReference[] = {-0.009796f, -0.004547f, -0.009460f, | |
200 -0.009796f, -0.004547f, -0.009460f}; | |
201 RunBitExactnessTest(16000, 2, GainControl::Mode::kAdaptiveDigital, 10, 50, 5, | |
202 true, 0, 100, kStreamAnalogLevelReference, | |
203 kOutputReference); | |
204 } | |
205 | |
206 TEST(GainControlBitExactnessTest, | |
207 Mono32kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
208 const int kStreamAnalogLevelReference = 50; | |
209 const float kOutputReference[] = {-0.019287f, -0.017578f, -0.014709f}; | |
210 RunBitExactnessTest(32000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5, | |
211 true, 0, 100, kStreamAnalogLevelReference, | |
212 kOutputReference); | |
213 } | |
214 | |
215 TEST(GainControlBitExactnessTest, | |
216 Mono48kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
217 const int kStreamAnalogLevelReference = 50; | |
218 const float kOutputReference[] = {-0.019287f, -0.017578f, -0.014709f}; | |
219 RunBitExactnessTest(32000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5, | |
220 true, 0, 100, kStreamAnalogLevelReference, | |
221 kOutputReference); | |
222 } | |
223 | |
224 TEST(GainControlBitExactnessTest, | |
225 Mono8kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
226 const int kStreamAnalogLevelReference = 50; | |
227 const float kOutputReference[] = {-0.008209f, -0.007172f, -0.005371f}; | |
228 RunBitExactnessTest(8000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5, | |
229 true, 0, 100, kStreamAnalogLevelReference, | |
230 kOutputReference); | |
231 } | |
232 | |
233 TEST(GainControlBitExactnessTest, | |
234 Mono16kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
235 const int kStreamAnalogLevelReference = 50; | |
236 const float kOutputReference[] = {-0.007721f, -0.007446f, -0.007355f}; | |
237 RunBitExactnessTest(16000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5, | |
238 true, 0, 100, kStreamAnalogLevelReference, | |
239 kOutputReference); | |
240 } | |
241 | |
242 TEST(GainControlBitExactnessTest, | |
243 Stereo16kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
244 const int kStreamAnalogLevelReference = 50; | |
245 const float kOutputReference[] = {-0.018402f, -0.008545f, -0.017792f, | |
246 -0.018402f, -0.008545f, -0.017792f}; | |
247 RunBitExactnessTest(16000, 2, GainControl::Mode::kFixedDigital, 10, 50, 5, | |
248 true, 0, 100, kStreamAnalogLevelReference, | |
249 kOutputReference); | |
250 } | |
251 | |
252 TEST(GainControlBitExactnessTest, | |
253 Mono32kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
254 const int kStreamAnalogLevelReference = 50; | |
255 const float kOutputReference[] = {-0.009979f, -0.009064f, -0.007629f}; | |
256 RunBitExactnessTest(32000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5, | |
257 true, 0, 100, kStreamAnalogLevelReference, | |
258 kOutputReference); | |
259 } | |
260 | |
261 TEST(GainControlBitExactnessTest, | |
262 Mono48kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) { | |
263 const int kStreamAnalogLevelReference = 50; | |
264 const float kOutputReference[] = {-0.009979f, -0.009064f, -0.007629f}; | |
265 RunBitExactnessTest(32000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5, | |
266 true, 0, 100, kStreamAnalogLevelReference, | |
267 kOutputReference); | |
268 } | |
269 | |
270 TEST(GainControlBitExactnessTest, | |
271 Mono16kHz_AdaptiveAnalog_Tl10_SL10_CG5_Lim_AL0_100) { | |
272 const int kStreamAnalogLevelReference = 12; | |
273 const float kOutputReference[] = {-0.004303f, -0.004150f, -0.004089f}; | |
274 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 10, 5, | |
275 true, 0, 100, kStreamAnalogLevelReference, | |
276 kOutputReference); | |
277 } | |
278 | |
279 TEST(GainControlBitExactnessTest, | |
280 Mono16kHz_AdaptiveAnalog_Tl10_SL100_CG5_Lim_AL70_80) { | |
281 const int kStreamAnalogLevelReference = 100; | |
282 const float kOutputReference[] = {-0.004303f, -0.004150f, -0.004089f}; | |
283 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 100, 5, | |
284 true, 70, 80, kStreamAnalogLevelReference, | |
285 kOutputReference); | |
286 } | |
287 | |
288 TEST(GainControlBitExactnessTest, | |
289 Mono16kHz_AdaptiveDigital_Tl10_SL100_CG5_NoLim_AL0_100) { | |
290 const int kStreamAnalogLevelReference = 100; | |
291 const float kOutputReference[] = {-0.014923f, -0.014404f, -0.014191f}; | |
292 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveDigital, 10, 100, 5, | |
293 false, 0, 100, kStreamAnalogLevelReference, | |
294 kOutputReference); | |
295 } | |
296 | |
297 TEST(GainControlBitExactnessTest, | |
298 Mono16kHz_AdaptiveDigital_Tl40_SL100_CG5_Lim_AL0_100) { | |
299 const int kStreamAnalogLevelReference = 100; | |
300 const float kOutputReference[] = {-0.020721f, -0.019989f, -0.019714f}; | |
301 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveDigital, 40, 100, 5, | |
302 true, 0, 100, kStreamAnalogLevelReference, | |
303 kOutputReference); | |
304 } | |
305 | |
306 TEST(GainControlBitExactnessTest, | |
307 Mono16kHz_AdaptiveDigital_Tl10_SL100_CG30_Lim_AL0_100) { | |
308 const int kStreamAnalogLevelReference = 100; | |
309 const float kOutputReference[] = {-0.020416f, -0.019714f, -0.019409f}; | |
310 RunBitExactnessTest(16000, 1, GainControl::Mode::kAdaptiveDigital, 10, 100, | |
311 30, true, 0, 100, kStreamAnalogLevelReference, | |
312 kOutputReference); | |
313 } | |
314 | |
315 } // namespace webrtc | |
OLD | NEW |