Index: webrtc/modules/audio_processing/audio_processing_performance_unittest.cc |
diff --git a/webrtc/modules/audio_processing/audio_processing_performance_unittest.cc b/webrtc/modules/audio_processing/audio_processing_performance_unittest.cc |
deleted file mode 100644 |
index 9da3cd499be1c18e731b587ca095ce5320299e84..0000000000000000000000000000000000000000 |
--- a/webrtc/modules/audio_processing/audio_processing_performance_unittest.cc |
+++ /dev/null |
@@ -1,720 +0,0 @@ |
-/* |
- * 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 <math.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/base/platform_thread.h" |
-#include "webrtc/base/safe_conversions.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/clock.h" |
-#include "webrtc/system_wrappers/include/event_wrapper.h" |
-#include "webrtc/system_wrappers/include/sleep.h" |
-#include "webrtc/test/random.h" |
-#include "webrtc/test/testsupport/perf_test.h" |
- |
-namespace webrtc { |
- |
-namespace { |
- |
-static const bool kPrintAllDurations = false; |
- |
-class CallSimulator; |
- |
-// Type of the render thread APM API call to use in the test. |
-enum class ProcessorType { kRender, kCapture }; |
- |
-// Variant of APM processing settings to use in the test. |
-enum class SettingsType { |
- kDefaultApmDesktop, |
- kDefaultApmMobile, |
- kDefaultApmDesktopAndBeamformer, |
- kDefaultApmDesktopAndIntelligibilityEnhancer, |
- kAllSubmodulesTurnedOff, |
- kDefaultDesktopApmWithoutDelayAgnostic, |
- kDefaultDesktopApmWithoutExtendedFilter |
-}; |
- |
-// Variables related to the audio data and formats. |
-struct AudioFrameData { |
- explicit AudioFrameData(size_t 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]; |
- } |
- |
- std::vector<float> output_frame_channels; |
- std::vector<float*> output_frame; |
- std::vector<float> input_framechannels; |
- std::vector<float*> input_frame; |
- StreamConfig input_stream_config; |
- StreamConfig output_stream_config; |
-}; |
- |
-// The configuration for the test. |
-struct SimulationConfig { |
- SimulationConfig(int sample_rate_hz, SettingsType simulation_settings) |
- : sample_rate_hz(sample_rate_hz), |
- simulation_settings(simulation_settings) {} |
- |
- static std::vector<SimulationConfig> GenerateSimulationConfigs() { |
- std::vector<SimulationConfig> simulation_configs; |
-#ifndef WEBRTC_ANDROID |
- const SettingsType desktop_settings[] = { |
- SettingsType::kDefaultApmDesktop, SettingsType::kAllSubmodulesTurnedOff, |
- SettingsType::kDefaultDesktopApmWithoutDelayAgnostic, |
- SettingsType::kDefaultDesktopApmWithoutExtendedFilter}; |
- |
- const int desktop_sample_rates[] = {8000, 16000, 32000, 48000}; |
- |
- for (auto sample_rate : desktop_sample_rates) { |
- for (auto settings : desktop_settings) { |
- simulation_configs.push_back(SimulationConfig(sample_rate, settings)); |
- } |
- } |
- |
- const SettingsType intelligibility_enhancer_settings[] = { |
- SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer}; |
- |
- const int intelligibility_enhancer_sample_rates[] = {8000, 16000, 32000, |
- 48000}; |
- |
- for (auto sample_rate : intelligibility_enhancer_sample_rates) { |
- for (auto settings : intelligibility_enhancer_settings) { |
- simulation_configs.push_back(SimulationConfig(sample_rate, settings)); |
- } |
- } |
- |
- const SettingsType beamformer_settings[] = { |
- SettingsType::kDefaultApmDesktopAndBeamformer}; |
- |
- const int beamformer_sample_rates[] = {8000, 16000, 32000, 48000}; |
- |
- for (auto sample_rate : beamformer_sample_rates) { |
- for (auto settings : beamformer_settings) { |
- simulation_configs.push_back(SimulationConfig(sample_rate, settings)); |
- } |
- } |
-#endif |
- |
- const SettingsType mobile_settings[] = {SettingsType::kDefaultApmMobile}; |
- |
- const int mobile_sample_rates[] = {8000, 16000}; |
- |
- for (auto sample_rate : mobile_sample_rates) { |
- for (auto settings : mobile_settings) { |
- simulation_configs.push_back(SimulationConfig(sample_rate, settings)); |
- } |
- } |
- |
- return simulation_configs; |
- } |
- |
- std::string SettingsDescription() const { |
- std::string description; |
- switch (simulation_settings) { |
- case SettingsType::kDefaultApmMobile: |
- description = "DefaultApmMobile"; |
- break; |
- case SettingsType::kDefaultApmDesktop: |
- description = "DefaultApmDesktop"; |
- break; |
- case SettingsType::kDefaultApmDesktopAndBeamformer: |
- description = "DefaultApmDesktopAndBeamformer"; |
- break; |
- case SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer: |
- description = "DefaultApmDesktopAndIntelligibilityEnhancer"; |
- break; |
- case SettingsType::kAllSubmodulesTurnedOff: |
- description = "AllSubmodulesOff"; |
- break; |
- case SettingsType::kDefaultDesktopApmWithoutDelayAgnostic: |
- description = "DefaultDesktopApmWithoutDelayAgnostic"; |
- break; |
- case SettingsType::kDefaultDesktopApmWithoutExtendedFilter: |
- description = "DefaultDesktopApmWithoutExtendedFilter"; |
- break; |
- } |
- return description; |
- } |
- |
- int sample_rate_hz = 16000; |
- SettingsType simulation_settings = SettingsType::kDefaultApmDesktop; |
-}; |
- |
-// 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() const { |
- rtc::CritScope cs(&crit_); |
- return capture_count_; |
- } |
- |
- int GetRenderCounter() const { |
- rtc::CritScope cs(&crit_); |
- return render_count_; |
- } |
- |
- int CaptureMinusRenderCounters() const { |
- rtc::CritScope cs(&crit_); |
- return capture_count_ - render_count_; |
- } |
- |
- int RenderMinusCaptureCounters() const { |
- return -CaptureMinusRenderCounters(); |
- } |
- |
- bool BothCountersExceedeThreshold(int threshold) const { |
- rtc::CritScope cs(&crit_); |
- return (render_count_ > threshold && capture_count_ > threshold); |
- } |
- |
- private: |
- mutable rtc::CriticalSection crit_; |
- int render_count_ GUARDED_BY(crit_) = 0; |
- int capture_count_ GUARDED_BY(crit_) = 0; |
-}; |
- |
-// Class that protects a flag using a lock. |
-class LockedFlag { |
- public: |
- bool get_flag() const { |
- rtc::CritScope cs(&crit_); |
- return flag_; |
- } |
- |
- void set_flag() { |
- rtc::CritScope cs(&crit_); |
- flag_ = true; |
- } |
- |
- private: |
- mutable rtc::CriticalSection crit_; |
- bool flag_ GUARDED_BY(crit_) = false; |
-}; |
- |
-// Parent class for the thread processors. |
-class TimedThreadApiProcessor { |
- public: |
- TimedThreadApiProcessor(ProcessorType processor_type, |
- test::Random* rand_gen, |
- FrameCounters* shared_counters_state, |
- LockedFlag* capture_call_checker, |
- CallSimulator* test_framework, |
- const SimulationConfig* simulation_config, |
- AudioProcessing* apm, |
- int num_durations_to_store, |
- float input_level, |
- int num_channels) |
- : rand_gen_(rand_gen), |
- frame_counters_(shared_counters_state), |
- capture_call_checker_(capture_call_checker), |
- test_(test_framework), |
- simulation_config_(simulation_config), |
- apm_(apm), |
- frame_data_(kMaxFrameSize), |
- clock_(webrtc::Clock::GetRealTimeClock()), |
- num_durations_to_store_(num_durations_to_store), |
- input_level_(input_level), |
- processor_type_(processor_type), |
- num_channels_(num_channels) { |
- api_call_durations_.reserve(num_durations_to_store_); |
- } |
- |
- // Implements the callback functionality for the threads. |
- bool Process(); |
- |
- // Method for printing out the simulation statistics. |
- void print_processor_statistics(std::string processor_name) const { |
- const std::string modifier = "_api_call_duration"; |
- |
- // Lambda function for creating a test printout string. |
- auto create_mean_and_std_string = [](int64_t average, |
- int64_t standard_dev) { |
- std::string s = std::to_string(average); |
- s += ", "; |
- s += std::to_string(standard_dev); |
- return s; |
- }; |
- |
- const std::string sample_rate_name = |
- "_" + std::to_string(simulation_config_->sample_rate_hz) + "Hz"; |
- |
- webrtc::test::PrintResultMeanAndError( |
- "apm_timing", sample_rate_name, processor_name, |
- create_mean_and_std_string(GetDurationAverage(), |
- GetDurationStandardDeviation()), |
- "us", false); |
- |
- if (kPrintAllDurations) { |
- std::string value_string = ""; |
- for (int64_t duration : api_call_durations_) { |
- value_string += std::to_string(duration) + ","; |
- } |
- webrtc::test::PrintResultList("apm_call_durations", sample_rate_name, |
- processor_name, value_string, "us", false); |
- } |
- } |
- |
- void AddDuration(int64_t duration) { |
- if (api_call_durations_.size() < num_durations_to_store_) { |
- api_call_durations_.push_back(duration); |
- } |
- } |
- |
- private: |
- static const int kMaxCallDifference = 10; |
- static const int kMaxFrameSize = 480; |
- static const int kNumInitializationFrames = 5; |
- |
- int64_t GetDurationStandardDeviation() const { |
- double variance = 0; |
- const int64_t average_duration = GetDurationAverage(); |
- for (size_t k = kNumInitializationFrames; k < api_call_durations_.size(); |
- k++) { |
- int64_t tmp = api_call_durations_[k] - average_duration; |
- variance += static_cast<double>(tmp * tmp); |
- } |
- const int denominator = rtc::checked_cast<int>(api_call_durations_.size()) - |
- kNumInitializationFrames; |
- return (denominator > 0 |
- ? rtc::checked_cast<int64_t>(sqrt(variance / denominator)) |
- : -1); |
- } |
- |
- int64_t GetDurationAverage() const { |
- int64_t average_duration = 0; |
- for (size_t k = kNumInitializationFrames; k < api_call_durations_.size(); |
- k++) { |
- average_duration += api_call_durations_[k]; |
- } |
- const int denominator = rtc::checked_cast<int>(api_call_durations_.size()) - |
- kNumInitializationFrames; |
- return (denominator > 0 ? average_duration / denominator : -1); |
- } |
- |
- int ProcessCapture() { |
- // Set the stream delay. |
- apm_->set_stream_delay_ms(30); |
- |
- // Call and time the specified capture side API processing method. |
- const int64_t start_time = clock_->TimeInMicroseconds(); |
- const int result = apm_->ProcessStream( |
- &frame_data_.input_frame[0], frame_data_.input_stream_config, |
- frame_data_.output_stream_config, &frame_data_.output_frame[0]); |
- const int64_t end_time = clock_->TimeInMicroseconds(); |
- |
- frame_counters_->IncreaseCaptureCounter(); |
- |
- AddDuration(end_time - start_time); |
- |
- if (first_process_call_) { |
- // 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_->set_flag(); |
- first_process_call_ = false; |
- } |
- return result; |
- } |
- |
- bool ReadyToProcessCapture() { |
- return (frame_counters_->CaptureMinusRenderCounters() <= |
- kMaxCallDifference); |
- } |
- |
- int ProcessRender() { |
- // Call and time the specified render side API processing method. |
- const int64_t start_time = clock_->TimeInMicroseconds(); |
- const int result = apm_->ProcessReverseStream( |
- &frame_data_.input_frame[0], frame_data_.input_stream_config, |
- frame_data_.output_stream_config, &frame_data_.output_frame[0]); |
- const int64_t end_time = clock_->TimeInMicroseconds(); |
- frame_counters_->IncreaseRenderCounter(); |
- |
- AddDuration(end_time - start_time); |
- |
- return result; |
- } |
- |
- bool ReadyToProcessRender() { |
- // Do not process until at least one capture call has been done. |
- // (implicitly required by the APM API). |
- if (first_process_call_ && !capture_call_checker_->get_flag()) { |
- return false; |
- } |
- |
- // Ensure that the number of render and capture calls do not differ too |
- // much. |
- if (frame_counters_->RenderMinusCaptureCounters() > kMaxCallDifference) { |
- return false; |
- } |
- |
- first_process_call_ = false; |
- return true; |
- } |
- |
- void PrepareFrame() { |
- // Lambda function for populating a float multichannel audio frame |
- // with random data. |
- auto populate_audio_frame = [](float amplitude, size_t num_channels, |
- size_t samples_per_channel, |
- test::Random* rand_gen, float** frame) { |
- for (size_t ch = 0; ch < num_channels; ch++) { |
- for (size_t k = 0; k < samples_per_channel; k++) { |
- // Store random float number with a value between +-amplitude. |
- frame[ch][k] = amplitude * (2 * rand_gen->Rand<float>() - 1); |
- } |
- } |
- }; |
- |
- // Prepare the audio input data and metadata. |
- frame_data_.input_stream_config.set_sample_rate_hz( |
- simulation_config_->sample_rate_hz); |
- frame_data_.input_stream_config.set_num_channels(num_channels_); |
- frame_data_.input_stream_config.set_has_keyboard(false); |
- populate_audio_frame(input_level_, num_channels_, |
- (simulation_config_->sample_rate_hz * |
- AudioProcessing::kChunkSizeMs / 1000), |
- rand_gen_, &frame_data_.input_frame[0]); |
- |
- // Prepare the float audio output data and metadata. |
- frame_data_.output_stream_config.set_sample_rate_hz( |
- simulation_config_->sample_rate_hz); |
- frame_data_.output_stream_config.set_num_channels(1); |
- frame_data_.output_stream_config.set_has_keyboard(false); |
- } |
- |
- bool ReadyToProcess() { |
- switch (processor_type_) { |
- case ProcessorType::kRender: |
- return ReadyToProcessRender(); |
- break; |
- case ProcessorType::kCapture: |
- return ReadyToProcessCapture(); |
- break; |
- } |
- |
- // Should not be reached, but the return statement is needed for the code to |
- // build successfully on Android. |
- RTC_NOTREACHED(); |
- return false; |
- } |
- |
- test::Random* rand_gen_ = nullptr; |
- FrameCounters* frame_counters_ = nullptr; |
- LockedFlag* capture_call_checker_ = nullptr; |
- CallSimulator* test_ = nullptr; |
- const SimulationConfig* const simulation_config_ = nullptr; |
- AudioProcessing* apm_ = nullptr; |
- AudioFrameData frame_data_; |
- webrtc::Clock* clock_; |
- const size_t num_durations_to_store_; |
- std::vector<int64_t> api_call_durations_; |
- const float input_level_; |
- bool first_process_call_ = true; |
- const ProcessorType processor_type_; |
- const int num_channels_ = 1; |
-}; |
- |
-// Class for managing the test simulation. |
-class CallSimulator : public ::testing::TestWithParam<SimulationConfig> { |
- public: |
- CallSimulator() |
- : test_complete_(EventWrapper::Create()), |
- render_thread_(PlatformThread::CreateThread(RenderProcessorThreadFunc, |
- this, |
- "render")), |
- capture_thread_(PlatformThread::CreateThread(CaptureProcessorThreadFunc, |
- this, |
- "capture")), |
- rand_gen_(42U), |
- simulation_config_(static_cast<SimulationConfig>(GetParam())) {} |
- |
- // Run the call simulation with a timeout. |
- EventTypeWrapper Run() { |
- StartThreads(); |
- |
- EventTypeWrapper result = test_complete_->Wait(kTestTimeout); |
- |
- render_thread_state_->print_processor_statistics( |
- simulation_config_.SettingsDescription() + "_render"); |
- capture_thread_state_->print_processor_statistics( |
- simulation_config_.SettingsDescription() + "_capture"); |
- |
- return result; |
- } |
- |
- // Tests whether all the required render and capture side calls have been |
- // done. |
- void MaybeEndTest() { |
- if (frame_counters_.BothCountersExceedeThreshold(kMinNumFramesToProcess)) { |
- test_complete_->Set(); |
- } |
- } |
- |
- private: |
- static const float kCaptureInputFloatLevel; |
- static const float kRenderInputFloatLevel; |
- static const int kMinNumFramesToProcess = 150; |
- static const int32_t kTestTimeout = 3 * 10 * kMinNumFramesToProcess; |
- |
- // ::testing::TestWithParam<> implementation. |
- void TearDown() override { |
- render_thread_->Stop(); |
- capture_thread_->Stop(); |
- } |
- |
- // Simulator and APM setup. |
- void SetUp() override { |
- // Lambda function for setting the default APM runtime settings for desktop. |
- auto set_default_desktop_apm_runtime_settings = [](AudioProcessing* apm) { |
- 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::kAdaptiveDigital)); |
- 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)); |
- 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)); |
- }; |
- |
- // Lambda function for setting the default APM runtime settings for mobile. |
- auto set_default_mobile_apm_runtime_settings = [](AudioProcessing* apm) { |
- 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::kAdaptiveDigital)); |
- 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)); |
- ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true)); |
- ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false)); |
- }; |
- |
- // Lambda function for turning off all of the APM runtime settings |
- // submodules. |
- auto turn_off_default_apm_runtime_settings = [](AudioProcessing* apm) { |
- ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, |
- apm->gain_control()->set_mode(GainControl::kAdaptiveDigital)); |
- ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false)); |
- ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->enable_metrics(false)); |
- ASSERT_EQ(apm->kNoError, |
- apm->echo_cancellation()->enable_delay_logging(false)); |
- }; |
- |
- // Lambda function for adding default desktop APM settings to a config. |
- auto add_default_desktop_config = [](Config* config) { |
- config->Set<ExtendedFilter>(new ExtendedFilter(true)); |
- config->Set<DelayAgnostic>(new DelayAgnostic(true)); |
- }; |
- |
- // Lambda function for adding beamformer settings to a config. |
- auto add_beamformer_config = [](Config* config) { |
- const size_t num_mics = 2; |
- const std::vector<Point> array_geometry = |
- ParseArrayGeometry("0 0 0 0.05 0 0", num_mics); |
- RTC_CHECK_EQ(array_geometry.size(), num_mics); |
- |
- config->Set<Beamforming>( |
- new Beamforming(true, array_geometry, |
- SphericalPointf(DegreesToRadians(90), 0.f, 1.f))); |
- }; |
- |
- int num_capture_channels = 1; |
- switch (simulation_config_.simulation_settings) { |
- case SettingsType::kDefaultApmMobile: { |
- apm_.reset(AudioProcessingImpl::Create()); |
- ASSERT_TRUE(!!apm_); |
- set_default_mobile_apm_runtime_settings(apm_.get()); |
- break; |
- } |
- case SettingsType::kDefaultApmDesktop: { |
- Config config; |
- add_default_desktop_config(&config); |
- apm_.reset(AudioProcessingImpl::Create(config)); |
- ASSERT_TRUE(!!apm_); |
- set_default_desktop_apm_runtime_settings(apm_.get()); |
- apm_->SetExtraOptions(config); |
- break; |
- } |
- case SettingsType::kDefaultApmDesktopAndBeamformer: { |
- Config config; |
- add_beamformer_config(&config); |
- add_default_desktop_config(&config); |
- apm_.reset(AudioProcessingImpl::Create(config)); |
- ASSERT_TRUE(!!apm_); |
- set_default_desktop_apm_runtime_settings(apm_.get()); |
- apm_->SetExtraOptions(config); |
- num_capture_channels = 2; |
- break; |
- } |
- case SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer: { |
- Config config; |
- config.Set<Intelligibility>(new Intelligibility(true)); |
- add_default_desktop_config(&config); |
- apm_.reset(AudioProcessingImpl::Create(config)); |
- ASSERT_TRUE(!!apm_); |
- set_default_desktop_apm_runtime_settings(apm_.get()); |
- apm_->SetExtraOptions(config); |
- break; |
- } |
- case SettingsType::kAllSubmodulesTurnedOff: { |
- apm_.reset(AudioProcessingImpl::Create()); |
- ASSERT_TRUE(!!apm_); |
- turn_off_default_apm_runtime_settings(apm_.get()); |
- break; |
- } |
- case SettingsType::kDefaultDesktopApmWithoutDelayAgnostic: { |
- Config config; |
- config.Set<ExtendedFilter>(new ExtendedFilter(true)); |
- config.Set<DelayAgnostic>(new DelayAgnostic(false)); |
- apm_.reset(AudioProcessingImpl::Create(config)); |
- ASSERT_TRUE(!!apm_); |
- set_default_desktop_apm_runtime_settings(apm_.get()); |
- apm_->SetExtraOptions(config); |
- break; |
- } |
- case SettingsType::kDefaultDesktopApmWithoutExtendedFilter: { |
- Config config; |
- config.Set<ExtendedFilter>(new ExtendedFilter(false)); |
- config.Set<DelayAgnostic>(new DelayAgnostic(true)); |
- apm_.reset(AudioProcessingImpl::Create(config)); |
- ASSERT_TRUE(!!apm_); |
- set_default_desktop_apm_runtime_settings(apm_.get()); |
- apm_->SetExtraOptions(config); |
- break; |
- } |
- } |
- |
- render_thread_state_.reset(new TimedThreadApiProcessor( |
- ProcessorType::kRender, &rand_gen_, &frame_counters_, |
- &capture_call_checker_, this, &simulation_config_, apm_.get(), |
- kMinNumFramesToProcess, kRenderInputFloatLevel, 1)); |
- capture_thread_state_.reset(new TimedThreadApiProcessor( |
- ProcessorType::kCapture, &rand_gen_, &frame_counters_, |
- &capture_call_checker_, this, &simulation_config_, apm_.get(), |
- kMinNumFramesToProcess, kCaptureInputFloatLevel, num_capture_channels)); |
- } |
- |
- // Thread callback for the render thread. |
- static bool RenderProcessorThreadFunc(void* context) { |
- return reinterpret_cast<CallSimulator*>(context) |
- ->render_thread_state_->Process(); |
- } |
- |
- // Thread callback for the capture thread. |
- static bool CaptureProcessorThreadFunc(void* context) { |
- return reinterpret_cast<CallSimulator*>(context) |
- ->capture_thread_state_->Process(); |
- } |
- |
- // Start the threads used in the test. |
- void StartThreads() { |
- ASSERT_NO_FATAL_FAILURE(render_thread_->Start()); |
- render_thread_->SetPriority(kRealtimePriority); |
- ASSERT_NO_FATAL_FAILURE(capture_thread_->Start()); |
- capture_thread_->SetPriority(kRealtimePriority); |
- } |
- |
- // Event handler for the test. |
- const rtc::scoped_ptr<EventWrapper> test_complete_; |
- |
- // Thread related variables. |
- rtc::scoped_ptr<PlatformThread> render_thread_; |
- rtc::scoped_ptr<PlatformThread> capture_thread_; |
- test::Random rand_gen_; |
- |
- rtc::scoped_ptr<AudioProcessing> apm_; |
- const SimulationConfig simulation_config_; |
- FrameCounters frame_counters_; |
- LockedFlag capture_call_checker_; |
- rtc::scoped_ptr<TimedThreadApiProcessor> render_thread_state_; |
- rtc::scoped_ptr<TimedThreadApiProcessor> capture_thread_state_; |
-}; |
- |
-// Implements the callback functionality for the threads. |
-bool TimedThreadApiProcessor::Process() { |
- PrepareFrame(); |
- |
- // Wait in a spinlock manner until it is ok to start processing. |
- // Note that SleepMs is not applicable since it only allows sleeping |
- // on a millisecond basis which is too long. |
- while (!ReadyToProcess()) { |
- } |
- |
- int result = AudioProcessing::kNoError; |
- switch (processor_type_) { |
- case ProcessorType::kRender: |
- result = ProcessRender(); |
- break; |
- case ProcessorType::kCapture: |
- result = ProcessCapture(); |
- break; |
- } |
- |
- EXPECT_EQ(result, AudioProcessing::kNoError); |
- |
- test_->MaybeEndTest(); |
- |
- return true; |
-} |
- |
-const float CallSimulator::kRenderInputFloatLevel = 0.5f; |
-const float CallSimulator::kCaptureInputFloatLevel = 0.03125f; |
-} // anonymous namespace |
- |
-TEST_P(CallSimulator, ApiCallDurationTest) { |
- // Run test and verify that it did not time out. |
- EXPECT_EQ(kEventSignaled, Run()); |
-} |
- |
-INSTANTIATE_TEST_CASE_P( |
- AudioProcessingPerformanceTest, |
- CallSimulator, |
- ::testing::ValuesIn(SimulationConfig::GenerateSimulationConfigs())); |
- |
-} // namespace webrtc |