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