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