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