OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2015 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/audio_processing_impl.h" | |
12 | |
13 #include <algorithm> | |
14 #include <vector> | |
15 | |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 #include "webrtc/base/criticalsection.h" | |
19 #include "webrtc/config.h" | |
20 #include "webrtc/modules/audio_processing/test/test_utils.h" | |
21 #include "webrtc/modules/interface/module_common_types.h" | |
22 #include "webrtc/system_wrappers/interface/event_wrapper.h" | |
23 #include "webrtc/system_wrappers/interface/sleep.h" | |
24 #include "webrtc/system_wrappers/interface/thread_wrapper.h" | |
25 | |
26 namespace webrtc { | |
27 | |
28 namespace { | |
29 | |
30 // Type of the render thread APM API call to use in the test. | |
31 enum class RenderApiFunctionImplementation { | |
32 ProcessReverseStreamImplementation1, | |
33 ProcessReverseStreamImplementation2, | |
34 AnalyzeReverseStreamImplementation1, | |
35 AnalyzeReverseStreamImplementation2 | |
36 }; | |
37 // Type of the capture thread APM API call to use in the test. | |
38 enum class CaptureApiFunctionImplementation { | |
39 ProcessStreamImplementation1, | |
40 ProcessStreamImplementation2, | |
41 ProcessStreamImplementation3 | |
42 }; | |
43 // The runtime parameter setting scheme to use in the test. | |
44 enum class RuntimeParameterSettingScheme { | |
45 SparseStreamMetadataChangeScheme, | |
46 ExtremeStreamMetadataChangeScheme, | |
47 FixedMonoStreamMetadataScheme, | |
48 FixedStereoStreamMetadataScheme | |
49 }; | |
50 enum class AecType { | |
51 BasicWebRtcAecSettings, | |
52 AecTurnedOff, | |
53 BasicWebRtcAecSettingsWithExtentedFilter, | |
hlundin-webrtc
2015/10/27 10:54:24
I gather that BasicWebRtcAecSettingsWith* alters t
peah-webrtc
2015/10/29 09:00:09
Great point! Unfortunately the APM api does not al
| |
54 BasicWebRtcAecSettingsWithDelayAgnosticAec, | |
55 BasicWebRtcAecSettingsWithAecMobile | |
56 }; | |
57 | |
58 // The configuration for the test to use. | |
59 struct TestConfig { | |
60 RenderApiFunctionImplementation render_api_function; | |
61 CaptureApiFunctionImplementation capture_api_function; | |
62 RuntimeParameterSettingScheme runtime_parameter_setting_scheme; | |
63 int initial_sample_rate; | |
hlundin-webrtc
2015/10/27 10:54:25
Unit should be included in variable name, e.g., in
peah-webrtc
2015/10/29 09:00:08
Done.
| |
64 AecType aec_type; | |
65 int min_number_of_calls; | |
66 }; | |
67 | |
68 // Provides thread_safe random numbers. | |
hlundin-webrtc
2015/10/27 10:54:25
thread_safe -> thread-safe
peah-webrtc
2015/10/29 09:00:08
Done.
| |
69 class ThreadSafeRandomNumberGenerator { | |
the sun
2015/10/27 11:02:15
Please use webrtc/test/random.h instead.
peah-webrtc
2015/10/29 09:00:08
Done.
| |
70 public: | |
71 ThreadSafeRandomNumberGenerator() : ThreadSafeRandomNumberGenerator(42) {} | |
72 | |
73 explicit ThreadSafeRandomNumberGenerator(int seed) { srand(seed); } | |
kwiberg-webrtc
2015/10/26 14:43:14
Since the sequence of random numbers observed by a
hlundin-webrtc
2015/10/27 10:54:25
Agree. But if you do keep this constructor, the ar
peah-webrtc
2015/10/29 09:00:08
Good point. This is now changed to use the random
peah-webrtc
2015/10/29 09:00:09
Another good point! This is now, however changed t
| |
74 | |
75 int operator()() { | |
76 rtc::CritScope cs(&crit_); | |
77 return rand(); | |
78 } | |
79 | |
80 private: | |
81 rtc::CriticalSection crit_; | |
82 }; | |
83 | |
84 // Class for implementing the tests of the locks in the audio processing module. | |
85 class AudioProcessingImpLockTest : public ::testing::TestWithParam<TestConfig> { | |
the sun
2015/10/27 11:02:15
nit: final
peah-webrtc
2015/10/29 09:00:08
Done.
| |
86 public: | |
87 AudioProcessingImpLockTest() | |
88 : test_complete_(EventWrapper::Create()), | |
89 render_thread_( | |
90 ThreadWrapper::CreateThread(CbRenderThread, this, "render")), | |
91 capture_thread_( | |
92 ThreadWrapper::CreateThread(CbCaptureThread, this, "capture")), | |
93 stats_thread_( | |
94 ThreadWrapper::CreateThread(CbStatsThread, this, "stats")) { | |
95 // Setup the two-dimensional arrays needed for the APM API calls. | |
hlundin-webrtc
2015/10/27 10:54:25
Nit: Setup -> Set up
The former is a noun or adjec
peah-webrtc
2015/10/29 09:00:08
Great catch!
Done.
| |
96 capture_thread_only_state_.capture_input_framechannels_.resize(2 * 480); | |
97 capture_thread_only_state_.capture_input_frame.resize(2); | |
98 capture_thread_only_state_.capture_input_frame[0] = | |
99 &capture_thread_only_state_.capture_input_framechannels_[0]; | |
100 capture_thread_only_state_.capture_input_frame[1] = | |
101 &capture_thread_only_state_.capture_input_framechannels_[480]; | |
102 | |
103 capture_thread_only_state_.capture_output_frame_channels.resize(2 * 480); | |
104 capture_thread_only_state_.capture_output_frame.resize(2); | |
105 capture_thread_only_state_.capture_output_frame[0] = | |
106 &capture_thread_only_state_.capture_output_frame_channels[0]; | |
107 capture_thread_only_state_.capture_output_frame[1] = | |
108 &capture_thread_only_state_.capture_output_frame_channels[480]; | |
109 | |
110 render_thread_only_state_.render_input_frame_channels.resize(2 * 480); | |
111 render_thread_only_state_.render_input_frame.resize(2); | |
112 render_thread_only_state_.render_input_frame[0] = | |
113 &render_thread_only_state_.render_input_frame_channels[0]; | |
114 render_thread_only_state_.render_input_frame[1] = | |
115 &render_thread_only_state_.render_input_frame_channels[480]; | |
116 | |
117 render_thread_only_state_.render_output_frame_channels.resize(2 * 480); | |
118 render_thread_only_state_.render_output_frame.resize(2); | |
119 render_thread_only_state_.render_output_frame[0] = | |
120 &render_thread_only_state_.render_output_frame_channels[0]; | |
121 render_thread_only_state_.render_output_frame[1] = | |
122 &render_thread_only_state_.render_output_frame_channels[480]; | |
123 } | |
124 | |
125 // Run the test with a timeout. | |
126 EventTypeWrapper RunTest() { | |
127 StartThreads(); | |
128 return test_complete_->Wait(kTestTimeOutLimit); | |
129 } | |
130 | |
131 virtual void SetUp() { | |
hlundin-webrtc
2015/10/27 10:54:25
override, and not virtual.
peah-webrtc
2015/10/29 09:00:08
Done.
| |
132 apm_.reset(AudioProcessingImpl::Create()); | |
133 test_config_ = static_cast<TestConfig>(GetParam()); | |
134 | |
135 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true)); | |
hlundin-webrtc
2015/10/27 10:54:25
Does it make sense to continue with the test if an
peah-webrtc
2015/10/29 09:00:08
Good point!
Done.
| |
136 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true)); | |
137 | |
138 EXPECT_EQ(apm_->kNoError, | |
139 apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog)); | |
140 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true)); | |
141 EXPECT_EQ(apm_->kNoError, | |
142 apm_->gain_control()->set_mode(GainControl::kFixedDigital)); | |
143 | |
144 EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true)); | |
145 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true)); | |
146 | |
147 Config config; | |
148 bool use_config = false; | |
149 if (test_config_.aec_type == AecType::AecTurnedOff) { | |
150 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false)); | |
151 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false)); | |
152 } else { | |
153 if (test_config_.aec_type == | |
154 AecType::BasicWebRtcAecSettingsWithAecMobile) { | |
155 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true)); | |
156 } else { | |
157 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true)); | |
158 EXPECT_EQ(apm_->kNoError, | |
159 apm_->echo_cancellation()->enable_metrics(true)); | |
160 EXPECT_EQ(apm_->kNoError, | |
161 apm_->echo_cancellation()->enable_delay_logging(true)); | |
162 | |
163 if (test_config_.aec_type == | |
164 AecType::BasicWebRtcAecSettingsWithExtentedFilter) { | |
165 config.Set<ExtendedFilter>(new ExtendedFilter(true)); | |
166 use_config = true; | |
167 } | |
168 | |
169 if (test_config_.aec_type == | |
170 AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec) { | |
171 config.Set<DelayAgnostic>(new DelayAgnostic(true)); | |
172 use_config = true; | |
173 } | |
174 | |
175 if (use_config) | |
176 apm_->SetExtraOptions(config); | |
177 } | |
178 } | |
179 } | |
180 | |
181 virtual void TearDown() { | |
hlundin-webrtc
2015/10/27 10:54:25
override, and not virtual.
peah-webrtc
2015/10/29 09:00:08
Done.
| |
182 render_thread_->Stop(); | |
183 capture_thread_->Stop(); | |
184 stats_thread_->Stop(); | |
185 } | |
186 | |
187 // Function for generating the test configurations to use in the brief tests. | |
188 static std::vector<TestConfig> GenerateBriefTestConfigs() { | |
189 std::vector<TestConfig> test_configs; | |
190 for (int aec = static_cast<int>( | |
191 AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec); | |
192 aec <= static_cast<int>(AecType::BasicWebRtcAecSettingsWithAecMobile); | |
193 aec++) { | |
194 TestConfig test_config; | |
195 | |
196 test_config.min_number_of_calls = 300; | |
197 | |
198 // Perform tests only with the extreme runtime parameter setting scheme. | |
199 test_config.runtime_parameter_setting_scheme = | |
200 RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme; | |
201 | |
202 // Only test 16 kHz for this test suite. | |
203 test_config.initial_sample_rate = 16000; | |
204 | |
205 // Create test config for the second processing API function set. | |
206 test_config.render_api_function = | |
207 RenderApiFunctionImplementation::ProcessReverseStreamImplementation2; | |
208 test_config.capture_api_function = | |
209 CaptureApiFunctionImplementation::ProcessStreamImplementation2; | |
210 | |
211 // Create test config for the first processing API function set. | |
212 test_configs.push_back(test_config); | |
213 test_config.render_api_function = | |
214 RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation2; | |
215 test_config.capture_api_function = | |
216 CaptureApiFunctionImplementation::ProcessStreamImplementation3; | |
217 test_configs.push_back(test_config); | |
218 } | |
219 | |
220 // Return the created test configurations | |
hlundin-webrtc
2015/10/27 10:54:25
End with .
peah-webrtc
2015/10/29 09:00:08
Done.
| |
221 return test_configs; | |
222 } | |
223 | |
224 // Function for generating the test configurations to use in the extensive | |
225 // tests | |
hlundin-webrtc
2015/10/27 10:54:25
End with .
peah-webrtc
2015/10/29 09:00:09
Done.
| |
226 static std::vector<TestConfig> GenerateExtensiveTestConfigs() { | |
227 std::vector<TestConfig> test_configs; | |
228 // Loop over all possible test configurations | |
hlundin-webrtc
2015/10/27 10:54:24
End with .
peah-webrtc
2015/10/29 09:00:08
Done.
| |
229 for (int render = static_cast<int>(RenderApiFunctionImplementation:: | |
230 ProcessReverseStreamImplementation1); | |
231 render <= static_cast<int>(RenderApiFunctionImplementation:: | |
232 AnalyzeReverseStreamImplementation2); | |
233 render++) | |
234 for (int capture = static_cast<int>( | |
235 CaptureApiFunctionImplementation::ProcessStreamImplementation1); | |
236 capture <= | |
237 static_cast<int>( | |
238 CaptureApiFunctionImplementation::ProcessStreamImplementation3); | |
239 capture++) | |
240 for (int aec = static_cast<int>(AecType::BasicWebRtcAecSettings); | |
241 aec <= | |
242 static_cast<int>(AecType::BasicWebRtcAecSettingsWithAecMobile); | |
243 aec++) | |
244 for (int scheme = | |
245 static_cast<int>(RuntimeParameterSettingScheme:: | |
246 SparseStreamMetadataChangeScheme); | |
247 scheme <= static_cast<int>(RuntimeParameterSettingScheme:: | |
248 FixedStereoStreamMetadataScheme); | |
249 scheme++) { | |
250 TestConfig test_config; | |
251 test_config.min_number_of_calls = 10000; | |
252 | |
253 test_config.render_api_function = | |
254 static_cast<RenderApiFunctionImplementation>(render); | |
255 test_config.capture_api_function = | |
256 static_cast<CaptureApiFunctionImplementation>(capture); | |
257 test_config.aec_type = static_cast<AecType>(aec); | |
258 | |
259 // Check that the selected render and capture API calls are | |
260 // compatible | |
261 if ((((test_config.render_api_function == | |
262 RenderApiFunctionImplementation:: | |
263 ProcessReverseStreamImplementation1) || | |
264 (test_config.render_api_function == | |
265 RenderApiFunctionImplementation:: | |
266 AnalyzeReverseStreamImplementation1)) && | |
267 (test_config.capture_api_function == | |
268 CaptureApiFunctionImplementation:: | |
269 ProcessStreamImplementation1)) || | |
270 (((test_config.render_api_function != | |
271 RenderApiFunctionImplementation:: | |
272 ProcessReverseStreamImplementation1) && | |
273 (test_config.render_api_function != | |
274 RenderApiFunctionImplementation:: | |
275 AnalyzeReverseStreamImplementation1)) && | |
276 (test_config.capture_api_function != | |
277 CaptureApiFunctionImplementation:: | |
278 ProcessStreamImplementation1))) { | |
279 // For the compatible render and capture function combinations | |
280 // add test configs with different initial sample rates and | |
281 // parameter setting schemes | |
hlundin-webrtc
2015/10/27 10:54:25
End with .
peah-webrtc
2015/10/29 09:00:08
Done.
| |
282 test_config.runtime_parameter_setting_scheme = | |
283 static_cast<RuntimeParameterSettingScheme>(scheme); | |
284 | |
285 test_config.initial_sample_rate = 8000; | |
286 test_configs.push_back(test_config); | |
287 | |
288 test_config.initial_sample_rate = 16000; | |
289 test_configs.push_back(test_config); | |
290 | |
291 if (test_config.aec_type != | |
292 AecType::BasicWebRtcAecSettingsWithAecMobile) { | |
293 test_config.initial_sample_rate = 32000; | |
294 test_configs.push_back(test_config); | |
295 | |
296 test_config.initial_sample_rate = 48000; | |
297 test_configs.push_back(test_config); | |
298 } | |
299 } | |
300 } | |
301 // Return the created test configurations | |
hlundin-webrtc
2015/10/27 10:54:25
End with .
peah-webrtc
2015/10/29 09:00:08
Done.
| |
302 return test_configs; | |
303 } | |
304 | |
305 private: | |
306 static const int kTestTimeOutLimit = 10 * 60 * 1000; | |
307 static const int kMaxCallDifference = 10; | |
308 static constexpr float kRenderInputFloatLevel = 0.5f; | |
hlundin-webrtc
2015/10/27 10:54:24
constexpr is still banned in Chromium. See https:/
peah-webrtc
2015/10/29 09:00:08
Done.
| |
309 static constexpr float kCaptureInputFloatLevel = 0.03125f; | |
hlundin-webrtc
2015/10/27 10:54:25
And here.
peah-webrtc
2015/10/29 09:00:08
Done.
| |
310 static const int kRenderInputFixLevel = 16384; | |
311 static const int kCaptureInputFixLevel = 1024; | |
312 | |
313 // Generates random number between -(amplitude+1) and amplitude | |
314 int16_t GenerateRandomInt16(int16_t amplitude) const { | |
315 return ((rand_gen() % (amplitude + amplitude + 1)) - (amplitude + 1)); | |
316 } | |
317 | |
318 // Populates a float audio frame with random data. | |
319 void PopulateAudioFrame(float** frame, | |
320 float amplitude, | |
321 int num_channels, | |
322 int samples_per_channel) const { | |
323 for (int ch = 0; ch < num_channels; ch++) { | |
hlundin-webrtc
2015/10/27 10:54:25
Nit: ch and k should probably both be size_t, bein
peah-webrtc
2015/10/29 09:00:08
Done.
| |
324 for (int k = 0; k < samples_per_channel; k++) { | |
325 // Store random 16 bit quantized float number between the specified | |
326 // limits. | |
327 frame[ch][k] = amplitude * | |
328 static_cast<float>(GenerateRandomInt16(32767)) / | |
329 32768.0f; | |
330 } | |
331 } | |
332 } | |
333 | |
334 // Populates an audioframe frame of AudioFrame type with random data. | |
335 void PopulateAudioFrame(AudioFrame* frame, int16_t amplitude) const { | |
336 assert(amplitude > 0); | |
kwiberg-webrtc
2015/10/26 14:43:14
ASSERT_GT, or maybe EXPECT_GT
hlundin-webrtc
2015/10/27 10:54:24
Agree. Never use assert, CHECK or DCHECK in unit t
peah-webrtc
2015/10/29 09:00:08
Done.
peah-webrtc
2015/10/29 09:00:09
Thanks for the explanation! That is a great point
| |
337 assert(amplitude <= 32767); | |
kwiberg-webrtc
2015/10/26 14:43:14
Same, if you want to keep this no-op check.
peah-webrtc
2015/10/29 09:00:09
Done.
| |
338 for (int ch = 0; ch < frame->num_channels_; ch++) { | |
339 for (int k = 0; k < static_cast<int>(frame->samples_per_channel_); k++) { | |
340 // Store random 16 bit quantized float number between -1 and 1. | |
341 frame->data_[k * ch] = GenerateRandomInt16(amplitude); | |
342 } | |
343 } | |
344 } | |
345 | |
346 // Thread callback for the render thread | |
347 static bool CbRenderThread(void* context) { | |
the sun
2015/10/27 11:02:15
Drop the "Cb", here and below. I think it is confu
peah-webrtc
2015/10/29 09:00:09
Done.
| |
348 return reinterpret_cast<AudioProcessingImpLockTest*>(context) | |
349 ->CbRenderImpl(); | |
the sun
2015/10/27 11:02:15
CbRenderImpl -> RenderThreadImpl or simply RenderT
peah-webrtc
2015/10/29 09:00:08
Done.
| |
350 } | |
351 | |
352 // Thread callback for the capture thread | |
353 static bool CbCaptureThread(void* context) { | |
354 return reinterpret_cast<AudioProcessingImpLockTest*>(context) | |
355 ->CbCaptureImpl(); | |
356 } | |
357 | |
358 // Thread callback for the stats thread | |
359 static bool CbStatsThread(void* context) { | |
360 return reinterpret_cast<AudioProcessingImpLockTest*>(context) | |
361 ->CbStatsImpl(); | |
362 } | |
363 | |
364 // Tests whether all the required render and capture side calls have been | |
365 // done. | |
366 bool TestDone() { | |
367 rtc::CritScope cs(&crit_); | |
368 return ((shared_thread_counter_state_.render_count > | |
369 test_config_.min_number_of_calls) && | |
370 (shared_thread_counter_state_.capture_count > | |
371 test_config_.min_number_of_calls)); | |
372 } | |
373 | |
374 // Sleeps a random time between 0 and max_sleep milliseconds. | |
375 void SleepRandomTime(int max_sleep) const { | |
kwiberg-webrtc
2015/10/26 14:43:14
SleepRandomMs?
peah-webrtc
2015/10/29 09:00:09
Done.
| |
376 int sleeptime = rand_gen() % (max_sleep + 1); | |
377 SleepMs(sleeptime); | |
378 } | |
379 | |
380 // Implements the callback functionality for the statistics | |
381 // collection thread. | |
382 bool CbStatsImpl() { | |
383 SleepRandomTime(100); | |
384 | |
385 (void)apm_->echo_cancellation()->is_enabled(); | |
hlundin-webrtc
2015/10/27 10:54:24
Why do you need the C-style (void) cast?
the sun
2015/10/27 11:02:15
Why do you need to call these at all? If you do, d
peah-webrtc
2015/10/29 09:00:08
I'm interested in catching any side-effects presen
peah-webrtc
2015/10/29 09:00:09
Ouch! Old habit! I'm used to having build errors w
| |
386 (void)apm_->echo_cancellation()->stream_drift_samples(); | |
387 (void)apm_->echo_control_mobile()->is_enabled(); | |
388 (void)apm_->gain_control()->is_enabled(); | |
389 (void)apm_->gain_control()->stream_analog_level(); | |
390 (void)apm_->noise_suppression()->is_enabled(); | |
391 (void)apm_->noise_suppression()->speech_probability(); | |
392 (void)apm_->voice_detection()->is_enabled(); | |
393 | |
394 return true; | |
395 } | |
396 | |
397 // Implements the callback functionality for the render thread. | |
398 bool CbRenderImpl() { | |
399 // Conditional wait to ensure that a capture call has been done | |
400 // before the first render call is performed (implicitly | |
401 // required by the APM API). | |
402 if (render_thread_only_state_.first_render_side_call_) { | |
403 bool capture_side_called_local; | |
404 do { | |
405 { | |
406 rtc::CritScope cs(&crit_initial_sync_); | |
407 capture_side_called_local = | |
408 shared_thread_init_state_.capture_side_called; | |
409 } | |
410 SleepRandomTime(3); | |
411 } while (!capture_side_called_local); | |
412 | |
413 render_thread_only_state_.first_render_side_call_ = false; | |
414 } | |
415 | |
416 // Sleep a random time to simulate thread jitter. | |
417 SleepRandomTime(3); | |
418 | |
419 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
420 if (HasFatalFailure()) | |
421 test_complete_->Set(); | |
422 | |
423 // Ensure that the number of render and capture calls do not | |
424 // differ too much. | |
425 int frame_counter_difference; | |
426 do { | |
427 { | |
428 rtc::CritScope cs(&crit_); | |
429 frame_counter_difference = | |
430 (shared_thread_counter_state_.render_count - | |
431 (shared_thread_counter_state_.capture_count + kMaxCallDifference)); | |
432 } | |
433 if (frame_counter_difference > 0) | |
434 SleepMs(1); | |
435 } while (frame_counter_difference > 0); | |
436 | |
437 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
hlundin-webrtc
2015/10/27 10:54:25
Do you have to test this twice in the same functio
peah-webrtc
2015/10/29 09:00:09
Done.
| |
438 if (HasFatalFailure()) | |
439 test_complete_->Set(); | |
440 | |
441 // Apply any specified render side APM non-processing runtime calls. | |
442 ApplyRenderRuntimeSettingScheme(); | |
443 | |
444 // Apply the render side processing call. | |
445 CallRenderSide(); | |
446 | |
447 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
hlundin-webrtc
2015/10/27 10:54:25
Thrice...?!
peah-webrtc
2015/10/29 09:00:08
Done.
| |
448 if (HasFatalFailure()) | |
449 test_complete_->Set(); | |
450 | |
451 // Increase the number of render-side calls. | |
452 rtc::CritScope cs(&crit_); | |
453 shared_thread_counter_state_.render_count++; | |
454 | |
455 return true; | |
456 } | |
457 | |
458 // Makes the capture side processing API call. | |
459 void CallCaptureSide() { | |
460 // Prepare a proper capture side processing API call input. | |
461 PrepareCaptureFrame(); | |
462 | |
463 // Set the stream delay | |
464 (void)apm_->set_stream_delay_ms(30); | |
465 | |
466 // Call the specified capture side API processing method. | |
467 int result = AudioProcessing::kNoError; | |
468 switch (test_config_.capture_api_function) { | |
469 case CaptureApiFunctionImplementation::ProcessStreamImplementation1: | |
470 result = apm_->ProcessStream(&capture_thread_only_state_.capture_frame); | |
471 break; | |
472 case CaptureApiFunctionImplementation::ProcessStreamImplementation2: | |
473 result = apm_->ProcessStream( | |
474 &capture_thread_only_state_.capture_input_frame[0], | |
475 capture_thread_only_state_.capture_input_samples_per_channel, | |
476 capture_thread_only_state_.capture_input_sample_rate_hz, | |
477 capture_thread_only_state_.capture_input_channel_layout, | |
478 capture_thread_only_state_.capture_output_sample_rate_hz, | |
479 capture_thread_only_state_.capture_output_channel_layout, | |
480 &capture_thread_only_state_.capture_output_frame[0]); | |
481 break; | |
482 case CaptureApiFunctionImplementation::ProcessStreamImplementation3: | |
483 result = apm_->ProcessStream( | |
484 &capture_thread_only_state_.capture_input_frame[0], | |
485 capture_thread_only_state_.capture_input_stream_config, | |
486 capture_thread_only_state_.capture_output_stream_config, | |
487 &capture_thread_only_state_.capture_output_frame[0]); | |
488 break; | |
489 default: | |
490 assert(false); | |
491 } | |
492 | |
493 // Check the return code for error. | |
494 EXPECT_EQ(AudioProcessing::kNoError, result); | |
495 } | |
496 | |
497 // Prepares the render side frame and the accompanying metadata | |
498 // with the appropriate information. | |
499 void PrepareRenderFrame() { | |
500 // Restrict to a common fixed sample rate if the AudioFrame interface is | |
501 // used. | |
502 if ((test_config_.render_api_function == | |
503 RenderApiFunctionImplementation:: | |
504 AnalyzeReverseStreamImplementation1) || | |
505 (test_config_.render_api_function == | |
506 RenderApiFunctionImplementation:: | |
507 ProcessReverseStreamImplementation1) || | |
508 (test_config_.aec_type != | |
509 AecType::BasicWebRtcAecSettingsWithAecMobile)) { | |
510 render_thread_only_state_.render_input_sample_rate_hz = | |
511 test_config_.initial_sample_rate; | |
512 render_thread_only_state_.render_output_sample_rate_hz = | |
513 test_config_.initial_sample_rate; | |
514 } | |
515 | |
516 // Prepare the audioframe data and metadata | |
517 render_thread_only_state_.render_input_samples_per_channel = | |
518 render_thread_only_state_.render_input_sample_rate_hz * | |
519 AudioProcessing::kChunkSizeMs / 1000; | |
520 render_thread_only_state_.render_frame.sample_rate_hz_ = | |
521 render_thread_only_state_.render_input_sample_rate_hz; | |
522 render_thread_only_state_.render_frame.num_channels_ = | |
523 render_thread_only_state_.render_input_number_of_channels; | |
524 render_thread_only_state_.render_frame.samples_per_channel_ = | |
525 render_thread_only_state_.render_input_samples_per_channel; | |
526 memset(render_thread_only_state_.render_frame.data_, 0, | |
527 render_thread_only_state_.render_input_samples_per_channel * | |
528 sizeof(render_thread_only_state_.render_frame.data_[0])); | |
529 PopulateAudioFrame(&render_thread_only_state_.render_frame, | |
530 kRenderInputFixLevel); | |
531 | |
532 // Prepare the float audio input data and metadata. | |
533 render_thread_only_state_.render_input_stream_config.set_sample_rate_hz( | |
534 render_thread_only_state_.render_input_sample_rate_hz); | |
535 render_thread_only_state_.render_input_stream_config.set_num_channels( | |
536 render_thread_only_state_.render_input_number_of_channels); | |
537 render_thread_only_state_.render_input_stream_config.set_has_keyboard( | |
538 false); | |
539 PopulateAudioFrame( | |
540 &render_thread_only_state_.render_input_frame[0], | |
541 kRenderInputFloatLevel, | |
542 render_thread_only_state_.render_input_number_of_channels, | |
543 render_thread_only_state_.render_input_samples_per_channel); | |
544 render_thread_only_state_.render_input_channel_layout = | |
545 (render_thread_only_state_.render_input_number_of_channels == 1 | |
546 ? AudioProcessing::ChannelLayout::kMono | |
547 : AudioProcessing::ChannelLayout::kStereo); | |
548 | |
549 // Prepare the float audio output data and metadata. | |
550 render_thread_only_state_.render_output_samples_per_channel = | |
551 render_thread_only_state_.render_output_sample_rate_hz * | |
552 AudioProcessing::kChunkSizeMs / 1000; | |
553 render_thread_only_state_.render_output_stream_config.set_sample_rate_hz( | |
554 render_thread_only_state_.render_output_sample_rate_hz); | |
555 render_thread_only_state_.render_output_stream_config.set_num_channels( | |
556 render_thread_only_state_.render_output_number_of_channels); | |
557 render_thread_only_state_.render_output_stream_config.set_has_keyboard( | |
558 false); | |
559 render_thread_only_state_.render_output_channel_layout = | |
560 (render_thread_only_state_.render_output_number_of_channels == 1 | |
561 ? AudioProcessing::ChannelLayout::kMono | |
562 : AudioProcessing::ChannelLayout::kStereo); | |
563 } | |
564 | |
565 void PrepareCaptureFrame() { | |
566 // Restrict to a common fixed sample rate if the AudioFrame | |
567 // interface is used. | |
568 if (test_config_.capture_api_function == | |
569 CaptureApiFunctionImplementation::ProcessStreamImplementation1) { | |
570 capture_thread_only_state_.capture_input_sample_rate_hz = | |
571 test_config_.initial_sample_rate; | |
572 capture_thread_only_state_.capture_output_sample_rate_hz = | |
573 test_config_.initial_sample_rate; | |
574 } | |
575 | |
576 // Prepare the audioframe data and metadata. | |
577 capture_thread_only_state_.capture_input_samples_per_channel = | |
578 capture_thread_only_state_.capture_input_sample_rate_hz * | |
579 AudioProcessing::kChunkSizeMs / 1000; | |
580 capture_thread_only_state_.capture_frame.sample_rate_hz_ = | |
581 capture_thread_only_state_.capture_input_sample_rate_hz; | |
582 capture_thread_only_state_.capture_frame.num_channels_ = | |
583 capture_thread_only_state_.capture_input_number_of_channels; | |
584 capture_thread_only_state_.capture_frame.samples_per_channel_ = | |
585 capture_thread_only_state_.capture_input_samples_per_channel; | |
586 memset(capture_thread_only_state_.capture_frame.data_, 0, | |
587 capture_thread_only_state_.capture_input_samples_per_channel * | |
588 sizeof(capture_thread_only_state_.capture_frame.data_[0])); | |
589 PopulateAudioFrame(&capture_thread_only_state_.capture_frame, | |
590 kCaptureInputFixLevel); | |
591 | |
592 // Prepare the float audio input data and metadata. | |
593 capture_thread_only_state_.capture_input_stream_config.set_sample_rate_hz( | |
594 capture_thread_only_state_.capture_input_sample_rate_hz); | |
595 capture_thread_only_state_.capture_input_stream_config.set_num_channels( | |
596 capture_thread_only_state_.capture_input_number_of_channels); | |
597 capture_thread_only_state_.capture_input_stream_config.set_has_keyboard( | |
598 false); | |
599 PopulateAudioFrame( | |
600 &capture_thread_only_state_.capture_input_frame[0], | |
601 kCaptureInputFloatLevel, | |
602 capture_thread_only_state_.capture_input_number_of_channels, | |
603 capture_thread_only_state_.capture_input_samples_per_channel); | |
604 capture_thread_only_state_.capture_input_channel_layout = | |
605 (capture_thread_only_state_.capture_input_number_of_channels == 1 | |
606 ? AudioProcessing::ChannelLayout::kMonoAndKeyboard | |
607 : AudioProcessing::ChannelLayout::kStereoAndKeyboard); | |
608 | |
609 // Prepare the float audio output data and metadata. | |
610 capture_thread_only_state_.capture_output_samples_per_channel = | |
611 capture_thread_only_state_.capture_output_sample_rate_hz * | |
612 AudioProcessing::kChunkSizeMs / 1000; | |
613 capture_thread_only_state_.capture_output_stream_config.set_sample_rate_hz( | |
614 capture_thread_only_state_.capture_output_sample_rate_hz); | |
615 capture_thread_only_state_.capture_output_stream_config.set_num_channels( | |
616 capture_thread_only_state_.capture_output_number_of_channels); | |
617 capture_thread_only_state_.capture_output_stream_config.set_has_keyboard( | |
618 false); | |
619 capture_thread_only_state_.capture_output_channel_layout = | |
620 (capture_thread_only_state_.capture_output_number_of_channels == 1 | |
621 ? AudioProcessing::ChannelLayout::kMono | |
622 : AudioProcessing::ChannelLayout::kStereo); | |
623 } | |
624 | |
625 // Applies any render capture APM API calls and audio stream characteristics | |
626 // specified by the scheme for the test. | |
627 void ApplyRenderRuntimeSettingScheme() { | |
628 const int render_count_local = [this] { | |
629 rtc::CritScope cs(&crit_); | |
630 return shared_thread_counter_state_.render_count; | |
631 }(); | |
632 | |
633 // Update the number of channels and sample rates for the input and output. | |
634 // Note that the counts frequencies for when to set parameters | |
635 // are set using prime numbers in order to ensure that the | |
636 // permutation scheme in the parameter setting changes. | |
637 switch (test_config_.runtime_parameter_setting_scheme) { | |
638 case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: | |
639 if (render_count_local == 0) | |
640 render_thread_only_state_.render_input_sample_rate_hz = 16000; | |
641 else if (render_count_local % 47 == 0) | |
642 render_thread_only_state_.render_input_sample_rate_hz = 32000; | |
643 else if (render_count_local % 71 == 0) | |
644 render_thread_only_state_.render_input_sample_rate_hz = 48000; | |
645 else if (render_count_local % 79 == 0) | |
646 render_thread_only_state_.render_input_sample_rate_hz = 16000; | |
647 else if (render_count_local % 83 == 0) | |
648 render_thread_only_state_.render_input_sample_rate_hz = 8000; | |
649 | |
650 if (render_count_local == 0) | |
651 render_thread_only_state_.render_input_number_of_channels = 1; | |
652 else if (render_count_local % 4 == 0) | |
653 render_thread_only_state_.render_input_number_of_channels = | |
654 (render_thread_only_state_.render_input_number_of_channels == 1 | |
655 ? 2 | |
656 : 1); | |
657 | |
658 if (render_count_local == 0) | |
659 render_thread_only_state_.render_output_sample_rate_hz = 16000; | |
660 else if (render_count_local % 17 == 0) | |
661 render_thread_only_state_.render_output_sample_rate_hz = 32000; | |
662 else if (render_count_local % 19 == 0) | |
663 render_thread_only_state_.render_output_sample_rate_hz = 48000; | |
664 else if (render_count_local % 29 == 0) | |
665 render_thread_only_state_.render_output_sample_rate_hz = 16000; | |
666 else if (render_count_local % 61 == 0) | |
667 render_thread_only_state_.render_output_sample_rate_hz = 8000; | |
668 | |
669 if (render_count_local == 0) | |
670 render_thread_only_state_.render_output_number_of_channels = 1; | |
671 else if (render_count_local % 8 == 0) | |
672 render_thread_only_state_.render_output_number_of_channels = | |
673 (render_thread_only_state_.render_output_number_of_channels == 1 | |
674 ? 2 | |
675 : 1); | |
676 break; | |
677 case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: | |
678 if (render_count_local == 0) { | |
679 render_thread_only_state_.render_input_number_of_channels = 1; | |
680 render_thread_only_state_.render_input_sample_rate_hz = 16000; | |
681 render_thread_only_state_.render_output_number_of_channels = 1; | |
682 render_thread_only_state_.render_output_sample_rate_hz = 16000; | |
683 } else { | |
684 render_thread_only_state_.render_input_number_of_channels = | |
685 (render_thread_only_state_.render_input_number_of_channels == 1 | |
686 ? 2 | |
687 : 1); | |
688 if (render_thread_only_state_.render_input_sample_rate_hz == 8000) | |
689 render_thread_only_state_.render_input_sample_rate_hz = 16000; | |
690 else if (render_thread_only_state_.render_input_sample_rate_hz == | |
691 16000) | |
692 render_thread_only_state_.render_input_sample_rate_hz = 32000; | |
693 else if (render_thread_only_state_.render_input_sample_rate_hz == | |
694 32000) | |
695 render_thread_only_state_.render_input_sample_rate_hz = 48000; | |
696 else if (render_thread_only_state_.render_input_sample_rate_hz == | |
697 48000) | |
698 render_thread_only_state_.render_input_sample_rate_hz = 8000; | |
699 | |
700 render_thread_only_state_.render_output_number_of_channels = | |
701 (render_thread_only_state_.render_output_number_of_channels == 1 | |
702 ? 2 | |
703 : 1); | |
704 if (render_thread_only_state_.render_output_sample_rate_hz == 8000) | |
705 render_thread_only_state_.render_output_sample_rate_hz = 16000; | |
706 else if (render_thread_only_state_.render_output_sample_rate_hz == | |
707 16000) | |
708 render_thread_only_state_.render_output_sample_rate_hz = 32000; | |
709 else if (render_thread_only_state_.render_output_sample_rate_hz == | |
710 32000) | |
711 render_thread_only_state_.render_output_sample_rate_hz = 48000; | |
712 else if (render_thread_only_state_.render_output_sample_rate_hz == | |
713 48000) | |
714 render_thread_only_state_.render_output_sample_rate_hz = 8000; | |
715 } | |
716 break; | |
717 case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: | |
718 if (render_count_local == 0) { | |
719 render_thread_only_state_.render_input_sample_rate_hz = 16000; | |
720 render_thread_only_state_.render_input_number_of_channels = 1; | |
721 render_thread_only_state_.render_output_sample_rate_hz = 16000; | |
722 render_thread_only_state_.render_output_number_of_channels = 1; | |
723 } | |
724 break; | |
725 case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: | |
726 if (render_count_local == 0) { | |
727 render_thread_only_state_.render_input_sample_rate_hz = 16000; | |
728 render_thread_only_state_.render_input_number_of_channels = 2; | |
729 render_thread_only_state_.render_output_sample_rate_hz = 16000; | |
730 render_thread_only_state_.render_output_number_of_channels = 2; | |
731 } | |
732 | |
733 break; | |
734 default: | |
735 assert(false); | |
736 } | |
737 | |
738 // Restric the number of output channels not to exceed | |
739 // the number of input channels. | |
740 render_thread_only_state_.render_output_number_of_channels = | |
741 std::min(render_thread_only_state_.render_output_number_of_channels, | |
742 render_thread_only_state_.render_input_number_of_channels); | |
743 } | |
744 | |
745 // Applies any runtime capture APM API calls and audio stream characteristics | |
746 // specified by the scheme for the test. | |
747 void ApplyCaptureRuntimeSettingScheme() { | |
748 const int capture_count_local = [this] { | |
749 rtc::CritScope cs(&crit_); | |
750 return shared_thread_counter_state_.capture_count; | |
751 }(); | |
752 | |
753 // Update the number of channels and sample rates for the input and output. | |
754 // Note that the counts frequencies for when to set parameters | |
755 // are set using prime numbers in order to ensure that the | |
756 // permutation scheme in the parameter setting changes. | |
757 switch (test_config_.runtime_parameter_setting_scheme) { | |
758 case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: | |
759 if (capture_count_local == 0) | |
760 capture_thread_only_state_.capture_input_sample_rate_hz = 16000; | |
761 else if (capture_count_local % 11 == 0) | |
762 capture_thread_only_state_.capture_input_sample_rate_hz = 32000; | |
763 else if (capture_count_local % 73 == 0) | |
764 capture_thread_only_state_.capture_input_sample_rate_hz = 48000; | |
765 else if (capture_count_local % 89 == 0) | |
766 capture_thread_only_state_.capture_input_sample_rate_hz = 16000; | |
767 else if (capture_count_local % 97 == 0) | |
768 capture_thread_only_state_.capture_input_sample_rate_hz = 8000; | |
769 | |
770 if (capture_count_local == 0) | |
771 capture_thread_only_state_.capture_input_number_of_channels = 1; | |
772 else if (capture_count_local % 4 == 0) | |
773 capture_thread_only_state_.capture_input_number_of_channels = | |
774 (capture_thread_only_state_.capture_input_number_of_channels == 1 | |
775 ? 2 | |
776 : 1); | |
777 | |
778 if (capture_count_local == 0) | |
779 capture_thread_only_state_.capture_output_sample_rate_hz = 16000; | |
780 else if (capture_count_local % 5 == 0) | |
781 capture_thread_only_state_.capture_output_sample_rate_hz = 32000; | |
782 else if (capture_count_local % 47 == 0) | |
783 capture_thread_only_state_.capture_output_sample_rate_hz = 48000; | |
784 else if (capture_count_local % 53 == 0) | |
785 capture_thread_only_state_.capture_output_sample_rate_hz = 16000; | |
786 else if (capture_count_local % 71 == 0) | |
787 capture_thread_only_state_.capture_output_sample_rate_hz = 8000; | |
788 | |
789 if (capture_count_local == 0) | |
790 capture_thread_only_state_.capture_output_number_of_channels = 1; | |
791 else if (capture_count_local % 8 == 0) | |
792 capture_thread_only_state_.capture_output_number_of_channels = | |
793 (capture_thread_only_state_.capture_output_number_of_channels == 1 | |
794 ? 2 | |
795 : 1); | |
796 break; | |
797 case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: | |
798 if (capture_count_local % 2 == 0) { | |
799 capture_thread_only_state_.capture_input_number_of_channels = 1; | |
800 capture_thread_only_state_.capture_input_sample_rate_hz = 16000; | |
801 capture_thread_only_state_.capture_output_number_of_channels = 1; | |
802 capture_thread_only_state_.capture_output_sample_rate_hz = 16000; | |
803 } else { | |
804 capture_thread_only_state_.capture_input_number_of_channels = | |
805 (capture_thread_only_state_.capture_input_number_of_channels == 1 | |
806 ? 2 | |
807 : 1); | |
808 if (capture_thread_only_state_.capture_input_sample_rate_hz == 8000) | |
809 capture_thread_only_state_.capture_input_sample_rate_hz = 16000; | |
810 else if (capture_thread_only_state_.capture_input_sample_rate_hz == | |
811 16000) | |
812 capture_thread_only_state_.capture_input_sample_rate_hz = 32000; | |
813 else if (capture_thread_only_state_.capture_input_sample_rate_hz == | |
814 32000) | |
815 capture_thread_only_state_.capture_input_sample_rate_hz = 48000; | |
816 else if (capture_thread_only_state_.capture_input_sample_rate_hz == | |
817 48000) | |
818 capture_thread_only_state_.capture_input_sample_rate_hz = 8000; | |
819 | |
820 capture_thread_only_state_.capture_output_number_of_channels = | |
821 (capture_thread_only_state_.capture_output_number_of_channels == 1 | |
822 ? 2 | |
823 : 1); | |
824 if (capture_thread_only_state_.capture_output_sample_rate_hz == 8000) | |
825 capture_thread_only_state_.capture_output_sample_rate_hz = 16000; | |
826 else if (capture_thread_only_state_.capture_output_sample_rate_hz == | |
827 16000) | |
828 capture_thread_only_state_.capture_output_sample_rate_hz = 32000; | |
829 else if (capture_thread_only_state_.capture_output_sample_rate_hz == | |
830 32000) | |
831 capture_thread_only_state_.capture_output_sample_rate_hz = 48000; | |
832 else if (capture_thread_only_state_.capture_output_sample_rate_hz == | |
833 48000) | |
834 capture_thread_only_state_.capture_output_sample_rate_hz = 8000; | |
835 } | |
836 break; | |
837 case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: | |
838 if (capture_count_local == 0) { | |
839 capture_thread_only_state_.capture_input_sample_rate_hz = 16000; | |
840 capture_thread_only_state_.capture_input_number_of_channels = 1; | |
841 capture_thread_only_state_.capture_output_sample_rate_hz = 16000; | |
842 capture_thread_only_state_.capture_output_number_of_channels = 1; | |
843 } | |
844 break; | |
845 case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: | |
846 if (capture_count_local == 0) { | |
847 capture_thread_only_state_.capture_input_sample_rate_hz = 16000; | |
848 capture_thread_only_state_.capture_input_number_of_channels = 2; | |
849 capture_thread_only_state_.capture_output_sample_rate_hz = 16000; | |
850 capture_thread_only_state_.capture_output_number_of_channels = 2; | |
851 } | |
852 | |
853 break; | |
854 default: | |
855 assert(false); | |
856 } | |
857 | |
858 // Call any specified runtime APM setter and | |
859 // getter calls. | |
860 switch (test_config_.runtime_parameter_setting_scheme) { | |
861 case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: | |
862 case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: | |
863 break; | |
864 case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: | |
865 case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: | |
866 if ((capture_count_local % 2) == 0) { | |
867 EXPECT_EQ(AudioProcessing::Error::kNoError, | |
868 apm_->set_stream_delay_ms(30)); | |
869 apm_->set_stream_key_pressed(true); | |
870 apm_->set_output_will_be_muted(true); | |
871 apm_->set_delay_offset_ms(15); | |
872 (void)apm_->delay_offset_ms(); | |
873 apm_->set_output_will_be_muted(true); | |
874 (void)apm_->num_reverse_channels(); | |
875 } else { | |
876 EXPECT_EQ(AudioProcessing::Error::kNoError, | |
877 apm_->set_stream_delay_ms(50)); | |
878 apm_->set_stream_key_pressed(false); | |
879 apm_->set_output_will_be_muted(false); | |
880 apm_->set_delay_offset_ms(20); | |
881 (void)apm_->delay_offset_ms(); | |
882 apm_->set_output_will_be_muted(false); | |
883 (void)apm_->num_reverse_channels(); | |
884 } | |
885 break; | |
886 default: | |
887 ASSERT_TRUE(false); | |
hlundin-webrtc
2015/10/27 10:54:24
Simply FAIL();
https://code.google.com/p/googletes
peah-webrtc
2015/10/29 09:00:09
Done.
| |
888 } | |
889 | |
890 // Restric the number of output channels not to exceed | |
891 // the number of input channels. | |
892 capture_thread_only_state_.capture_output_number_of_channels = | |
893 std::min(capture_thread_only_state_.capture_output_number_of_channels, | |
894 capture_thread_only_state_.capture_input_number_of_channels); | |
895 } | |
896 | |
897 // Makes the render side processing API call. | |
898 void CallRenderSide() { | |
899 // Prepare a proper render side processing API call input. | |
900 PrepareRenderFrame(); | |
901 | |
902 // Call the specified render side API processing method. | |
903 int result = AudioProcessing::kNoError; | |
904 switch (test_config_.render_api_function) { | |
905 case RenderApiFunctionImplementation::ProcessReverseStreamImplementation1: | |
906 result = | |
907 apm_->ProcessReverseStream(&render_thread_only_state_.render_frame); | |
908 break; | |
909 case RenderApiFunctionImplementation::ProcessReverseStreamImplementation2: | |
910 result = apm_->ProcessReverseStream( | |
911 &render_thread_only_state_.render_input_frame[0], | |
912 render_thread_only_state_.render_input_stream_config, | |
913 render_thread_only_state_.render_output_stream_config, | |
914 &render_thread_only_state_.render_output_frame[0]); | |
915 break; | |
916 case RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation1: | |
917 result = | |
918 apm_->AnalyzeReverseStream(&render_thread_only_state_.render_frame); | |
919 break; | |
920 case RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation2: | |
921 result = apm_->AnalyzeReverseStream( | |
922 &render_thread_only_state_.render_input_frame[0], | |
923 render_thread_only_state_.render_input_samples_per_channel, | |
924 render_thread_only_state_.render_input_sample_rate_hz, | |
925 render_thread_only_state_.render_input_channel_layout); | |
926 break; | |
927 default: | |
928 assert(false); | |
929 } | |
930 | |
931 // Check the return code for error. | |
932 EXPECT_EQ(AudioProcessing::kNoError, result); | |
933 } | |
934 | |
935 // Implements the callback functionality for the capture thread. | |
936 bool CbCaptureImpl() { | |
937 // Sleep a random time to simulate thread jitter. | |
938 SleepRandomTime(3); | |
939 | |
940 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
hlundin-webrtc
2015/10/27 10:54:24
Same comment as earlier: do you really have to che
peah-webrtc
2015/10/29 09:00:08
Done.
| |
941 if (HasFatalFailure()) | |
942 test_complete_->Set(); | |
943 | |
944 // Ensure that there are not more capture side calls than render side | |
945 // calls. | |
946 int frame_counter_difference; | |
947 do { | |
948 { | |
949 rtc::CritScope cs(&crit_); | |
950 frame_counter_difference = shared_thread_counter_state_.capture_count - | |
951 shared_thread_counter_state_.render_count; | |
952 } | |
953 if (frame_counter_difference > 0) | |
954 SleepMs(1); | |
955 } while (frame_counter_difference > 0); | |
956 | |
957 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
958 if (HasFatalFailure()) | |
959 test_complete_->Set(); | |
960 | |
961 // Apply any specified capture side APM non-processing runtime calls. | |
962 ApplyCaptureRuntimeSettingScheme(); | |
963 | |
964 // Apply the capture side processing call. | |
965 CallCaptureSide(); | |
966 | |
967 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
968 if (HasFatalFailure()) | |
969 test_complete_->Set(); | |
970 | |
971 // Increase the number of capture-side calls. | |
972 { | |
973 rtc::CritScope cs(&crit_); | |
974 shared_thread_counter_state_.capture_count++; | |
975 } | |
976 | |
977 // Check if the test is done. | |
978 if (TestDone()) | |
979 test_complete_->Set(); | |
980 | |
981 // Flag that the capture side has been called at least once | |
982 // (needed to ensure that a capture call has been done | |
983 // before the first render call is performed (implicitly | |
984 // required by the APM API). | |
985 { | |
986 rtc::CritScope cs(&crit_initial_sync_); | |
987 shared_thread_init_state_.capture_side_called = true; | |
988 } | |
989 | |
990 return true; | |
991 } | |
992 | |
993 // Start the threads used in the test. | |
994 void StartThreads() { | |
995 ASSERT_TRUE(render_thread_->Start()); | |
996 render_thread_->SetPriority(kRealtimePriority); | |
997 ASSERT_TRUE(capture_thread_->Start()); | |
998 capture_thread_->SetPriority(kRealtimePriority); | |
999 ASSERT_TRUE(stats_thread_->Start()); | |
1000 stats_thread_->SetPriority(kNormalPriority); | |
1001 } | |
1002 | |
1003 // Event handler for the test. | |
1004 const rtc::scoped_ptr<EventWrapper> test_complete_; | |
1005 | |
1006 // Thread related variables. | |
1007 rtc::CriticalSection crit_; | |
1008 rtc::CriticalSection crit_initial_sync_; | |
1009 rtc::scoped_ptr<ThreadWrapper> render_thread_; | |
1010 rtc::scoped_ptr<ThreadWrapper> capture_thread_; | |
1011 rtc::scoped_ptr<ThreadWrapper> stats_thread_; | |
1012 mutable ThreadSafeRandomNumberGenerator rand_gen; | |
1013 | |
1014 // The APM object. | |
1015 rtc::scoped_ptr<AudioProcessing> apm_; | |
1016 | |
1017 // The test configuration. | |
1018 TestConfig test_config_; | |
1019 | |
1020 // Variables shared by the threads during the whole test. | |
1021 struct { | |
1022 int render_count = 0; | |
1023 int capture_count = 0; | |
1024 } shared_thread_counter_state_ GUARDED_BY(crit_); | |
1025 | |
1026 // Variable shared by the threads during the initialization phase. | |
1027 struct { | |
1028 bool capture_side_called; | |
1029 } shared_thread_init_state_ GUARDED_BY(crit_initial_sync_); | |
1030 | |
1031 // Variables only used on the capture side thread. | |
1032 struct { | |
1033 // Variables related to the capture side audio data and formats. | |
1034 AudioFrame capture_frame; | |
1035 std::vector<float*> capture_output_frame; | |
hlundin-webrtc
2015/10/27 10:54:25
You can make most of the member variable names sho
peah-webrtc
2015/10/29 09:00:09
Done.
| |
1036 std::vector<float> capture_output_frame_channels; | |
1037 AudioProcessing::ChannelLayout capture_output_channel_layout; | |
1038 int capture_input_sample_rate_hz = 16000; | |
1039 int capture_input_number_of_channels; | |
1040 std::vector<float*> capture_input_frame; | |
1041 std::vector<float> capture_input_framechannels_; | |
1042 AudioProcessing::ChannelLayout capture_input_channel_layout; | |
1043 int capture_output_sample_rate_hz = 16000; | |
1044 int capture_output_number_of_channels; | |
1045 StreamConfig capture_input_stream_config; | |
1046 StreamConfig capture_output_stream_config; | |
1047 int capture_input_samples_per_channel; | |
1048 int capture_output_samples_per_channel; | |
1049 } capture_thread_only_state_; | |
hlundin-webrtc
2015/10/27 10:54:24
You can make many lines shorter by abbreviating th
peah-webrtc
2015/10/29 09:00:08
Done.
| |
1050 | |
1051 // Variables only used on the render side thread. | |
1052 struct { | |
1053 bool first_render_side_call_ = true; | |
1054 | |
1055 // Variables related to the render side audio data and formats. | |
1056 AudioFrame render_frame; | |
hlundin-webrtc
2015/10/27 10:54:25
Same as above: drop the render_ prefix.
peah-webrtc
2015/10/29 09:00:08
Done.
| |
1057 std::vector<float*> render_output_frame; | |
1058 std::vector<float> render_output_frame_channels; | |
1059 AudioProcessing::ChannelLayout render_output_channel_layout; | |
1060 int render_input_sample_rate_hz = 16000; | |
1061 int render_input_number_of_channels; | |
1062 std::vector<float*> render_input_frame; | |
1063 std::vector<float> render_input_frame_channels; | |
1064 AudioProcessing::ChannelLayout render_input_channel_layout; | |
1065 int render_output_sample_rate_hz = 16000; | |
1066 int render_output_number_of_channels; | |
1067 StreamConfig render_input_stream_config; | |
1068 StreamConfig render_output_stream_config; | |
1069 int render_input_samples_per_channel; | |
1070 int render_output_samples_per_channel; | |
1071 } render_thread_only_state_; | |
hlundin-webrtc
2015/10/27 10:54:24
Same as above: name it render_state_.
peah-webrtc
2015/10/29 09:00:08
Done.
| |
1072 }; | |
1073 | |
1074 } // anonymous namespace | |
1075 | |
1076 TEST_P(AudioProcessingImpLockTest, LockTest) { | |
1077 // Run test and verify that it did not time out. | |
1078 EXPECT_EQ(kEventSignaled, RunTest()); | |
1079 } | |
1080 | |
1081 // Instantiate tests from the extreme test configuration set. | |
1082 INSTANTIATE_TEST_CASE_P( | |
1083 DISABLED_AudioProcessingImpLockExtensive, | |
1084 AudioProcessingImpLockTest, | |
1085 ::testing::ValuesIn( | |
1086 AudioProcessingImpLockTest::GenerateExtensiveTestConfigs())); | |
1087 | |
1088 INSTANTIATE_TEST_CASE_P( | |
1089 AudioProcessingImpLockBrief, | |
1090 AudioProcessingImpLockTest, | |
1091 ::testing::ValuesIn( | |
1092 AudioProcessingImpLockTest::GenerateBriefTestConfigs())); | |
1093 | |
1094 } // namespace webrtc | |
OLD | NEW |