Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc

Issue 1394803002: Unittest for the locking in APM (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Response to reviewer comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/modules.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698