Index: webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc |
diff --git a/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d1dabee6363baca814b5727375bba0335ccb97c5 |
--- /dev/null |
+++ b/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc |
@@ -0,0 +1,1118 @@ |
+/* |
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#include "webrtc/modules/audio_processing/audio_processing_impl.h" |
+ |
+#include <algorithm> |
+#include <vector> |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "webrtc/base/array_view.h" |
+#include "webrtc/base/criticalsection.h" |
+#include "webrtc/config.h" |
+#include "webrtc/modules/audio_processing/test/test_utils.h" |
+#include "webrtc/modules/include/module_common_types.h" |
+#include "webrtc/system_wrappers/include/event_wrapper.h" |
+#include "webrtc/system_wrappers/include/sleep.h" |
+#include "webrtc/system_wrappers/include/thread_wrapper.h" |
+#include "webrtc/test/random.h" |
+ |
+namespace webrtc { |
+ |
+namespace { |
+ |
+class AudioProcessingImplLockTest; |
+ |
+// Sleeps a random time between 0 and max_sleep milliseconds. |
+void SleepRandomMs(int max_sleep, test::Random* rand_gen) { |
+ int sleeptime = rand_gen->Rand(0, max_sleep); |
+ SleepMs(sleeptime); |
+} |
+ |
+// Populates a float audio frame with random data. |
+void PopulateAudioFrame(float** frame, |
+ float amplitude, |
+ size_t num_channels, |
+ size_t samples_per_channel, |
+ test::Random* rand_gen) { |
+ for (size_t ch = 0; ch < num_channels; ch++) { |
+ for (size_t k = 0; k < samples_per_channel; k++) { |
+ // Store random 16 bit quantized float number between +-amplitude. |
+ frame[ch][k] = amplitude * (2 * rand_gen->Rand<float>() - 1); |
+ } |
+ } |
+} |
+ |
+// Populates an audioframe frame of AudioFrame type with random data. |
+void PopulateAudioFrame(AudioFrame* frame, |
+ int16_t amplitude, |
+ test::Random* rand_gen) { |
+ ASSERT_GT(amplitude, 0); |
+ ASSERT_LE(amplitude, 32767); |
+ for (int ch = 0; ch < frame->num_channels_; ch++) { |
+ for (int k = 0; k < static_cast<int>(frame->samples_per_channel_); k++) { |
+ // Store random 16 bit number between -(amplitude+1) and |
+ // amplitude. |
+ frame->data_[k * ch] = rand_gen->Rand(2 * amplitude + 1) - amplitude - 1; |
+ } |
+ } |
+} |
+ |
+// Type of the render thread APM API call to use in the test. |
+enum class RenderApiImpl { |
+ ProcessReverseStreamImpl1, |
+ ProcessReverseStreamImpl2, |
+ AnalyzeReverseStreamImpl1, |
+ AnalyzeReverseStreamImpl2 |
+}; |
+ |
+// Type of the capture thread APM API call to use in the test. |
+enum class CaptureApiImpl { |
+ ProcessStreamImpl1, |
+ ProcessStreamImpl2, |
+ ProcessStreamImpl3 |
+}; |
+ |
+// The runtime parameter setting scheme to use in the test. |
+enum class RuntimeParameterSettingScheme { |
+ SparseStreamMetadataChangeScheme, |
+ ExtremeStreamMetadataChangeScheme, |
+ FixedMonoStreamMetadataScheme, |
+ FixedStereoStreamMetadataScheme |
+}; |
+ |
+// Variant of echo canceller settings to use in the test. |
+enum class AecType { |
+ BasicWebRtcAecSettings, |
+ AecTurnedOff, |
+ BasicWebRtcAecSettingsWithExtentedFilter, |
+ BasicWebRtcAecSettingsWithDelayAgnosticAec, |
+ BasicWebRtcAecSettingsWithAecMobile |
+}; |
+ |
+// Variables related to the audio data and formats. |
+struct AudioFrameData { |
+ explicit AudioFrameData(int max_frame_size) { |
+ // Set up the two-dimensional arrays needed for the APM API calls. |
+ input_framechannels.resize(2 * max_frame_size); |
+ input_frame.resize(2); |
+ input_frame[0] = &input_framechannels[0]; |
+ input_frame[1] = &input_framechannels[max_frame_size]; |
+ |
+ output_frame_channels.resize(2 * max_frame_size); |
+ output_frame.resize(2); |
+ output_frame[0] = &output_frame_channels[0]; |
+ output_frame[1] = &output_frame_channels[max_frame_size]; |
+ } |
+ |
+ AudioFrame frame; |
+ std::vector<float*> output_frame; |
+ std::vector<float> output_frame_channels; |
+ AudioProcessing::ChannelLayout output_channel_layout = |
+ AudioProcessing::ChannelLayout::kMono; |
+ int input_sample_rate_hz = 16000; |
+ int input_number_of_channels = -1; |
+ std::vector<float*> input_frame; |
+ std::vector<float> input_framechannels; |
+ AudioProcessing::ChannelLayout input_channel_layout = |
+ AudioProcessing::ChannelLayout::kMono; |
+ int output_sample_rate_hz = 16000; |
+ int output_number_of_channels = -1; |
+ StreamConfig input_stream_config; |
+ StreamConfig output_stream_config; |
+ int input_samples_per_channel = -1; |
+ int output_samples_per_channel = -1; |
+}; |
+ |
+// The configuration for the test. |
+struct TestConfig { |
+ // Test case generator for the test configurations to use in the brief tests. |
+ static std::vector<TestConfig> GenerateBriefTestConfigs() { |
+ std::vector<TestConfig> test_configs; |
+ AecType aec_types[] = {AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec, |
+ AecType::BasicWebRtcAecSettingsWithAecMobile}; |
+ for (auto aec_type : aec_types) { |
+ TestConfig test_config; |
+ test_config.aec_type = aec_type; |
+ |
+ test_config.min_number_of_calls = 300; |
+ |
+ // Perform tests only with the extreme runtime parameter setting scheme. |
+ test_config.runtime_parameter_setting_scheme = |
+ RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme; |
+ |
+ // Only test 16 kHz for this test suite. |
+ test_config.initial_sample_rate_hz = 16000; |
+ |
+ // Create test config for the second processing API function set. |
+ test_config.render_api_function = |
+ RenderApiImpl::ProcessReverseStreamImpl2; |
+ test_config.capture_api_function = CaptureApiImpl::ProcessStreamImpl2; |
+ |
+ // Create test config for the first processing API function set. |
+ test_configs.push_back(test_config); |
+ test_config.render_api_function = |
+ RenderApiImpl::AnalyzeReverseStreamImpl2; |
+ test_config.capture_api_function = CaptureApiImpl::ProcessStreamImpl3; |
+ test_configs.push_back(test_config); |
+ } |
+ |
+ // Return the created test configurations. |
+ return test_configs; |
+ } |
+ |
+ // Test case generator for the test configurations to use in the extensive |
+ // tests. |
+ static std::vector<TestConfig> GenerateExtensiveTestConfigs() { |
+ // Lambda functions for the test config generation. |
+ auto add_processing_apis = [](TestConfig test_config) { |
+ struct AllowedApiCallCombinations { |
+ RenderApiImpl render_api; |
+ CaptureApiImpl capture_api; |
+ }; |
+ |
+ const AllowedApiCallCombinations api_calls[] = { |
+ {RenderApiImpl::ProcessReverseStreamImpl1, |
+ CaptureApiImpl::ProcessStreamImpl1}, |
+ {RenderApiImpl::AnalyzeReverseStreamImpl1, |
+ CaptureApiImpl::ProcessStreamImpl1}, |
+ {RenderApiImpl::ProcessReverseStreamImpl2, |
+ CaptureApiImpl::ProcessStreamImpl2}, |
+ {RenderApiImpl::ProcessReverseStreamImpl2, |
+ CaptureApiImpl::ProcessStreamImpl3}, |
+ {RenderApiImpl::AnalyzeReverseStreamImpl2, |
+ CaptureApiImpl::ProcessStreamImpl2}, |
+ {RenderApiImpl::AnalyzeReverseStreamImpl2, |
+ CaptureApiImpl::ProcessStreamImpl3}}; |
+ std::vector<TestConfig> out; |
+ for (auto api_call : api_calls) { |
+ test_config.render_api_function = api_call.render_api; |
+ test_config.capture_api_function = api_call.capture_api; |
+ out.push_back(test_config); |
+ } |
+ return out; |
+ }; |
+ |
+ auto add_aec_settings = [](const std::vector<TestConfig>& in) { |
+ std::vector<TestConfig> out; |
+ AecType aec_types[] = { |
+ AecType::BasicWebRtcAecSettings, AecType::AecTurnedOff, |
+ AecType::BasicWebRtcAecSettingsWithExtentedFilter, |
+ AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec, |
+ AecType::BasicWebRtcAecSettingsWithAecMobile}; |
+ for (auto test_config : in) { |
+ for (auto aec_type : aec_types) { |
+ test_config.aec_type = aec_type; |
+ out.push_back(test_config); |
+ } |
+ } |
+ return out; |
+ }; |
+ |
+ auto add_settings_scheme = [](const std::vector<TestConfig>& in) { |
+ std::vector<TestConfig> out; |
+ RuntimeParameterSettingScheme schemes[] = { |
+ RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme, |
+ RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme, |
+ RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme, |
+ RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme}; |
+ |
+ for (auto test_config : in) { |
+ for (auto scheme : schemes) { |
+ test_config.runtime_parameter_setting_scheme = scheme; |
+ out.push_back(test_config); |
+ } |
+ } |
+ return out; |
+ }; |
+ |
+ auto add_sample_rates = [](const std::vector<TestConfig>& in) { |
+ const int sample_rates[] = {8000, 16000, 32000, 48000}; |
+ |
+ std::vector<TestConfig> out; |
+ for (auto test_config : in) { |
+ auto available_rates = |
+ (test_config.aec_type == |
+ AecType::BasicWebRtcAecSettingsWithAecMobile |
+ ? rtc::ArrayView<const int>(sample_rates, 2) |
+ : rtc::ArrayView<const int>(sample_rates)); |
+ |
+ for (auto rate : available_rates) { |
+ test_config.initial_sample_rate_hz = rate; |
+ out.push_back(test_config); |
+ } |
+ } |
+ return out; |
+ }; |
+ |
+ // Generate test configurations of the relevant combinations of the |
+ // parameters to |
+ // test. |
+ TestConfig test_config; |
+ test_config.min_number_of_calls = 10000; |
+ return add_sample_rates(add_settings_scheme( |
+ add_aec_settings(add_processing_apis(test_config)))); |
+ } |
+ |
+ RenderApiImpl render_api_function = RenderApiImpl::ProcessReverseStreamImpl2; |
+ CaptureApiImpl capture_api_function = CaptureApiImpl::ProcessStreamImpl2; |
+ RuntimeParameterSettingScheme runtime_parameter_setting_scheme = |
+ RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme; |
+ int initial_sample_rate_hz = 16000; |
+ AecType aec_type = AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec; |
+ int min_number_of_calls = 300; |
+}; |
+ |
+// Handler for the frame counters. |
+class FrameCounters { |
+ public: |
+ void IncreaseRenderCounter() { |
+ rtc::CritScope cs(&crit_); |
+ render_count++; |
+ } |
+ |
+ void IncreaseCaptureCounter() { |
+ rtc::CritScope cs(&crit_); |
+ capture_count++; |
+ } |
+ |
+ int GetCaptureCounter() { |
+ rtc::CritScope cs(&crit_); |
+ return capture_count; |
+ } |
+ |
+ int GetRenderCounter() { |
+ rtc::CritScope cs(&crit_); |
+ return render_count; |
+ } |
+ |
+ int CaptureMinusRenderCounters() { |
+ rtc::CritScope cs(&crit_); |
+ return capture_count - render_count; |
+ } |
+ |
+ bool BothCountersExceedeThreshold(int threshold) { |
+ rtc::CritScope cs(&crit_); |
+ return (render_count > threshold && capture_count > threshold); |
+ } |
+ |
+ private: |
+ rtc::CriticalSection crit_; |
+ int render_count GUARDED_BY(crit_) = 0; |
+ int capture_count GUARDED_BY(crit_) = 0; |
+}; |
+ |
+// Checker for whether the capture side has been called. |
+class CaptureSideCalledChecker { |
+ public: |
+ bool CaptureSideCalled() { |
+ rtc::CritScope cs(&crit_); |
+ return capture_side_called_; |
+ } |
+ |
+ void FlagCaptureSideCalled() { |
+ rtc::CritScope cs(&crit_); |
+ capture_side_called_ = true; |
+ } |
+ |
+ private: |
+ rtc::CriticalSection crit_; |
+ bool capture_side_called_ GUARDED_BY(crit_) = false; |
+}; |
+ |
+// Class for handling the capture side processing. |
+class CaptureProcessor { |
+ public: |
+ CaptureProcessor(int max_frame_size, |
+ test::Random* rand_gen, |
+ FrameCounters* shared_counters_state, |
+ CaptureSideCalledChecker* capture_call_checker, |
+ AudioProcessingImplLockTest* test_framework, |
+ TestConfig* test_config, |
+ AudioProcessing* apm); |
+ bool Process(); |
+ |
+ private: |
+ static const int kMaxCallDifference = 10; |
+ static const float kCaptureInputFloatLevel; |
+ static const int kCaptureInputFixLevel = 1024; |
+ |
+ void PrepareFrame(); |
+ void CallApmCaptureSide(); |
+ void ApplyRuntimeSettingScheme(); |
+ |
+ test::Random* rand_gen_ = nullptr; |
+ FrameCounters* frame_counters_ = nullptr; |
+ CaptureSideCalledChecker* capture_call_checker_ = nullptr; |
+ AudioProcessingImplLockTest* test_ = nullptr; |
+ TestConfig* test_config_ = nullptr; |
+ AudioProcessing* apm_ = nullptr; |
+ AudioFrameData frame_data_; |
+}; |
+ |
+// Class for handling the stats processing. |
+class StatsProcessor { |
+ public: |
+ StatsProcessor(test::Random* rand_gen, |
+ TestConfig* test_config, |
+ AudioProcessing* apm); |
+ bool Process(); |
+ |
+ private: |
+ test::Random* rand_gen_ = nullptr; |
+ TestConfig* test_config_ = nullptr; |
+ AudioProcessing* apm_ = nullptr; |
+}; |
+ |
+// Class for handling the render side processing. |
+class RenderProcessor { |
+ public: |
+ RenderProcessor(int max_frame_size, |
+ test::Random* rand_gen, |
+ FrameCounters* shared_counters_state, |
+ CaptureSideCalledChecker* capture_call_checker, |
+ AudioProcessingImplLockTest* test_framework, |
+ TestConfig* test_config, |
+ AudioProcessing* apm); |
+ bool Process(); |
+ |
+ private: |
+ static const int kMaxCallDifference = 10; |
+ static const int kRenderInputFixLevel = 16384; |
+ static const float kRenderInputFloatLevel; |
+ |
+ void PrepareFrame(); |
+ void CallApmRenderSide(); |
+ void ApplyRuntimeSettingScheme(); |
+ |
+ test::Random* rand_gen_ = nullptr; |
+ FrameCounters* frame_counters_ = nullptr; |
+ CaptureSideCalledChecker* capture_call_checker_ = nullptr; |
+ AudioProcessingImplLockTest* test_ = nullptr; |
+ TestConfig* test_config_ = nullptr; |
+ AudioProcessing* apm_ = nullptr; |
+ bool first_render_side_call_ = true; |
+ AudioFrameData frame_data_; |
+}; |
+ |
+class AudioProcessingImplLockTest |
+ : public ::testing::TestWithParam<TestConfig> { |
+ public: |
+ AudioProcessingImplLockTest(); |
+ EventTypeWrapper RunTest(); |
+ void CheckTestCompleteness(); |
+ |
+ private: |
+ static const int kTestTimeOutLimit = 10 * 60 * 1000; |
+ static const int kMaxFrameSize = 480; |
+ |
+ // ::testing::TestWithParam<> implementation |
+ void SetUp() override; |
+ void TearDown() override; |
+ |
+ // Thread callback for the render thread |
+ static bool RenderProcessorThreadFunc(void* context) { |
+ return reinterpret_cast<AudioProcessingImplLockTest*>(context) |
+ ->render_thread_state_.Process(); |
+ } |
+ |
+ // Thread callback for the capture thread |
+ static bool CaptureProcessorThreadFunc(void* context) { |
+ return reinterpret_cast<AudioProcessingImplLockTest*>(context) |
+ ->capture_thread_state_.Process(); |
+ } |
+ |
+ // Thread callback for the stats thread |
+ static bool StatsProcessorThreadFunc(void* context) { |
+ return reinterpret_cast<AudioProcessingImplLockTest*>(context) |
+ ->stats_thread_state_.Process(); |
+ } |
+ |
+ // Tests whether all the required render and capture side calls have been |
+ // done. |
+ bool TestDone() { |
+ return frame_counters_.BothCountersExceedeThreshold( |
+ test_config_.min_number_of_calls); |
+ } |
+ |
+ // Start the threads used in the test. |
+ void StartThreads() { |
+ ASSERT_TRUE(render_thread_->Start()); |
+ render_thread_->SetPriority(kRealtimePriority); |
+ ASSERT_TRUE(capture_thread_->Start()); |
+ capture_thread_->SetPriority(kRealtimePriority); |
+ ASSERT_TRUE(stats_thread_->Start()); |
+ stats_thread_->SetPriority(kNormalPriority); |
+ } |
+ |
+ // Event handler for the test. |
+ const rtc::scoped_ptr<EventWrapper> test_complete_; |
+ |
+ // Thread related variables. |
+ rtc::scoped_ptr<ThreadWrapper> render_thread_; |
+ rtc::scoped_ptr<ThreadWrapper> capture_thread_; |
+ rtc::scoped_ptr<ThreadWrapper> stats_thread_; |
+ mutable test::Random rand_gen_; |
+ |
+ rtc::scoped_ptr<AudioProcessing> apm_; |
+ TestConfig test_config_; |
+ FrameCounters frame_counters_; |
+ CaptureSideCalledChecker capture_call_checker_; |
+ RenderProcessor render_thread_state_; |
+ CaptureProcessor capture_thread_state_; |
+ StatsProcessor stats_thread_state_; |
+}; |
+ |
+AudioProcessingImplLockTest::AudioProcessingImplLockTest() |
+ : test_complete_(EventWrapper::Create()), |
+ render_thread_(ThreadWrapper::CreateThread(RenderProcessorThreadFunc, |
+ this, |
+ "render")), |
+ capture_thread_(ThreadWrapper::CreateThread(CaptureProcessorThreadFunc, |
+ this, |
+ "capture")), |
+ stats_thread_( |
+ ThreadWrapper::CreateThread(StatsProcessorThreadFunc, this, "stats")), |
+ rand_gen_(42U), |
+ apm_(AudioProcessingImpl::Create()), |
+ render_thread_state_(kMaxFrameSize, |
+ &rand_gen_, |
+ &frame_counters_, |
+ &capture_call_checker_, |
+ this, |
+ &test_config_, |
+ apm_.get()), |
+ capture_thread_state_(kMaxFrameSize, |
+ &rand_gen_, |
+ &frame_counters_, |
+ &capture_call_checker_, |
+ this, |
+ &test_config_, |
+ apm_.get()), |
+ stats_thread_state_(&rand_gen_, &test_config_, apm_.get()) {} |
+ |
+// Run the test with a timeout. |
+EventTypeWrapper AudioProcessingImplLockTest::RunTest() { |
+ StartThreads(); |
+ return test_complete_->Wait(kTestTimeOutLimit); |
+} |
+ |
+void AudioProcessingImplLockTest::CheckTestCompleteness() { |
+ if (HasFatalFailure() || TestDone()) { |
+ test_complete_->Set(); |
+ } |
+} |
+ |
+// Setup of test and APM. |
+void AudioProcessingImplLockTest::SetUp() { |
+ test_config_ = static_cast<TestConfig>(GetParam()); |
+ |
+ ASSERT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true)); |
+ ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true)); |
+ |
+ ASSERT_EQ(apm_->kNoError, |
+ apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog)); |
+ ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true)); |
+ |
+ ASSERT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true)); |
+ ASSERT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true)); |
+ |
+ Config config; |
+ if (test_config_.aec_type == AecType::AecTurnedOff) { |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false)); |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false)); |
+ } else if (test_config_.aec_type == |
+ AecType::BasicWebRtcAecSettingsWithAecMobile) { |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true)); |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false)); |
+ } else { |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false)); |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true)); |
+ ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->enable_metrics(true)); |
+ ASSERT_EQ(apm_->kNoError, |
+ apm_->echo_cancellation()->enable_delay_logging(true)); |
+ |
+ config.Set<ExtendedFilter>( |
+ new ExtendedFilter(test_config_.aec_type == |
+ AecType::BasicWebRtcAecSettingsWithExtentedFilter)); |
+ |
+ config.Set<DelayAgnostic>( |
+ new DelayAgnostic(test_config_.aec_type == |
+ AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec)); |
+ |
+ apm_->SetExtraOptions(config); |
+ } |
+} |
+ |
+void AudioProcessingImplLockTest::TearDown() { |
+ render_thread_->Stop(); |
+ capture_thread_->Stop(); |
+ stats_thread_->Stop(); |
+} |
+ |
+StatsProcessor::StatsProcessor(test::Random* rand_gen, |
+ TestConfig* test_config, |
+ AudioProcessing* apm) |
+ : rand_gen_(rand_gen), test_config_(test_config), apm_(apm) {} |
+ |
+// Implements the callback functionality for the statistics |
+// collection thread. |
+bool StatsProcessor::Process() { |
+ SleepRandomMs(100, rand_gen_); |
+ |
+ EXPECT_EQ(apm_->echo_cancellation()->is_enabled(), |
+ ((test_config_->aec_type != AecType::AecTurnedOff) && |
+ (test_config_->aec_type != |
+ AecType::BasicWebRtcAecSettingsWithAecMobile))); |
+ apm_->echo_cancellation()->stream_drift_samples(); |
+ EXPECT_EQ(apm_->echo_control_mobile()->is_enabled(), |
+ (test_config_->aec_type != AecType::AecTurnedOff) && |
+ (test_config_->aec_type == |
+ AecType::BasicWebRtcAecSettingsWithAecMobile)); |
+ EXPECT_TRUE(apm_->gain_control()->is_enabled()); |
+ apm_->gain_control()->stream_analog_level(); |
+ EXPECT_TRUE(apm_->noise_suppression()->is_enabled()); |
+ |
+ // The below return values are not testable. |
+ apm_->noise_suppression()->speech_probability(); |
+ apm_->voice_detection()->is_enabled(); |
+ |
+ return true; |
+} |
+ |
+const float CaptureProcessor::kCaptureInputFloatLevel = 0.03125f; |
+ |
+CaptureProcessor::CaptureProcessor( |
+ int max_frame_size, |
+ test::Random* rand_gen, |
+ FrameCounters* shared_counters_state, |
+ CaptureSideCalledChecker* capture_call_checker, |
+ AudioProcessingImplLockTest* test_framework, |
+ TestConfig* test_config, |
+ AudioProcessing* apm) |
+ : rand_gen_(rand_gen), |
+ frame_counters_(shared_counters_state), |
+ capture_call_checker_(capture_call_checker), |
+ test_(test_framework), |
+ test_config_(test_config), |
+ apm_(apm), |
+ frame_data_(max_frame_size) {} |
+ |
+// Implements the callback functionality for the capture thread. |
+bool CaptureProcessor::Process() { |
+ // Sleep a random time to simulate thread jitter. |
+ SleepRandomMs(3, rand_gen_); |
+ |
+ // End the test if complete. |
+ test_->CheckTestCompleteness(); |
+ |
+ // Ensure that there are not more capture side calls than render side |
+ // calls. |
+ if (capture_call_checker_->CaptureSideCalled()) { |
+ while (kMaxCallDifference < frame_counters_->CaptureMinusRenderCounters()) { |
+ SleepMs(1); |
+ } |
+ } |
+ |
+ // Apply any specified capture side APM non-processing runtime calls. |
+ ApplyRuntimeSettingScheme(); |
+ |
+ // Apply the capture side processing call. |
+ CallApmCaptureSide(); |
+ |
+ // Increase the number of capture-side calls. |
+ frame_counters_->IncreaseCaptureCounter(); |
+ |
+ // Flag that the capture side has been called at least once |
+ // (needed to ensure that a capture call has been done |
+ // before the first render call is performed (implicitly |
+ // required by the APM API). |
+ capture_call_checker_->FlagCaptureSideCalled(); |
+ |
+ return true; |
+} |
+ |
+// Prepares a frame with relevant audio data and metadata. |
+void CaptureProcessor::PrepareFrame() { |
+ // Restrict to a common fixed sample rate if the AudioFrame |
+ // interface is used. |
+ if (test_config_->capture_api_function == |
+ CaptureApiImpl::ProcessStreamImpl1) { |
+ frame_data_.input_sample_rate_hz = test_config_->initial_sample_rate_hz; |
+ frame_data_.output_sample_rate_hz = test_config_->initial_sample_rate_hz; |
+ } |
+ |
+ // Prepare the audioframe data and metadata. |
+ frame_data_.input_samples_per_channel = |
+ frame_data_.input_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; |
+ frame_data_.frame.sample_rate_hz_ = frame_data_.input_sample_rate_hz; |
+ frame_data_.frame.num_channels_ = frame_data_.input_number_of_channels; |
+ frame_data_.frame.samples_per_channel_ = |
+ frame_data_.input_samples_per_channel; |
+ PopulateAudioFrame(&frame_data_.frame, kCaptureInputFixLevel, rand_gen_); |
+ |
+ // Prepare the float audio input data and metadata. |
+ frame_data_.input_stream_config.set_sample_rate_hz( |
+ frame_data_.input_sample_rate_hz); |
+ frame_data_.input_stream_config.set_num_channels( |
+ frame_data_.input_number_of_channels); |
+ frame_data_.input_stream_config.set_has_keyboard(false); |
+ PopulateAudioFrame(&frame_data_.input_frame[0], kCaptureInputFloatLevel, |
+ frame_data_.input_number_of_channels, |
+ frame_data_.input_samples_per_channel, rand_gen_); |
+ frame_data_.input_channel_layout = |
+ (frame_data_.input_number_of_channels == 1 |
+ ? AudioProcessing::ChannelLayout::kMono |
+ : AudioProcessing::ChannelLayout::kStereo); |
+ |
+ // Prepare the float audio output data and metadata. |
+ frame_data_.output_samples_per_channel = |
+ frame_data_.output_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; |
+ frame_data_.output_stream_config.set_sample_rate_hz( |
+ frame_data_.output_sample_rate_hz); |
+ frame_data_.output_stream_config.set_num_channels( |
+ frame_data_.output_number_of_channels); |
+ frame_data_.output_stream_config.set_has_keyboard(false); |
+ frame_data_.output_channel_layout = |
+ (frame_data_.output_number_of_channels == 1 |
+ ? AudioProcessing::ChannelLayout::kMono |
+ : AudioProcessing::ChannelLayout::kStereo); |
+} |
+ |
+// Applies the capture side processing API call. |
+void CaptureProcessor::CallApmCaptureSide() { |
+ // Prepare a proper capture side processing API call input. |
+ PrepareFrame(); |
+ |
+ // Set the stream delay |
+ apm_->set_stream_delay_ms(30); |
+ |
+ // Call the specified capture side API processing method. |
+ int result = AudioProcessing::kNoError; |
+ switch (test_config_->capture_api_function) { |
+ case CaptureApiImpl::ProcessStreamImpl1: |
+ result = apm_->ProcessStream(&frame_data_.frame); |
+ break; |
+ case CaptureApiImpl::ProcessStreamImpl2: |
+ result = apm_->ProcessStream( |
+ &frame_data_.input_frame[0], frame_data_.input_samples_per_channel, |
+ frame_data_.input_sample_rate_hz, frame_data_.input_channel_layout, |
+ frame_data_.output_sample_rate_hz, frame_data_.output_channel_layout, |
+ &frame_data_.output_frame[0]); |
+ break; |
+ case CaptureApiImpl::ProcessStreamImpl3: |
+ result = apm_->ProcessStream( |
+ &frame_data_.input_frame[0], frame_data_.input_stream_config, |
+ frame_data_.output_stream_config, &frame_data_.output_frame[0]); |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ // Check the return code for error. |
+ ASSERT_EQ(AudioProcessing::kNoError, result); |
+} |
+ |
+// Applies any runtime capture APM API calls and audio stream characteristics |
+// specified by the scheme for the test. |
+void CaptureProcessor::ApplyRuntimeSettingScheme() { |
+ const int capture_count_local = frame_counters_->GetCaptureCounter(); |
+ |
+ // Update the number of channels and sample rates for the input and output. |
+ // Note that the counts frequencies for when to set parameters |
+ // are set using prime numbers in order to ensure that the |
+ // permutation scheme in the parameter setting changes. |
+ switch (test_config_->runtime_parameter_setting_scheme) { |
+ case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: |
+ if (capture_count_local == 0) |
+ frame_data_.input_sample_rate_hz = 16000; |
+ else if (capture_count_local % 11 == 0) |
+ frame_data_.input_sample_rate_hz = 32000; |
+ else if (capture_count_local % 73 == 0) |
+ frame_data_.input_sample_rate_hz = 48000; |
+ else if (capture_count_local % 89 == 0) |
+ frame_data_.input_sample_rate_hz = 16000; |
+ else if (capture_count_local % 97 == 0) |
+ frame_data_.input_sample_rate_hz = 8000; |
+ |
+ if (capture_count_local == 0) |
+ frame_data_.input_number_of_channels = 1; |
+ else if (capture_count_local % 4 == 0) |
+ frame_data_.input_number_of_channels = |
+ (frame_data_.input_number_of_channels == 1 ? 2 : 1); |
+ |
+ if (capture_count_local == 0) |
+ frame_data_.output_sample_rate_hz = 16000; |
+ else if (capture_count_local % 5 == 0) |
+ frame_data_.output_sample_rate_hz = 32000; |
+ else if (capture_count_local % 47 == 0) |
+ frame_data_.output_sample_rate_hz = 48000; |
+ else if (capture_count_local % 53 == 0) |
+ frame_data_.output_sample_rate_hz = 16000; |
+ else if (capture_count_local % 71 == 0) |
+ frame_data_.output_sample_rate_hz = 8000; |
+ |
+ if (capture_count_local == 0) |
+ frame_data_.output_number_of_channels = 1; |
+ else if (capture_count_local % 8 == 0) |
+ frame_data_.output_number_of_channels = |
+ (frame_data_.output_number_of_channels == 1 ? 2 : 1); |
+ break; |
+ case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: |
+ if (capture_count_local % 2 == 0) { |
+ frame_data_.input_number_of_channels = 1; |
+ frame_data_.input_sample_rate_hz = 16000; |
+ frame_data_.output_number_of_channels = 1; |
+ frame_data_.output_sample_rate_hz = 16000; |
+ } else { |
+ frame_data_.input_number_of_channels = |
+ (frame_data_.input_number_of_channels == 1 ? 2 : 1); |
+ if (frame_data_.input_sample_rate_hz == 8000) |
+ frame_data_.input_sample_rate_hz = 16000; |
+ else if (frame_data_.input_sample_rate_hz == 16000) |
+ frame_data_.input_sample_rate_hz = 32000; |
+ else if (frame_data_.input_sample_rate_hz == 32000) |
+ frame_data_.input_sample_rate_hz = 48000; |
+ else if (frame_data_.input_sample_rate_hz == 48000) |
+ frame_data_.input_sample_rate_hz = 8000; |
+ |
+ frame_data_.output_number_of_channels = |
+ (frame_data_.output_number_of_channels == 1 ? 2 : 1); |
+ if (frame_data_.output_sample_rate_hz == 8000) |
+ frame_data_.output_sample_rate_hz = 16000; |
+ else if (frame_data_.output_sample_rate_hz == 16000) |
+ frame_data_.output_sample_rate_hz = 32000; |
+ else if (frame_data_.output_sample_rate_hz == 32000) |
+ frame_data_.output_sample_rate_hz = 48000; |
+ else if (frame_data_.output_sample_rate_hz == 48000) |
+ frame_data_.output_sample_rate_hz = 8000; |
+ } |
+ break; |
+ case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: |
+ if (capture_count_local == 0) { |
+ frame_data_.input_sample_rate_hz = 16000; |
+ frame_data_.input_number_of_channels = 1; |
+ frame_data_.output_sample_rate_hz = 16000; |
+ frame_data_.output_number_of_channels = 1; |
+ } |
+ break; |
+ case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: |
+ if (capture_count_local == 0) { |
+ frame_data_.input_sample_rate_hz = 16000; |
+ frame_data_.input_number_of_channels = 2; |
+ frame_data_.output_sample_rate_hz = 16000; |
+ frame_data_.output_number_of_channels = 2; |
+ } |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ // Call any specified runtime APM setter and |
+ // getter calls. |
+ switch (test_config_->runtime_parameter_setting_scheme) { |
+ case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: |
+ case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: |
+ break; |
+ case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: |
+ case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: |
+ if (capture_count_local % 2 == 0) { |
+ ASSERT_EQ(AudioProcessing::Error::kNoError, |
+ apm_->set_stream_delay_ms(30)); |
+ apm_->set_stream_key_pressed(true); |
+ apm_->set_output_will_be_muted(true); |
+ apm_->set_delay_offset_ms(15); |
+ EXPECT_EQ(apm_->delay_offset_ms(), 15); |
+ EXPECT_GE(apm_->num_reverse_channels(), 0); |
+ EXPECT_LE(apm_->num_reverse_channels(), 2); |
+ } else { |
+ ASSERT_EQ(AudioProcessing::Error::kNoError, |
+ apm_->set_stream_delay_ms(50)); |
+ apm_->set_stream_key_pressed(false); |
+ apm_->set_output_will_be_muted(false); |
+ apm_->set_delay_offset_ms(20); |
+ EXPECT_EQ(apm_->delay_offset_ms(), 20); |
+ apm_->delay_offset_ms(); |
+ apm_->num_reverse_channels(); |
+ EXPECT_GE(apm_->num_reverse_channels(), 0); |
+ EXPECT_LE(apm_->num_reverse_channels(), 2); |
+ } |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ // Restric the number of output channels not to exceed |
+ // the number of input channels. |
+ frame_data_.output_number_of_channels = |
+ std::min(frame_data_.output_number_of_channels, |
+ frame_data_.input_number_of_channels); |
+} |
+ |
+const float RenderProcessor::kRenderInputFloatLevel = 0.5f; |
+ |
+RenderProcessor::RenderProcessor(int max_frame_size, |
+ test::Random* rand_gen, |
+ FrameCounters* shared_counters_state, |
+ CaptureSideCalledChecker* capture_call_checker, |
+ AudioProcessingImplLockTest* test_framework, |
+ TestConfig* test_config, |
+ AudioProcessing* apm) |
+ : rand_gen_(rand_gen), |
+ frame_counters_(shared_counters_state), |
+ capture_call_checker_(capture_call_checker), |
+ test_(test_framework), |
+ test_config_(test_config), |
+ apm_(apm), |
+ frame_data_(max_frame_size) {} |
+ |
+// Implements the callback functionality for the render thread. |
+bool RenderProcessor::Process() { |
+ // Conditional wait to ensure that a capture call has been done |
+ // before the first render call is performed (implicitly |
+ // required by the APM API). |
+ if (first_render_side_call_) { |
+ while (!capture_call_checker_->CaptureSideCalled()) { |
+ SleepRandomMs(3, rand_gen_); |
+ } |
+ |
+ first_render_side_call_ = false; |
+ } |
+ |
+ // Sleep a random time to simulate thread jitter. |
+ SleepRandomMs(3, rand_gen_); |
+ |
+ // End the test early if a fatal failure (ASSERT_*) has occurred. |
+ test_->CheckTestCompleteness(); |
+ |
+ // Ensure that the number of render and capture calls do not |
+ // differ too much. |
+ while (kMaxCallDifference < -frame_counters_->CaptureMinusRenderCounters()) { |
+ SleepMs(1); |
+ } |
+ |
+ // Apply any specified render side APM non-processing runtime calls. |
+ ApplyRuntimeSettingScheme(); |
+ |
+ // Apply the render side processing call. |
+ CallApmRenderSide(); |
+ |
+ // Increase the number of render-side calls. |
+ frame_counters_->IncreaseRenderCounter(); |
+ |
+ return true; |
+} |
+ |
+// Prepares the render side frame and the accompanying metadata |
+// with the appropriate information. |
+void RenderProcessor::PrepareFrame() { |
+ // Restrict to a common fixed sample rate if the AudioFrame interface is |
+ // used. |
+ if ((test_config_->render_api_function == |
+ RenderApiImpl::AnalyzeReverseStreamImpl1) || |
+ (test_config_->render_api_function == |
+ RenderApiImpl::ProcessReverseStreamImpl1) || |
+ (test_config_->aec_type != |
+ AecType::BasicWebRtcAecSettingsWithAecMobile)) { |
+ frame_data_.input_sample_rate_hz = test_config_->initial_sample_rate_hz; |
+ frame_data_.output_sample_rate_hz = test_config_->initial_sample_rate_hz; |
+ } |
+ |
+ // Prepare the audioframe data and metadata |
+ frame_data_.input_samples_per_channel = |
+ frame_data_.input_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; |
+ frame_data_.frame.sample_rate_hz_ = frame_data_.input_sample_rate_hz; |
+ frame_data_.frame.num_channels_ = frame_data_.input_number_of_channels; |
+ frame_data_.frame.samples_per_channel_ = |
+ frame_data_.input_samples_per_channel; |
+ PopulateAudioFrame(&frame_data_.frame, kRenderInputFixLevel, rand_gen_); |
+ |
+ // Prepare the float audio input data and metadata. |
+ frame_data_.input_stream_config.set_sample_rate_hz( |
+ frame_data_.input_sample_rate_hz); |
+ frame_data_.input_stream_config.set_num_channels( |
+ frame_data_.input_number_of_channels); |
+ frame_data_.input_stream_config.set_has_keyboard(false); |
+ PopulateAudioFrame(&frame_data_.input_frame[0], kRenderInputFloatLevel, |
+ frame_data_.input_number_of_channels, |
+ frame_data_.input_samples_per_channel, rand_gen_); |
+ frame_data_.input_channel_layout = |
+ (frame_data_.input_number_of_channels == 1 |
+ ? AudioProcessing::ChannelLayout::kMono |
+ : AudioProcessing::ChannelLayout::kStereo); |
+ |
+ // Prepare the float audio output data and metadata. |
+ frame_data_.output_samples_per_channel = |
+ frame_data_.output_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000; |
+ frame_data_.output_stream_config.set_sample_rate_hz( |
+ frame_data_.output_sample_rate_hz); |
+ frame_data_.output_stream_config.set_num_channels( |
+ frame_data_.output_number_of_channels); |
+ frame_data_.output_stream_config.set_has_keyboard(false); |
+ frame_data_.output_channel_layout = |
+ (frame_data_.output_number_of_channels == 1 |
+ ? AudioProcessing::ChannelLayout::kMono |
+ : AudioProcessing::ChannelLayout::kStereo); |
+} |
+ |
+// Makes the render side processing API call. |
+void RenderProcessor::CallApmRenderSide() { |
+ // Prepare a proper render side processing API call input. |
+ PrepareFrame(); |
+ |
+ // Call the specified render side API processing method. |
+ int result = AudioProcessing::kNoError; |
+ switch (test_config_->render_api_function) { |
+ case RenderApiImpl::ProcessReverseStreamImpl1: |
+ result = apm_->ProcessReverseStream(&frame_data_.frame); |
+ break; |
+ case RenderApiImpl::ProcessReverseStreamImpl2: |
+ result = apm_->ProcessReverseStream( |
+ &frame_data_.input_frame[0], frame_data_.input_stream_config, |
+ frame_data_.output_stream_config, &frame_data_.output_frame[0]); |
+ break; |
+ case RenderApiImpl::AnalyzeReverseStreamImpl1: |
+ result = apm_->AnalyzeReverseStream(&frame_data_.frame); |
+ break; |
+ case RenderApiImpl::AnalyzeReverseStreamImpl2: |
+ result = apm_->AnalyzeReverseStream( |
+ &frame_data_.input_frame[0], frame_data_.input_samples_per_channel, |
+ frame_data_.input_sample_rate_hz, frame_data_.input_channel_layout); |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ // Check the return code for error. |
+ ASSERT_EQ(AudioProcessing::kNoError, result); |
+} |
+ |
+// Applies any render capture side APM API calls and audio stream |
+// characteristics |
+// specified by the scheme for the test. |
+void RenderProcessor::ApplyRuntimeSettingScheme() { |
+ const int render_count_local = frame_counters_->GetRenderCounter(); |
+ |
+ // Update the number of channels and sample rates for the input and output. |
+ // Note that the counts frequencies for when to set parameters |
+ // are set using prime numbers in order to ensure that the |
+ // permutation scheme in the parameter setting changes. |
+ switch (test_config_->runtime_parameter_setting_scheme) { |
+ case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme: |
+ if (render_count_local == 0) |
+ frame_data_.input_sample_rate_hz = 16000; |
+ else if (render_count_local % 47 == 0) |
+ frame_data_.input_sample_rate_hz = 32000; |
+ else if (render_count_local % 71 == 0) |
+ frame_data_.input_sample_rate_hz = 48000; |
+ else if (render_count_local % 79 == 0) |
+ frame_data_.input_sample_rate_hz = 16000; |
+ else if (render_count_local % 83 == 0) |
+ frame_data_.input_sample_rate_hz = 8000; |
+ |
+ if (render_count_local == 0) |
+ frame_data_.input_number_of_channels = 1; |
+ else if (render_count_local % 4 == 0) |
+ frame_data_.input_number_of_channels = |
+ (frame_data_.input_number_of_channels == 1 ? 2 : 1); |
+ |
+ if (render_count_local == 0) |
+ frame_data_.output_sample_rate_hz = 16000; |
+ else if (render_count_local % 17 == 0) |
+ frame_data_.output_sample_rate_hz = 32000; |
+ else if (render_count_local % 19 == 0) |
+ frame_data_.output_sample_rate_hz = 48000; |
+ else if (render_count_local % 29 == 0) |
+ frame_data_.output_sample_rate_hz = 16000; |
+ else if (render_count_local % 61 == 0) |
+ frame_data_.output_sample_rate_hz = 8000; |
+ |
+ if (render_count_local == 0) |
+ frame_data_.output_number_of_channels = 1; |
+ else if (render_count_local % 8 == 0) |
+ frame_data_.output_number_of_channels = |
+ (frame_data_.output_number_of_channels == 1 ? 2 : 1); |
+ break; |
+ case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme: |
+ if (render_count_local == 0) { |
+ frame_data_.input_number_of_channels = 1; |
+ frame_data_.input_sample_rate_hz = 16000; |
+ frame_data_.output_number_of_channels = 1; |
+ frame_data_.output_sample_rate_hz = 16000; |
+ } else { |
+ frame_data_.input_number_of_channels = |
+ (frame_data_.input_number_of_channels == 1 ? 2 : 1); |
+ if (frame_data_.input_sample_rate_hz == 8000) |
+ frame_data_.input_sample_rate_hz = 16000; |
+ else if (frame_data_.input_sample_rate_hz == 16000) |
+ frame_data_.input_sample_rate_hz = 32000; |
+ else if (frame_data_.input_sample_rate_hz == 32000) |
+ frame_data_.input_sample_rate_hz = 48000; |
+ else if (frame_data_.input_sample_rate_hz == 48000) |
+ frame_data_.input_sample_rate_hz = 8000; |
+ |
+ frame_data_.output_number_of_channels = |
+ (frame_data_.output_number_of_channels == 1 ? 2 : 1); |
+ if (frame_data_.output_sample_rate_hz == 8000) |
+ frame_data_.output_sample_rate_hz = 16000; |
+ else if (frame_data_.output_sample_rate_hz == 16000) |
+ frame_data_.output_sample_rate_hz = 32000; |
+ else if (frame_data_.output_sample_rate_hz == 32000) |
+ frame_data_.output_sample_rate_hz = 48000; |
+ else if (frame_data_.output_sample_rate_hz == 48000) |
+ frame_data_.output_sample_rate_hz = 8000; |
+ } |
+ break; |
+ case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme: |
+ if (render_count_local == 0) { |
+ frame_data_.input_sample_rate_hz = 16000; |
+ frame_data_.input_number_of_channels = 1; |
+ frame_data_.output_sample_rate_hz = 16000; |
+ frame_data_.output_number_of_channels = 1; |
+ } |
+ break; |
+ case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme: |
+ if (render_count_local == 0) { |
+ frame_data_.input_sample_rate_hz = 16000; |
+ frame_data_.input_number_of_channels = 2; |
+ frame_data_.output_sample_rate_hz = 16000; |
+ frame_data_.output_number_of_channels = 2; |
+ } |
+ break; |
+ default: |
+ FAIL(); |
+ } |
+ |
+ // Restric the number of output channels not to exceed |
+ // the number of input channels. |
+ frame_data_.output_number_of_channels = |
+ std::min(frame_data_.output_number_of_channels, |
+ frame_data_.input_number_of_channels); |
+} |
+ |
+} // anonymous namespace |
+ |
+TEST_P(AudioProcessingImplLockTest, LockTest) { |
+ // Run test and verify that it did not time out. |
+ ASSERT_EQ(kEventSignaled, RunTest()); |
+} |
+ |
+// Instantiate tests from the extreme test configuration set. |
+INSTANTIATE_TEST_CASE_P( |
+ DISABLED_AudioProcessingImplLockExtensive, |
+ AudioProcessingImplLockTest, |
+ ::testing::ValuesIn(TestConfig::GenerateExtensiveTestConfigs())); |
+ |
+INSTANTIATE_TEST_CASE_P( |
+ DISABLED_AudioProcessingImplLockBrief, |
+ AudioProcessingImplLockTest, |
+ ::testing::ValuesIn(TestConfig::GenerateBriefTestConfigs())); |
+ |
+} // namespace webrtc |