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/include/event_wrapper.h" | |
23 #include "webrtc/system_wrappers/include/sleep.h" | |
24 #include "webrtc/system_wrappers/include/thread_wrapper.h" | |
25 #include "webrtc/test/random.h" | |
26 | |
27 namespace webrtc { | |
28 | |
29 namespace { | |
30 | |
31 class AudioProcessingImplLockTest; | |
32 | |
33 // Sleeps a random time between 0 and max_sleep milliseconds. | |
34 void SleepRandomMs(int max_sleep, test::Random* rand_gen) { | |
35 int sleeptime = rand_gen->Rand(0, max_sleep); | |
36 SleepMs(sleeptime); | |
37 } | |
38 | |
39 // Populates a float audio frame with random data. | |
40 void PopulateAudioFrame(float** frame, | |
41 float amplitude, | |
42 size_t num_channels, | |
43 size_t samples_per_channel, | |
44 test::Random* rand_gen) { | |
45 for (size_t ch = 0; ch < num_channels; ch++) { | |
46 for (size_t k = 0; k < samples_per_channel; k++) { | |
47 // Store random 16 bit quantized float number between the specified | |
48 // limits. | |
49 frame[ch][k] = amplitude * | |
50 static_cast<float>(rand_gen->Rand(-32767 - 1, 32767)) / | |
51 32768.0f; | |
52 } | |
53 } | |
54 } | |
55 | |
56 // Populates an audioframe frame of AudioFrame type with random data. | |
57 void PopulateAudioFrame(AudioFrame* frame, | |
58 int16_t amplitude, | |
59 test::Random* rand_gen) { | |
60 ASSERT_GT(amplitude, 0); | |
61 ASSERT_LE(amplitude, 32767); | |
62 for (int ch = 0; ch < frame->num_channels_; ch++) { | |
63 for (int k = 0; k < static_cast<int>(frame->samples_per_channel_); k++) { | |
64 // Store random 16 bit quantized float number between -1 and 1. | |
kwiberg-webrtc
2015/11/04 07:08:25
This comment isn't consistent with amplitude being
peah-webrtc
2015/11/04 09:07:15
Done.
| |
65 frame->data_[k * ch] = rand_gen->Rand(-amplitude - 1, amplitude); | |
66 } | |
67 } | |
68 } | |
69 | |
70 // Type of the render thread APM API call to use in the test. | |
71 enum class RenderApiFunctionImplementation { | |
72 ProcessReverseStreamImplementation1, | |
73 ProcessReverseStreamImplementation2, | |
74 AnalyzeReverseStreamImplementation1, | |
75 AnalyzeReverseStreamImplementation2 | |
76 }; | |
kwiberg-webrtc
2015/11/04 07:08:25
Suggestion: "Implementation" -> "Impl" and "Functi
peah-webrtc
2015/11/04 09:07:15
Done.
| |
77 | |
78 // Type of the capture thread APM API call to use in the test. | |
79 enum class CaptureApiFunctionImplementation { | |
80 ProcessStreamImplementation1, | |
81 ProcessStreamImplementation2, | |
82 ProcessStreamImplementation3 | |
83 }; | |
84 | |
85 // The runtime parameter setting scheme to use in the test. | |
86 enum class RuntimeParameterSettingScheme { | |
87 SparseStreamMetadataChangeScheme, | |
88 ExtremeStreamMetadataChangeScheme, | |
89 FixedMonoStreamMetadataScheme, | |
90 FixedStereoStreamMetadataScheme | |
91 }; | |
92 | |
93 // Variant of echo canceller settings to use in the test. | |
94 enum class AecType { | |
95 BasicWebRtcAecSettings, | |
96 AecTurnedOff, | |
97 BasicWebRtcAecSettingsWithExtentedFilter, | |
98 BasicWebRtcAecSettingsWithDelayAgnosticAec, | |
99 BasicWebRtcAecSettingsWithAecMobile | |
100 }; | |
101 | |
102 // Variables related to the audio data and formats. | |
103 struct AudioFrameData { | |
104 explicit AudioFrameData(int max_frame_size) { | |
105 // Set up the two-dimensional arrays needed for the APM API calls. | |
106 input_framechannels.resize(2 * max_frame_size); | |
107 input_frame.resize(2); | |
108 input_frame[0] = &input_framechannels[0]; | |
109 input_frame[1] = &input_framechannels[max_frame_size]; | |
110 | |
111 output_frame_channels.resize(2 * max_frame_size); | |
112 output_frame.resize(2); | |
113 output_frame[0] = &output_frame_channels[0]; | |
114 output_frame[1] = &output_frame_channels[max_frame_size]; | |
115 } | |
116 | |
117 AudioFrame frame; | |
118 std::vector<float*> output_frame; | |
119 std::vector<float> output_frame_channels; | |
120 AudioProcessing::ChannelLayout output_channel_layout; | |
121 int input_sample_rate_hz = 16000; | |
122 int input_number_of_channels; | |
123 std::vector<float*> input_frame; | |
124 std::vector<float> input_framechannels; | |
125 AudioProcessing::ChannelLayout input_channel_layout; | |
126 int output_sample_rate_hz = 16000; | |
127 int output_number_of_channels; | |
128 StreamConfig input_stream_config; | |
129 StreamConfig output_stream_config; | |
130 int input_samples_per_channel; | |
131 int output_samples_per_channel; | |
132 }; | |
133 | |
134 // The configuration for the test to use. | |
kwiberg-webrtc
2015/11/04 07:08:25
Remove "to use".
peah-webrtc
2015/11/04 09:07:15
Done.
| |
135 struct TestConfig { | |
136 // Test case generator for the test configurations to use in the brief tests. | |
137 static std::vector<TestConfig> GenerateBriefTestConfigs() { | |
138 std::vector<TestConfig> test_configs; | |
139 for (int aec = static_cast<int>( | |
140 AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec); | |
141 aec <= static_cast<int>(AecType::BasicWebRtcAecSettingsWithAecMobile); | |
142 aec++) { | |
143 TestConfig test_config; | |
144 | |
145 test_config.min_number_of_calls = 300; | |
146 | |
147 // Perform tests only with the extreme runtime parameter setting scheme. | |
148 test_config.runtime_parameter_setting_scheme = | |
149 RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme; | |
150 | |
151 // Only test 16 kHz for this test suite. | |
152 test_config.initial_sample_rate_hz = 16000; | |
153 | |
154 // Create test config for the second processing API function set. | |
155 test_config.render_api_function = | |
156 RenderApiFunctionImplementation::ProcessReverseStreamImplementation2; | |
157 test_config.capture_api_function = | |
158 CaptureApiFunctionImplementation::ProcessStreamImplementation2; | |
159 | |
160 // Create test config for the first processing API function set. | |
161 test_configs.push_back(test_config); | |
162 test_config.render_api_function = | |
163 RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation2; | |
164 test_config.capture_api_function = | |
165 CaptureApiFunctionImplementation::ProcessStreamImplementation3; | |
166 test_configs.push_back(test_config); | |
167 } | |
168 | |
169 // Return the created test configurations. | |
170 return test_configs; | |
171 } | |
172 | |
173 // Checker for whether the a test configuration is valid. | |
174 static bool ValidTestConfig(const TestConfig& test_config) { | |
175 return ( | |
176 (((test_config.render_api_function == | |
177 RenderApiFunctionImplementation:: | |
178 ProcessReverseStreamImplementation1) || | |
179 (test_config.render_api_function == | |
180 RenderApiFunctionImplementation:: | |
181 AnalyzeReverseStreamImplementation1)) && | |
182 (test_config.capture_api_function == | |
183 CaptureApiFunctionImplementation::ProcessStreamImplementation1)) || | |
184 (((test_config.render_api_function != | |
185 RenderApiFunctionImplementation:: | |
186 ProcessReverseStreamImplementation1) && | |
187 (test_config.render_api_function != | |
188 RenderApiFunctionImplementation:: | |
189 AnalyzeReverseStreamImplementation1)) && | |
190 (test_config.capture_api_function != | |
191 CaptureApiFunctionImplementation::ProcessStreamImplementation1))); | |
192 } | |
193 | |
194 // Test case generator for the test configurations to use in the extensive | |
195 // tests. | |
196 static std::vector<TestConfig> GenerateExtensiveTestConfigs() { | |
197 std::vector<TestConfig> test_configs; | |
198 std::vector<TestConfig> tmp_test_configs; | |
kwiberg-webrtc
2015/11/04 07:08:25
I don't quite get how you use these. You repeatedl
peah-webrtc
2015/11/04 09:07:15
The idea is to use this pattern to achieve a test
kwiberg-webrtc
2015/11/04 09:49:16
OK, I get it now.
Suggestion: Break this into a b
peah-webrtc
2015/11/05 10:10:09
Great suggestion!
Done.
| |
199 | |
200 // Create test configurations for al the render API function | |
201 // implementations. | |
202 for (int render = static_cast<int>(RenderApiFunctionImplementation:: | |
203 ProcessReverseStreamImplementation1); | |
204 render <= static_cast<int>(RenderApiFunctionImplementation:: | |
205 AnalyzeReverseStreamImplementation2); | |
206 render++) { | |
207 TestConfig test_config; | |
208 test_config.render_api_function = | |
209 static_cast<RenderApiFunctionImplementation>(render); | |
210 test_configs.push_back(test_config); | |
211 } | |
212 | |
213 // Set the miminum number of calls for the test configurations. | |
214 for (TestConfig& test_config : test_configs) { | |
215 test_config.min_number_of_calls = 10000; | |
216 } | |
217 | |
218 // Combine the existing set of test configurations with the capture API | |
219 // function implementations. | |
220 tmp_test_configs.swap(test_configs); | |
221 test_configs.clear(); | |
222 for (TestConfig test_config : tmp_test_configs) { | |
223 for (int capture = static_cast<int>( | |
224 CaptureApiFunctionImplementation::ProcessStreamImplementation1); | |
225 capture <= | |
226 static_cast<int>( | |
227 CaptureApiFunctionImplementation::ProcessStreamImplementation3); | |
228 capture++) { | |
229 test_config.capture_api_function = | |
230 static_cast<CaptureApiFunctionImplementation>(capture); | |
231 test_configs.push_back(test_config); | |
232 } | |
233 } | |
234 | |
235 // Combine the existing set of test configurations with the AEC | |
236 // configurations. | |
237 tmp_test_configs.swap(test_configs); | |
238 test_configs.clear(); | |
239 for (TestConfig test_config : tmp_test_configs) { | |
240 for (int aec = static_cast<int>(AecType::BasicWebRtcAecSettings); | |
241 aec <= | |
242 static_cast<int>(AecType::BasicWebRtcAecSettingsWithAecMobile); | |
243 aec++) { | |
244 test_config.aec_type = static_cast<AecType>(aec); | |
245 test_configs.push_back(test_config); | |
246 } | |
247 } | |
248 | |
249 // Combine the existing set of test configurations with the parameter | |
250 // setting schemes. | |
251 tmp_test_configs.swap(test_configs); | |
252 test_configs.clear(); | |
253 for (TestConfig test_config : tmp_test_configs) { | |
254 for (int scheme = static_cast<int>( | |
255 RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme); | |
256 scheme <= | |
257 static_cast<int>( | |
258 RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme); | |
259 scheme++) { | |
260 // Only produce test configs with compatible render and capture API | |
261 // calls. | |
262 if (ValidTestConfig(test_config)) { | |
263 // Add test configs with different initial sample rates and | |
264 // parameter setting schemes. | |
265 test_config.runtime_parameter_setting_scheme = | |
266 static_cast<RuntimeParameterSettingScheme>(scheme); | |
267 test_configs.push_back(test_config); | |
268 } | |
269 } | |
270 } | |
271 | |
272 // Replicate the test configurations for all possible initial sample rates. | |
273 tmp_test_configs.swap(test_configs); | |
274 test_configs.clear(); | |
275 for (TestConfig test_config : tmp_test_configs) { | |
276 test_config.initial_sample_rate_hz = 8000; | |
277 test_configs.push_back(test_config); | |
278 | |
279 test_config.initial_sample_rate_hz = 16000; | |
280 test_configs.push_back(test_config); | |
281 | |
282 if (test_config.aec_type != | |
283 AecType::BasicWebRtcAecSettingsWithAecMobile) { | |
284 test_config.initial_sample_rate_hz = 32000; | |
285 test_configs.push_back(test_config); | |
286 | |
287 test_config.initial_sample_rate_hz = 48000; | |
288 test_configs.push_back(test_config); | |
289 } | |
290 | |
291 test_config.initial_sample_rate_hz = 8000; | |
292 test_configs.push_back(test_config); | |
293 | |
294 test_config.initial_sample_rate_hz = 16000; | |
295 test_configs.push_back(test_config); | |
296 } | |
297 | |
298 // Return the created test configurations. | |
299 return test_configs; | |
300 } | |
301 | |
302 RenderApiFunctionImplementation render_api_function; | |
303 CaptureApiFunctionImplementation capture_api_function; | |
304 RuntimeParameterSettingScheme runtime_parameter_setting_scheme; | |
305 int initial_sample_rate_hz; | |
306 AecType aec_type; | |
307 int min_number_of_calls; | |
308 }; | |
309 | |
310 // Handler for the frame counters. | |
311 class FrameCounter { | |
kwiberg-webrtc
2015/11/04 07:08:25
Nit: plural?
peah-webrtc
2015/11/04 09:07:15
Done.
| |
312 public: | |
313 void IncreaseRenderCounter() { | |
314 rtc::CritScope cs(&crit_); | |
315 render_count++; | |
316 } | |
317 | |
318 void IncreaseCaptureCounter() { | |
319 rtc::CritScope cs(&crit_); | |
320 capture_count++; | |
321 } | |
322 | |
323 int GetCaptureCounter() { | |
324 rtc::CritScope cs(&crit_); | |
325 return capture_count; | |
326 } | |
327 | |
328 int GetRenderCounter() { | |
329 rtc::CritScope cs(&crit_); | |
330 return capture_count; | |
331 } | |
332 | |
333 int CaptureMinusRenderCounters() { | |
334 rtc::CritScope cs(&crit_); | |
335 return capture_count - render_count; | |
336 } | |
337 | |
338 bool BothCountersExceedeThreshold(int threshold) { | |
339 rtc::CritScope cs(&crit_); | |
340 return (render_count > threshold && capture_count > threshold); | |
341 } | |
342 | |
343 private: | |
344 rtc::CriticalSection crit_; | |
345 int render_count GUARDED_BY(crit_) = 0; | |
346 int capture_count GUARDED_BY(crit_) = 0; | |
347 }; | |
348 | |
349 // Checker for whether the capture side has been called. | |
350 class CaptureSideCalledChecker { | |
351 public: | |
352 bool CaptureSideCalled() { | |
353 rtc::CritScope cs(&crit_); | |
354 return capture_side_called_; | |
355 } | |
356 | |
357 void FlagCaptureSideCalled() { | |
358 rtc::CritScope cs(&crit_); | |
359 capture_side_called_ = true; | |
360 } | |
361 | |
362 private: | |
363 rtc::CriticalSection crit_; | |
364 bool capture_side_called_ GUARDED_BY(crit_) = false; | |
365 }; | |
366 | |
367 // Class for handling the capture side processing. | |
368 class CaptureProcessor { | |
369 public: | |
370 CaptureProcessor(int max_frame_size, | |
371 test::Random* rand_gen, | |
372 FrameCounter* shared_thread_counter_state, | |
373 CaptureSideCalledChecker* capture_call_checker, | |
374 AudioProcessingImplLockTest* test_framework, | |
375 TestConfig* test_config, | |
376 AudioProcessing* apm); | |
377 | |
378 bool Process(); | |
379 | |
380 private: | |
381 static const int kMaxCallDifference = 10; | |
382 static const float kCaptureInputFloatLevel; | |
383 static const int kCaptureInputFixLevel = 1024; | |
384 | |
385 void CallApmCaptureSide(); | |
386 void PrepareFrame(); | |
387 void ApplyRuntimeSettingScheme(); | |
388 | |
389 test::Random* rand_gen_; | |
390 FrameCounter* frame_counter_; | |
391 CaptureSideCalledChecker* capture_call_checker_; | |
392 AudioProcessingImplLockTest* test_; | |
393 TestConfig* test_config_; | |
394 AudioProcessing* apm_; | |
395 AudioFrameData frame_data_; | |
396 }; | |
397 | |
398 // Class for handling the stats processing. | |
399 class StatsProcessor { | |
400 public: | |
401 StatsProcessor(test::Random* rand_gen, | |
402 TestConfig* test_config, | |
403 AudioProcessing* apm); | |
404 | |
405 bool Process(); | |
406 | |
407 private: | |
408 test::Random* rand_gen_; | |
409 TestConfig* test_config_; | |
410 AudioProcessing* apm_; | |
411 }; | |
412 | |
413 // Class for handling the render side processing. | |
414 class RenderProcessor { | |
415 public: | |
416 RenderProcessor(int max_frame_size, | |
417 test::Random* rand_gen, | |
418 FrameCounter* shared_thread_counter_state, | |
419 CaptureSideCalledChecker* capture_call_checker, | |
420 AudioProcessingImplLockTest* test_framework, | |
421 TestConfig* test_config, | |
422 AudioProcessing* apm); | |
423 | |
424 bool Process(); | |
425 | |
426 private: | |
427 static const int kMaxCallDifference = 10; | |
428 static const int kRenderInputFixLevel = 16384; | |
429 static const float kRenderInputFloatLevel; | |
430 | |
431 void CallApmRenderSide(); | |
432 void ApplyRuntimeSettingScheme(); | |
433 void PrepareFrame(); | |
434 | |
435 test::Random* rand_gen_; | |
436 FrameCounter* frame_counter_; | |
437 CaptureSideCalledChecker* capture_call_checker_; | |
438 AudioProcessingImplLockTest* test_; | |
439 TestConfig* test_config_; | |
440 AudioProcessing* apm_; | |
441 bool first_render_side_call_ = true; | |
442 AudioFrameData frame_data_; | |
443 }; | |
444 | |
445 // Class for implementing the tests of the locks in the audio processing module. | |
446 class AudioProcessingImplLockTest | |
447 : public ::testing::TestWithParam<TestConfig> { | |
448 public: | |
449 AudioProcessingImplLockTest(); | |
450 EventTypeWrapper RunTest(); | |
451 void SetUp() override; | |
452 void TearDown() override; | |
453 void CheckTestCompleteness(); | |
454 | |
455 private: | |
456 static const int kTestTimeOutLimit = 10 * 60 * 1000; | |
457 static const int kMaxFrameSize = 480; | |
458 | |
459 // Thread callback for the render thread | |
460 static bool RenderProcessorCallback(void* context) { | |
461 return reinterpret_cast<AudioProcessingImplLockTest*>(context) | |
462 ->render_thread_state_.Process(); | |
463 } | |
464 | |
465 // Thread callback for the capture thread | |
466 static bool CaptureProcessorCallback(void* context) { | |
467 return reinterpret_cast<AudioProcessingImplLockTest*>(context) | |
468 ->capture_thread_state_.Process(); | |
469 } | |
470 | |
471 // Thread callback for the stats thread | |
472 static bool StatsProcessorCallback(void* context) { | |
473 return reinterpret_cast<AudioProcessingImplLockTest*>(context) | |
474 ->stats_thread_state_.Process(); | |
475 } | |
476 | |
477 // Tests whether all the required render and capture side calls have been | |
478 // done. | |
479 bool TestDone() { | |
480 return frame_counter_.BothCountersExceedeThreshold( | |
481 test_config_.min_number_of_calls); | |
482 } | |
483 | |
484 // Start the threads used in the test. | |
485 void StartThreads() { | |
486 ASSERT_TRUE(render_thread_->Start()); | |
487 render_thread_->SetPriority(kRealtimePriority); | |
488 ASSERT_TRUE(capture_thread_->Start()); | |
489 capture_thread_->SetPriority(kRealtimePriority); | |
490 ASSERT_TRUE(stats_thread_->Start()); | |
491 stats_thread_->SetPriority(kNormalPriority); | |
492 } | |
493 | |
494 // Event handler for the test. | |
495 const rtc::scoped_ptr<EventWrapper> test_complete_; | |
496 | |
497 // Thread related variables. | |
498 rtc::scoped_ptr<ThreadWrapper> render_thread_; | |
499 rtc::scoped_ptr<ThreadWrapper> capture_thread_; | |
500 rtc::scoped_ptr<ThreadWrapper> stats_thread_; | |
501 mutable test::Random rand_gen_; | |
502 | |
503 rtc::scoped_ptr<AudioProcessing> apm_; | |
504 TestConfig test_config_; | |
505 FrameCounter frame_counter_; | |
506 CaptureSideCalledChecker capture_call_checker_; | |
507 RenderProcessor render_thread_state_; | |
508 CaptureProcessor capture_thread_state_; | |
509 StatsProcessor stats_thread_state_; | |
510 }; | |
511 | |
512 AudioProcessingImplLockTest::AudioProcessingImplLockTest() | |
513 : test_complete_(EventWrapper::Create()), | |
514 render_thread_( | |
515 ThreadWrapper::CreateThread(RenderProcessorCallback, this, "render")), | |
516 capture_thread_(ThreadWrapper::CreateThread(CaptureProcessorCallback, | |
517 this, | |
518 "capture")), | |
519 stats_thread_( | |
520 ThreadWrapper::CreateThread(StatsProcessorCallback, this, "stats")), | |
521 rand_gen_(42U), | |
522 apm_(AudioProcessingImpl::Create()), | |
523 render_thread_state_(kMaxFrameSize, | |
524 &rand_gen_, | |
525 &frame_counter_, | |
526 &capture_call_checker_, | |
527 this, | |
528 &test_config_, | |
529 apm_.get()), | |
530 capture_thread_state_(kMaxFrameSize, | |
531 &rand_gen_, | |
532 &frame_counter_, | |
533 &capture_call_checker_, | |
534 this, | |
535 &test_config_, | |
536 apm_.get()), | |
537 stats_thread_state_(&rand_gen_, &test_config_, apm_.get()) {} | |
538 | |
539 // Run the test with a timeout. | |
540 EventTypeWrapper AudioProcessingImplLockTest::RunTest() { | |
541 StartThreads(); | |
542 return test_complete_->Wait(kTestTimeOutLimit); | |
543 } | |
544 | |
545 // Setup of test and APM. | |
546 void AudioProcessingImplLockTest::SetUp() { | |
547 // apm_.reset(AudioProcessingImpl::Create()); | |
548 test_config_ = static_cast<TestConfig>(GetParam()); | |
549 | |
550 ASSERT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true)); | |
551 ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true)); | |
552 | |
553 ASSERT_EQ(apm_->kNoError, | |
554 apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog)); | |
555 ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true)); | |
556 ASSERT_EQ(apm_->kNoError, | |
557 apm_->gain_control()->set_mode(GainControl::kFixedDigital)); | |
kwiberg-webrtc
2015/11/04 07:08:25
You enable gain control twice, each time setting a
peah-webrtc
2015/11/04 09:07:15
Good catch!
I'll remove setting the digital mode,
| |
558 | |
559 ASSERT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true)); | |
560 ASSERT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true)); | |
561 | |
562 Config config; | |
563 if (test_config_.aec_type == AecType::AecTurnedOff) { | |
564 ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false)); | |
565 ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false)); | |
566 } else { | |
567 if (test_config_.aec_type == AecType::BasicWebRtcAecSettingsWithAecMobile) { | |
kwiberg-webrtc
2015/11/04 07:08:25
if (a) {
...
} else {
if (b) {
...
} els
peah-webrtc
2015/11/04 09:07:15
Done.
| |
568 ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true)); | |
569 ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false)); | |
570 } else { | |
571 ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false)); | |
572 ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true)); | |
573 ASSERT_EQ(apm_->kNoError, | |
574 apm_->echo_cancellation()->enable_metrics(true)); | |
575 ASSERT_EQ(apm_->kNoError, | |
576 apm_->echo_cancellation()->enable_delay_logging(true)); | |
577 | |
578 config.Set<ExtendedFilter>(new ExtendedFilter( | |
579 test_config_.aec_type == | |
580 AecType::BasicWebRtcAecSettingsWithExtentedFilter)); | |
581 | |
582 config.Set<DelayAgnostic>(new DelayAgnostic( | |
583 test_config_.aec_type == | |
584 AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec)); | |
585 | |
586 apm_->SetExtraOptions(config); | |
587 } | |
588 } | |
589 } | |
590 | |
591 void AudioProcessingImplLockTest::TearDown() { | |
592 render_thread_->Stop(); | |
593 capture_thread_->Stop(); | |
594 stats_thread_->Stop(); | |
595 } | |
596 | |
597 StatsProcessor::StatsProcessor(test::Random* rand_gen, | |
598 TestConfig* test_config, | |
599 AudioProcessing* apm) | |
600 : rand_gen_(rand_gen), test_config_(test_config), apm_(apm) {} | |
601 | |
602 // Implements the callback functionality for the statistics | |
603 // collection thread. | |
604 bool StatsProcessor::Process() { | |
605 SleepRandomMs(100, rand_gen_); | |
606 | |
607 EXPECT_EQ(apm_->echo_cancellation()->is_enabled(), | |
608 ((test_config_->aec_type != AecType::AecTurnedOff) && | |
609 (test_config_->aec_type != | |
610 AecType::BasicWebRtcAecSettingsWithAecMobile))); | |
611 apm_->echo_cancellation()->stream_drift_samples(); | |
612 EXPECT_EQ(apm_->echo_control_mobile()->is_enabled(), | |
613 (test_config_->aec_type != AecType::AecTurnedOff) && | |
614 (test_config_->aec_type == | |
615 AecType::BasicWebRtcAecSettingsWithAecMobile)); | |
616 EXPECT_TRUE(apm_->gain_control()->is_enabled()); | |
617 apm_->gain_control()->stream_analog_level(); | |
618 EXPECT_TRUE(apm_->noise_suppression()->is_enabled()); | |
619 float speech_probablitity = apm_->noise_suppression()->speech_probability(); | |
620 EXPECT_TRUE(speech_probablitity < (apm_->kUnsupportedFunctionError + 0.5f) || | |
621 speech_probablitity >= 0); | |
622 apm_->voice_detection()->is_enabled(); | |
623 | |
624 return true; | |
625 } | |
626 | |
627 const float CaptureProcessor::kCaptureInputFloatLevel = 0.03125f; | |
628 | |
629 // Applies the capture side processing API call. | |
630 void CaptureProcessor::CallApmCaptureSide() { | |
631 // Prepare a proper capture side processing API call input. | |
632 PrepareFrame(); | |
633 | |
634 // Set the stream delay | |
635 apm_->set_stream_delay_ms(30); | |
636 | |
637 // Call the specified capture side API processing method. | |
638 int result = AudioProcessing::kNoError; | |
639 switch (test_config_->capture_api_function) { | |
640 case CaptureApiFunctionImplementation::ProcessStreamImplementation1: | |
641 result = apm_->ProcessStream(&frame_data_.frame); | |
642 break; | |
643 case CaptureApiFunctionImplementation::ProcessStreamImplementation2: | |
644 result = apm_->ProcessStream( | |
645 &frame_data_.input_frame[0], frame_data_.input_samples_per_channel, | |
646 frame_data_.input_sample_rate_hz, frame_data_.input_channel_layout, | |
647 frame_data_.output_sample_rate_hz, frame_data_.output_channel_layout, | |
648 &frame_data_.output_frame[0]); | |
649 break; | |
650 case CaptureApiFunctionImplementation::ProcessStreamImplementation3: | |
651 result = apm_->ProcessStream( | |
652 &frame_data_.input_frame[0], frame_data_.input_stream_config, | |
653 frame_data_.output_stream_config, &frame_data_.output_frame[0]); | |
654 break; | |
655 default: | |
656 assert(false); | |
657 } | |
658 | |
659 // Check the return code for error. | |
660 ASSERT_EQ(AudioProcessing::kNoError, result); | |
661 } | |
662 | |
663 // Applies any runtime capture APM API calls and audio stream characteristics | |
664 // specified by the scheme for the test. | |
665 void CaptureProcessor::ApplyRuntimeSettingScheme() { | |
666 const int capture_count_local = frame_counter_->GetCaptureCounter(); | |
667 | |
668 // Update the number of channels and sample rates for the input and output. | |
669 // Note that the counts frequencies for when to set parameters | |
670 // are set using prime numbers in order to ensure that the | |
671 // permutation scheme in the parameter setting changes. | |
672 switch (test_config_->runtime_parameter_setting_scheme) { | |
673 case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: | |
674 if (capture_count_local == 0) | |
675 frame_data_.input_sample_rate_hz = 16000; | |
676 else if (capture_count_local % 11 == 0) | |
677 frame_data_.input_sample_rate_hz = 32000; | |
678 else if (capture_count_local % 73 == 0) | |
679 frame_data_.input_sample_rate_hz = 48000; | |
680 else if (capture_count_local % 89 == 0) | |
681 frame_data_.input_sample_rate_hz = 16000; | |
682 else if (capture_count_local % 97 == 0) | |
683 frame_data_.input_sample_rate_hz = 8000; | |
684 | |
685 if (capture_count_local == 0) | |
686 frame_data_.input_number_of_channels = 1; | |
687 else if (capture_count_local % 4 == 0) | |
688 frame_data_.input_number_of_channels = | |
689 (frame_data_.input_number_of_channels == 1 ? 2 : 1); | |
690 | |
691 if (capture_count_local == 0) | |
692 frame_data_.output_sample_rate_hz = 16000; | |
693 else if (capture_count_local % 5 == 0) | |
694 frame_data_.output_sample_rate_hz = 32000; | |
695 else if (capture_count_local % 47 == 0) | |
696 frame_data_.output_sample_rate_hz = 48000; | |
697 else if (capture_count_local % 53 == 0) | |
698 frame_data_.output_sample_rate_hz = 16000; | |
699 else if (capture_count_local % 71 == 0) | |
700 frame_data_.output_sample_rate_hz = 8000; | |
701 | |
702 if (capture_count_local == 0) | |
703 frame_data_.output_number_of_channels = 1; | |
704 else if (capture_count_local % 8 == 0) | |
705 frame_data_.output_number_of_channels = | |
706 (frame_data_.output_number_of_channels == 1 ? 2 : 1); | |
707 break; | |
708 case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: | |
709 if (capture_count_local % 2 == 0) { | |
710 frame_data_.input_number_of_channels = 1; | |
711 frame_data_.input_sample_rate_hz = 16000; | |
712 frame_data_.output_number_of_channels = 1; | |
713 frame_data_.output_sample_rate_hz = 16000; | |
714 } else { | |
715 frame_data_.input_number_of_channels = | |
716 (frame_data_.input_number_of_channels == 1 ? 2 : 1); | |
717 if (frame_data_.input_sample_rate_hz == 8000) | |
718 frame_data_.input_sample_rate_hz = 16000; | |
719 else if (frame_data_.input_sample_rate_hz == 16000) | |
720 frame_data_.input_sample_rate_hz = 32000; | |
721 else if (frame_data_.input_sample_rate_hz == 32000) | |
722 frame_data_.input_sample_rate_hz = 48000; | |
723 else if (frame_data_.input_sample_rate_hz == 48000) | |
724 frame_data_.input_sample_rate_hz = 8000; | |
725 | |
726 frame_data_.output_number_of_channels = | |
727 (frame_data_.output_number_of_channels == 1 ? 2 : 1); | |
728 if (frame_data_.output_sample_rate_hz == 8000) | |
729 frame_data_.output_sample_rate_hz = 16000; | |
730 else if (frame_data_.output_sample_rate_hz == 16000) | |
731 frame_data_.output_sample_rate_hz = 32000; | |
732 else if (frame_data_.output_sample_rate_hz == 32000) | |
733 frame_data_.output_sample_rate_hz = 48000; | |
734 else if (frame_data_.output_sample_rate_hz == 48000) | |
735 frame_data_.output_sample_rate_hz = 8000; | |
736 } | |
737 break; | |
738 case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: | |
739 if (capture_count_local == 0) { | |
740 frame_data_.input_sample_rate_hz = 16000; | |
741 frame_data_.input_number_of_channels = 1; | |
742 frame_data_.output_sample_rate_hz = 16000; | |
743 frame_data_.output_number_of_channels = 1; | |
744 } | |
745 break; | |
746 case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: | |
747 if (capture_count_local == 0) { | |
748 frame_data_.input_sample_rate_hz = 16000; | |
749 frame_data_.input_number_of_channels = 2; | |
750 frame_data_.output_sample_rate_hz = 16000; | |
751 frame_data_.output_number_of_channels = 2; | |
752 } | |
753 | |
754 break; | |
755 default: | |
756 assert(false); | |
757 } | |
758 | |
759 // Call any specified runtime APM setter and | |
760 // getter calls. | |
761 switch (test_config_->runtime_parameter_setting_scheme) { | |
762 case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: | |
763 case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: | |
764 break; | |
765 case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: | |
766 case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: | |
767 if ((capture_count_local % 2) == 0) { | |
kwiberg-webrtc
2015/11/04 07:08:25
Nit: use fewer parentheses.
peah-webrtc
2015/11/04 09:07:15
Done.
| |
768 ASSERT_EQ(AudioProcessing::Error::kNoError, | |
769 apm_->set_stream_delay_ms(30)); | |
770 apm_->set_stream_key_pressed(true); | |
771 apm_->set_output_will_be_muted(true); | |
772 apm_->set_delay_offset_ms(15); | |
773 EXPECT_EQ(apm_->delay_offset_ms(), 15); | |
774 EXPECT_GE(apm_->num_reverse_channels(), 0); | |
775 EXPECT_LE(apm_->num_reverse_channels(), 2); | |
776 } else { | |
777 ASSERT_EQ(AudioProcessing::Error::kNoError, | |
778 apm_->set_stream_delay_ms(50)); | |
779 apm_->set_stream_key_pressed(false); | |
780 apm_->set_output_will_be_muted(false); | |
781 apm_->set_delay_offset_ms(20); | |
782 EXPECT_EQ(apm_->delay_offset_ms(), 20); | |
783 apm_->delay_offset_ms(); | |
784 apm_->num_reverse_channels(); | |
785 EXPECT_GE(apm_->num_reverse_channels(), 0); | |
786 EXPECT_LE(apm_->num_reverse_channels(), 2); | |
787 } | |
788 break; | |
789 default: | |
790 FAIL(); | |
791 } | |
792 | |
793 // Restric the number of output channels not to exceed | |
794 // the number of input channels. | |
795 frame_data_.output_number_of_channels = | |
796 std::min(frame_data_.output_number_of_channels, | |
797 frame_data_.input_number_of_channels); | |
798 } | |
799 | |
800 // Prepares a frame with relevant audio data and metadata. | |
801 void CaptureProcessor::PrepareFrame() { | |
802 // Restrict to a common fixed sample rate if the AudioFrame | |
803 // interface is used. | |
804 if (test_config_->capture_api_function == | |
805 CaptureApiFunctionImplementation::ProcessStreamImplementation1) { | |
806 frame_data_.input_sample_rate_hz = test_config_->initial_sample_rate_hz; | |
807 frame_data_.output_sample_rate_hz = test_config_->initial_sample_rate_hz; | |
808 } | |
809 | |
810 // Prepare the audioframe data and metadata. | |
811 frame_data_.input_samples_per_channel = | |
812 frame_data_.input_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; | |
813 frame_data_.frame.sample_rate_hz_ = frame_data_.input_sample_rate_hz; | |
814 frame_data_.frame.num_channels_ = frame_data_.input_number_of_channels; | |
815 frame_data_.frame.samples_per_channel_ = | |
816 frame_data_.input_samples_per_channel; | |
817 memset(frame_data_.frame.data_, 0, frame_data_.input_samples_per_channel * | |
818 sizeof(frame_data_.frame.data_[0])); | |
819 PopulateAudioFrame(&frame_data_.frame, kCaptureInputFixLevel, rand_gen_); | |
820 | |
821 // Prepare the float audio input data and metadata. | |
822 frame_data_.input_stream_config.set_sample_rate_hz( | |
823 frame_data_.input_sample_rate_hz); | |
824 frame_data_.input_stream_config.set_num_channels( | |
825 frame_data_.input_number_of_channels); | |
826 frame_data_.input_stream_config.set_has_keyboard(false); | |
827 PopulateAudioFrame(&frame_data_.input_frame[0], kCaptureInputFloatLevel, | |
828 frame_data_.input_number_of_channels, | |
829 frame_data_.input_samples_per_channel, rand_gen_); | |
830 frame_data_.input_channel_layout = | |
831 (frame_data_.input_number_of_channels == 1 | |
832 ? AudioProcessing::ChannelLayout::kMonoAndKeyboard | |
833 : AudioProcessing::ChannelLayout::kStereoAndKeyboard); | |
834 | |
835 // Prepare the float audio output data and metadata. | |
836 frame_data_.output_samples_per_channel = | |
837 frame_data_.output_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; | |
838 frame_data_.output_stream_config.set_sample_rate_hz( | |
839 frame_data_.output_sample_rate_hz); | |
840 frame_data_.output_stream_config.set_num_channels( | |
841 frame_data_.output_number_of_channels); | |
842 frame_data_.output_stream_config.set_has_keyboard(false); | |
843 frame_data_.output_channel_layout = | |
844 (frame_data_.output_number_of_channels == 1 | |
845 ? AudioProcessing::ChannelLayout::kMono | |
846 : AudioProcessing::ChannelLayout::kStereo); | |
847 } | |
848 | |
849 // Implements the callback functionality for the capture thread. | |
850 bool CaptureProcessor::Process() { | |
851 // Sleep a random time to simulate thread jitter. | |
852 SleepRandomMs(3, rand_gen_); | |
853 | |
854 // End the test is complete. | |
855 test_->CheckTestCompleteness(); | |
856 | |
857 // Ensure that there are not more capture side calls than render side | |
858 // calls. | |
859 if (capture_call_checker_->CaptureSideCalled()) { | |
860 while (kMaxCallDifference < frame_counter_->CaptureMinusRenderCounters()) { | |
861 SleepMs(1); | |
862 } | |
863 } | |
864 | |
865 // Apply any specified capture side APM non-processing runtime calls. | |
866 ApplyRuntimeSettingScheme(); | |
867 | |
868 // Apply the capture side processing call. | |
869 CallApmCaptureSide(); | |
870 | |
871 // Increase the number of capture-side calls. | |
872 frame_counter_->IncreaseCaptureCounter(); | |
873 | |
874 // Flag that the capture side has been called at least once | |
875 // (needed to ensure that a capture call has been done | |
876 // before the first render call is performed (implicitly | |
877 // required by the APM API). | |
878 capture_call_checker_->FlagCaptureSideCalled(); | |
879 | |
880 return true; | |
881 } | |
882 | |
883 CaptureProcessor::CaptureProcessor( | |
884 int max_frame_size, | |
885 test::Random* rand_gen, | |
886 FrameCounter* shared_thread_counter_state, | |
887 CaptureSideCalledChecker* capture_call_checker, | |
888 AudioProcessingImplLockTest* test_framework, | |
889 TestConfig* test_config, | |
890 AudioProcessing* apm) | |
891 : rand_gen_(rand_gen), | |
892 frame_counter_(shared_thread_counter_state), | |
893 capture_call_checker_(capture_call_checker), | |
894 test_(test_framework), | |
895 test_config_(test_config), | |
896 apm_(apm), | |
897 frame_data_(max_frame_size) {} | |
898 | |
899 const float RenderProcessor::kRenderInputFloatLevel = 0.5f; | |
900 | |
901 RenderProcessor::RenderProcessor(int max_frame_size, | |
902 test::Random* rand_gen, | |
903 FrameCounter* shared_thread_counter_state, | |
904 CaptureSideCalledChecker* capture_call_checker, | |
905 AudioProcessingImplLockTest* test_framework, | |
906 TestConfig* test_config, | |
907 AudioProcessing* apm) | |
908 : rand_gen_(rand_gen), | |
909 frame_counter_(shared_thread_counter_state), | |
910 capture_call_checker_(capture_call_checker), | |
911 test_(test_framework), | |
912 test_config_(test_config), | |
913 apm_(apm), | |
914 frame_data_(max_frame_size) {} | |
915 | |
916 // Prepares the render side frame and the accompanying metadata | |
917 // with the appropriate information. | |
918 void RenderProcessor::PrepareFrame() { | |
919 // Restrict to a common fixed sample rate if the AudioFrame interface is | |
920 // used. | |
921 if ((test_config_->render_api_function == | |
922 RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation1) || | |
923 (test_config_->render_api_function == | |
924 RenderApiFunctionImplementation::ProcessReverseStreamImplementation1) || | |
925 (test_config_->aec_type != | |
926 AecType::BasicWebRtcAecSettingsWithAecMobile)) { | |
927 frame_data_.input_sample_rate_hz = test_config_->initial_sample_rate_hz; | |
928 frame_data_.output_sample_rate_hz = test_config_->initial_sample_rate_hz; | |
929 } | |
930 | |
931 // Prepare the audioframe data and metadata | |
932 frame_data_.input_samples_per_channel = | |
933 frame_data_.input_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; | |
934 frame_data_.frame.sample_rate_hz_ = frame_data_.input_sample_rate_hz; | |
935 frame_data_.frame.num_channels_ = frame_data_.input_number_of_channels; | |
936 frame_data_.frame.samples_per_channel_ = | |
937 frame_data_.input_samples_per_channel; | |
938 memset(frame_data_.frame.data_, 0, frame_data_.input_samples_per_channel * | |
939 sizeof(frame_data_.frame.data_[0])); | |
940 PopulateAudioFrame(&frame_data_.frame, kRenderInputFixLevel, rand_gen_); | |
941 | |
942 // Prepare the float audio input data and metadata. | |
943 frame_data_.input_stream_config.set_sample_rate_hz( | |
944 frame_data_.input_sample_rate_hz); | |
945 frame_data_.input_stream_config.set_num_channels( | |
946 frame_data_.input_number_of_channels); | |
947 frame_data_.input_stream_config.set_has_keyboard(false); | |
948 PopulateAudioFrame(&frame_data_.input_frame[0], kRenderInputFloatLevel, | |
949 frame_data_.input_number_of_channels, | |
950 frame_data_.input_samples_per_channel, rand_gen_); | |
951 frame_data_.input_channel_layout = | |
952 (frame_data_.input_number_of_channels == 1 | |
953 ? AudioProcessing::ChannelLayout::kMono | |
954 : AudioProcessing::ChannelLayout::kStereo); | |
955 | |
956 // Prepare the float audio output data and metadata. | |
957 frame_data_.output_samples_per_channel = | |
958 frame_data_.output_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; | |
959 frame_data_.output_stream_config.set_sample_rate_hz( | |
960 frame_data_.output_sample_rate_hz); | |
961 frame_data_.output_stream_config.set_num_channels( | |
962 frame_data_.output_number_of_channels); | |
963 frame_data_.output_stream_config.set_has_keyboard(false); | |
964 frame_data_.output_channel_layout = | |
965 (frame_data_.output_number_of_channels == 1 | |
966 ? AudioProcessing::ChannelLayout::kMono | |
967 : AudioProcessing::ChannelLayout::kStereo); | |
968 } | |
969 | |
970 // Makes the render side processing API call. | |
971 void RenderProcessor::CallApmRenderSide() { | |
972 // Prepare a proper render side processing API call input. | |
973 PrepareFrame(); | |
974 | |
975 // Call the specified render side API processing method. | |
976 int result = AudioProcessing::kNoError; | |
977 switch (test_config_->render_api_function) { | |
978 case RenderApiFunctionImplementation::ProcessReverseStreamImplementation1: | |
979 result = apm_->ProcessReverseStream(&frame_data_.frame); | |
980 break; | |
981 case RenderApiFunctionImplementation::ProcessReverseStreamImplementation2: | |
982 result = apm_->ProcessReverseStream( | |
983 &frame_data_.input_frame[0], frame_data_.input_stream_config, | |
984 frame_data_.output_stream_config, &frame_data_.output_frame[0]); | |
985 break; | |
986 case RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation1: | |
987 result = apm_->AnalyzeReverseStream(&frame_data_.frame); | |
988 break; | |
989 case RenderApiFunctionImplementation::AnalyzeReverseStreamImplementation2: | |
990 result = apm_->AnalyzeReverseStream( | |
991 &frame_data_.input_frame[0], frame_data_.input_samples_per_channel, | |
992 frame_data_.input_sample_rate_hz, frame_data_.input_channel_layout); | |
993 break; | |
994 default: | |
995 assert(false); | |
996 } | |
997 | |
998 // Check the return code for error. | |
999 ASSERT_EQ(AudioProcessing::kNoError, result); | |
1000 } | |
1001 | |
1002 // Applies any render capture side APM API calls and audio stream | |
1003 // characteristics | |
1004 // specified by the scheme for the test. | |
1005 void RenderProcessor::ApplyRuntimeSettingScheme() { | |
1006 const int render_count_local = frame_counter_->GetRenderCounter(); | |
1007 | |
1008 // Update the number of channels and sample rates for the input and output. | |
1009 // Note that the counts frequencies for when to set parameters | |
1010 // are set using prime numbers in order to ensure that the | |
1011 // permutation scheme in the parameter setting changes. | |
1012 switch (test_config_->runtime_parameter_setting_scheme) { | |
1013 case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: | |
1014 if (render_count_local == 0) | |
1015 frame_data_.input_sample_rate_hz = 16000; | |
1016 else if (render_count_local % 47 == 0) | |
1017 frame_data_.input_sample_rate_hz = 32000; | |
1018 else if (render_count_local % 71 == 0) | |
1019 frame_data_.input_sample_rate_hz = 48000; | |
1020 else if (render_count_local % 79 == 0) | |
1021 frame_data_.input_sample_rate_hz = 16000; | |
1022 else if (render_count_local % 83 == 0) | |
1023 frame_data_.input_sample_rate_hz = 8000; | |
1024 | |
1025 if (render_count_local == 0) | |
1026 frame_data_.input_number_of_channels = 1; | |
1027 else if (render_count_local % 4 == 0) | |
1028 frame_data_.input_number_of_channels = | |
1029 (frame_data_.input_number_of_channels == 1 ? 2 : 1); | |
1030 | |
1031 if (render_count_local == 0) | |
1032 frame_data_.output_sample_rate_hz = 16000; | |
1033 else if (render_count_local % 17 == 0) | |
1034 frame_data_.output_sample_rate_hz = 32000; | |
1035 else if (render_count_local % 19 == 0) | |
1036 frame_data_.output_sample_rate_hz = 48000; | |
1037 else if (render_count_local % 29 == 0) | |
1038 frame_data_.output_sample_rate_hz = 16000; | |
1039 else if (render_count_local % 61 == 0) | |
1040 frame_data_.output_sample_rate_hz = 8000; | |
1041 | |
1042 if (render_count_local == 0) | |
1043 frame_data_.output_number_of_channels = 1; | |
1044 else if (render_count_local % 8 == 0) | |
1045 frame_data_.output_number_of_channels = | |
1046 (frame_data_.output_number_of_channels == 1 ? 2 : 1); | |
1047 break; | |
1048 case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: | |
1049 if (render_count_local == 0) { | |
1050 frame_data_.input_number_of_channels = 1; | |
1051 frame_data_.input_sample_rate_hz = 16000; | |
1052 frame_data_.output_number_of_channels = 1; | |
1053 frame_data_.output_sample_rate_hz = 16000; | |
1054 } else { | |
1055 frame_data_.input_number_of_channels = | |
1056 (frame_data_.input_number_of_channels == 1 ? 2 : 1); | |
1057 if (frame_data_.input_sample_rate_hz == 8000) | |
1058 frame_data_.input_sample_rate_hz = 16000; | |
1059 else if (frame_data_.input_sample_rate_hz == 16000) | |
1060 frame_data_.input_sample_rate_hz = 32000; | |
1061 else if (frame_data_.input_sample_rate_hz == 32000) | |
1062 frame_data_.input_sample_rate_hz = 48000; | |
1063 else if (frame_data_.input_sample_rate_hz == 48000) | |
1064 frame_data_.input_sample_rate_hz = 8000; | |
1065 | |
1066 frame_data_.output_number_of_channels = | |
1067 (frame_data_.output_number_of_channels == 1 ? 2 : 1); | |
1068 if (frame_data_.output_sample_rate_hz == 8000) | |
1069 frame_data_.output_sample_rate_hz = 16000; | |
1070 else if (frame_data_.output_sample_rate_hz == 16000) | |
1071 frame_data_.output_sample_rate_hz = 32000; | |
1072 else if (frame_data_.output_sample_rate_hz == 32000) | |
1073 frame_data_.output_sample_rate_hz = 48000; | |
1074 else if (frame_data_.output_sample_rate_hz == 48000) | |
1075 frame_data_.output_sample_rate_hz = 8000; | |
1076 } | |
1077 break; | |
1078 case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: | |
1079 if (render_count_local == 0) { | |
1080 frame_data_.input_sample_rate_hz = 16000; | |
1081 frame_data_.input_number_of_channels = 1; | |
1082 frame_data_.output_sample_rate_hz = 16000; | |
1083 frame_data_.output_number_of_channels = 1; | |
1084 } | |
1085 break; | |
1086 case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: | |
1087 if (render_count_local == 0) { | |
1088 frame_data_.input_sample_rate_hz = 16000; | |
1089 frame_data_.input_number_of_channels = 2; | |
1090 frame_data_.output_sample_rate_hz = 16000; | |
1091 frame_data_.output_number_of_channels = 2; | |
1092 } | |
1093 | |
1094 break; | |
1095 default: | |
1096 assert(false); | |
1097 } | |
1098 | |
1099 // Restric the number of output channels not to exceed | |
1100 // the number of input channels. | |
1101 frame_data_.output_number_of_channels = | |
1102 std::min(frame_data_.output_number_of_channels, | |
1103 frame_data_.input_number_of_channels); | |
1104 } | |
1105 | |
1106 // Implements the callback functionality for the render thread. | |
1107 bool RenderProcessor::Process() { | |
1108 // Conditional wait to ensure that a capture call has been done | |
1109 // before the first render call is performed (implicitly | |
1110 // required by the APM API). | |
1111 if (first_render_side_call_) { | |
1112 while (!capture_call_checker_->CaptureSideCalled()) { | |
1113 SleepRandomMs(3, rand_gen_); | |
1114 } | |
1115 | |
1116 first_render_side_call_ = false; | |
1117 } | |
1118 | |
1119 // Sleep a random time to simulate thread jitter. | |
1120 SleepRandomMs(3, rand_gen_); | |
1121 | |
1122 // End the test early if a fatal failure (ASSERT_*) has occurred. | |
1123 test_->CheckTestCompleteness(); | |
1124 | |
1125 // Ensure that the number of render and capture calls do not | |
1126 // differ too much. | |
1127 while (kMaxCallDifference < -frame_counter_->CaptureMinusRenderCounters()) { | |
1128 SleepMs(1); | |
1129 } | |
1130 | |
1131 // Apply any specified render side APM non-processing runtime calls. | |
1132 ApplyRuntimeSettingScheme(); | |
1133 | |
1134 // Apply the render side processing call. | |
1135 CallApmRenderSide(); | |
1136 | |
1137 // Increase the number of render-side calls. | |
1138 frame_counter_->IncreaseRenderCounter(); | |
1139 | |
1140 return true; | |
1141 } | |
1142 | |
1143 void AudioProcessingImplLockTest::CheckTestCompleteness() { | |
1144 if (HasFatalFailure() || TestDone()) { | |
1145 test_complete_->Set(); | |
1146 } | |
1147 } | |
1148 | |
1149 } // anonymous namespace | |
1150 | |
1151 TEST_P(AudioProcessingImplLockTest, LockTest) { | |
1152 // Run test and verify that it did not time out. | |
1153 ASSERT_EQ(kEventSignaled, RunTest()); | |
1154 } | |
1155 | |
1156 // Instantiate tests from the extreme test configuration set. | |
1157 INSTANTIATE_TEST_CASE_P( | |
1158 DISABLED_AudioProcessingImplLockExtensive, | |
1159 AudioProcessingImplLockTest, | |
1160 ::testing::ValuesIn(TestConfig::GenerateExtensiveTestConfigs())); | |
1161 | |
1162 INSTANTIATE_TEST_CASE_P( | |
1163 AudioProcessingImplLockBrief, | |
1164 AudioProcessingImplLockTest, | |
1165 ::testing::ValuesIn(TestConfig::GenerateBriefTestConfigs())); | |
1166 | |
1167 } // namespace webrtc | |
OLD | NEW |