/*
 *  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 <algorithm>
#include <memory>
#include <vector>

#include "api/array_view.h"
#include "modules/audio_processing/audio_processing_impl.h"
#include "modules/audio_processing/test/test_utils.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/event.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/random.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

class AudioProcessingImplLockTest;

// Type of the render thread APM API call to use in the test.
enum class RenderApiImpl {
  ProcessReverseStreamImplAudioFrame,
  ProcessReverseStreamImplStreamConfig,
  AnalyzeReverseStreamImplStreamConfig,
};

// Type of the capture thread APM API call to use in the test.
enum class CaptureApiImpl {
  ProcessStreamImplAudioFrame,
  ProcessStreamImplStreamConfig
};

// 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
};

// Thread-safe random number generator wrapper.
class RandomGenerator {
 public:
  RandomGenerator() : rand_gen_(42U) {}

  int RandInt(int min, int max) {
    rtc::CritScope cs(&crit_);
    return rand_gen_.Rand(min, max);
  }

  int RandInt(int max) {
    rtc::CritScope cs(&crit_);
    return rand_gen_.Rand(max);
  }

  float RandFloat() {
    rtc::CritScope cs(&crit_);
    return rand_gen_.Rand<float>();
  }

 private:
  rtc::CriticalSection crit_;
  Random rand_gen_ RTC_GUARDED_BY(crit_);
};

// 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 AudioFrame processing API function set.
      test_config.render_api_function =
          RenderApiImpl::ProcessReverseStreamImplAudioFrame;
      test_config.capture_api_function =
          CaptureApiImpl::ProcessStreamImplAudioFrame;
      test_configs.push_back(test_config);

      // Create test config for the StreamConfig processing API function set.
      test_config.render_api_function =
          RenderApiImpl::ProcessReverseStreamImplStreamConfig;
      test_config.capture_api_function =
          CaptureApiImpl::ProcessStreamImplStreamConfig;
      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::ProcessReverseStreamImplAudioFrame,
           CaptureApiImpl::ProcessStreamImplAudioFrame},
          {RenderApiImpl::ProcessReverseStreamImplStreamConfig,
           CaptureApiImpl::ProcessStreamImplStreamConfig},
          {RenderApiImpl::AnalyzeReverseStreamImplStreamConfig,
           CaptureApiImpl::ProcessStreamImplStreamConfig},
          {RenderApiImpl::ProcessReverseStreamImplAudioFrame,
           CaptureApiImpl::ProcessStreamImplStreamConfig},
          {RenderApiImpl::ProcessReverseStreamImplStreamConfig,
           CaptureApiImpl::ProcessStreamImplAudioFrame}};
      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) {
        // Due to a VisualStudio 2015 compiler issue, the internal loop
        // variable here cannot override a previously defined name.
        // In other words "type" cannot be named "aec_type" here.
        // https://connect.microsoft.com/VisualStudio/feedback/details/2291755
        for (auto type : aec_types) {
          test_config.aec_type = 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::ProcessReverseStreamImplStreamConfig;
  CaptureApiImpl capture_api_function =
      CaptureApiImpl::ProcessStreamImplStreamConfig;
  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() 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) {
    rtc::CritScope cs(&crit_);
    return (render_count > threshold && capture_count > threshold);
  }

 private:
  rtc::CriticalSection crit_;
  int render_count RTC_GUARDED_BY(crit_) = 0;
  int capture_count RTC_GUARDED_BY(crit_) = 0;
};

// Class for handling the capture side processing.
class CaptureProcessor {
 public:
  CaptureProcessor(int max_frame_size,
                   RandomGenerator* rand_gen,
                   rtc::Event* render_call_event,
                   rtc::Event* capture_call_event,
                   FrameCounters* shared_counters_state,
                   TestConfig* test_config,
                   AudioProcessing* apm);
  void Process();

 private:
  static const int kMaxCallDifference = 10;
  static const float kCaptureInputFloatLevel;
  static const int kCaptureInputFixLevel = 1024;

  void PrepareFrame();
  void CallApmCaptureSide();
  void ApplyRuntimeSettingScheme();

  RandomGenerator* const rand_gen_ = nullptr;
  rtc::Event* const render_call_event_ = nullptr;
  rtc::Event* const capture_call_event_ = nullptr;
  FrameCounters* const frame_counters_ = nullptr;
  const TestConfig* const test_config_ = nullptr;
  AudioProcessing* const apm_ = nullptr;
  AudioFrameData frame_data_;
};

// Class for handling the stats processing.
class StatsProcessor {
 public:
  StatsProcessor(RandomGenerator* rand_gen,
                 TestConfig* test_config,
                 AudioProcessing* apm);
  void Process();

 private:
  RandomGenerator* 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,
                  RandomGenerator* rand_gen,
                  rtc::Event* render_call_event,
                  rtc::Event* capture_call_event,
                  FrameCounters* shared_counters_state,
                  TestConfig* test_config,
                  AudioProcessing* apm);
  void Process();

 private:
  static const int kMaxCallDifference = 10;
  static const int kRenderInputFixLevel = 16384;
  static const float kRenderInputFloatLevel;

  void PrepareFrame();
  void CallApmRenderSide();
  void ApplyRuntimeSettingScheme();

  RandomGenerator* const rand_gen_ = nullptr;
  rtc::Event* const render_call_event_ = nullptr;
  rtc::Event* const capture_call_event_ = nullptr;
  FrameCounters* const frame_counters_ = nullptr;
  const TestConfig* const test_config_ = nullptr;
  AudioProcessing* const apm_ = nullptr;
  AudioFrameData frame_data_;
  bool first_render_call_ = true;
};

class AudioProcessingImplLockTest
    : public ::testing::TestWithParam<TestConfig> {
 public:
  AudioProcessingImplLockTest();
  bool RunTest();
  bool MaybeEndTest();

 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 void RenderProcessorThreadFunc(void* context) {
    AudioProcessingImplLockTest* impl =
        reinterpret_cast<AudioProcessingImplLockTest*>(context);
    while (!impl->MaybeEndTest()) {
      impl->render_thread_state_.Process();
    }
  }

  // Thread callback for the capture thread
  static void CaptureProcessorThreadFunc(void* context) {
    AudioProcessingImplLockTest* impl =
        reinterpret_cast<AudioProcessingImplLockTest*>(context);
    while (!impl->MaybeEndTest()) {
      impl->capture_thread_state_.Process();
    }
  }

  // Thread callback for the stats thread
  static void StatsProcessorThreadFunc(void* context) {
    AudioProcessingImplLockTest* impl =
        reinterpret_cast<AudioProcessingImplLockTest*>(context);
    while (!impl->MaybeEndTest()) {
      impl->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() {
    render_thread_.Start();
    capture_thread_.Start();
    stats_thread_.Start();
  }

  // Event handlers for the test.
  rtc::Event test_complete_;
  rtc::Event render_call_event_;
  rtc::Event capture_call_event_;

  // Thread related variables.
  rtc::PlatformThread render_thread_;
  rtc::PlatformThread capture_thread_;
  rtc::PlatformThread stats_thread_;
  mutable RandomGenerator rand_gen_;

  std::unique_ptr<AudioProcessing> apm_;
  TestConfig test_config_;
  FrameCounters frame_counters_;
  RenderProcessor render_thread_state_;
  CaptureProcessor capture_thread_state_;
  StatsProcessor stats_thread_state_;
};

// Sleeps a random time between 0 and max_sleep milliseconds.
void SleepRandomMs(int max_sleep, RandomGenerator* rand_gen) {
  int sleeptime = rand_gen->RandInt(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,
                        RandomGenerator* 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->RandFloat() - 1);
    }
  }
}

// Populates an audioframe frame of AudioFrame type with random data.
void PopulateAudioFrame(AudioFrame* frame,
                        int16_t amplitude,
                        RandomGenerator* rand_gen) {
  ASSERT_GT(amplitude, 0);
  ASSERT_LE(amplitude, 32767);
  int16_t* frame_data = frame->mutable_data();
  for (size_t ch = 0; ch < frame->num_channels_; ch++) {
    for (size_t k = 0; k < frame->samples_per_channel_; k++) {
      // Store random 16 bit number between -(amplitude+1) and
      // amplitude.
      frame_data[k * ch] = rand_gen->RandInt(2 * amplitude + 1) - amplitude - 1;
    }
  }
}

AudioProcessingImplLockTest::AudioProcessingImplLockTest()
    : render_thread_(RenderProcessorThreadFunc,
                     this,
                     "render",
                     rtc::kRealtimePriority),
      capture_thread_(CaptureProcessorThreadFunc,
                      this,
                      "capture",
                      rtc::kRealtimePriority),
      stats_thread_(StatsProcessorThreadFunc,
                    this,
                    "stats",
                    rtc::kNormalPriority),
      apm_(AudioProcessingBuilder().Create()),
      render_thread_state_(kMaxFrameSize,
                           &rand_gen_,
                           &render_call_event_,
                           &capture_call_event_,
                           &frame_counters_,
                           &test_config_,
                           apm_.get()),
      capture_thread_state_(kMaxFrameSize,
                            &rand_gen_,
                            &render_call_event_,
                            &capture_call_event_,
                            &frame_counters_,
                            &test_config_,
                            apm_.get()),
      stats_thread_state_(&rand_gen_, &test_config_, apm_.get()) {}

// Run the test with a timeout.
bool AudioProcessingImplLockTest::RunTest() {
  StartThreads();
  return test_complete_.Wait(kTestTimeOutLimit);
}

bool AudioProcessingImplLockTest::MaybeEndTest() {
  if (HasFatalFailure() || TestDone()) {
    test_complete_.Set();
    return true;
  }
  return false;
}

// Setup of test and APM.
void AudioProcessingImplLockTest::SetUp() {
  test_config_ = static_cast<TestConfig>(GetParam());

  AudioProcessing::Config apm_config = apm_->GetConfig();
  apm_config.echo_canceller.enabled =
      (test_config_.aec_type != AecType::AecTurnedOff);
  apm_config.echo_canceller.mobile_mode =
      (test_config_.aec_type == AecType::BasicWebRtcAecSettingsWithAecMobile);
  apm_config.gain_controller1.enabled = true;
  apm_config.gain_controller1.mode =
      AudioProcessing::Config::GainController1::kAdaptiveDigital;
  apm_config.noise_suppression.enabled = true;
  apm_config.voice_detection.enabled = true;
  apm_config.level_estimation.enabled = true;
  apm_->ApplyConfig(apm_config);

  Config config;
  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_call_event_.Set();
  capture_call_event_.Set();
  render_thread_.Stop();
  capture_thread_.Stop();
  stats_thread_.Stop();
}

StatsProcessor::StatsProcessor(RandomGenerator* 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.
void StatsProcessor::Process() {
  SleepRandomMs(100, rand_gen_);

  AudioProcessing::Config apm_config = apm_->GetConfig();
  if (test_config_->aec_type != AecType::AecTurnedOff) {
    EXPECT_TRUE(apm_config.echo_canceller.enabled);
    EXPECT_EQ(apm_config.echo_canceller.mobile_mode,
              (test_config_->aec_type ==
               AecType::BasicWebRtcAecSettingsWithAecMobile));
  } else {
    EXPECT_FALSE(apm_config.echo_canceller.enabled);
  }
  EXPECT_TRUE(apm_config.gain_controller1.enabled);
  EXPECT_TRUE(apm_config.noise_suppression.enabled);

  // The below return value is not testable.
  apm_->GetStatistics(/*has_remote_tracks=*/true);
}

const float CaptureProcessor::kCaptureInputFloatLevel = 0.03125f;

CaptureProcessor::CaptureProcessor(int max_frame_size,
                                   RandomGenerator* rand_gen,
                                   rtc::Event* render_call_event,
                                   rtc::Event* capture_call_event,
                                   FrameCounters* shared_counters_state,
                                   TestConfig* test_config,
                                   AudioProcessing* apm)
    : rand_gen_(rand_gen),
      render_call_event_(render_call_event),
      capture_call_event_(capture_call_event),
      frame_counters_(shared_counters_state),
      test_config_(test_config),
      apm_(apm),
      frame_data_(max_frame_size) {}

// Implements the callback functionality for the capture thread.
void CaptureProcessor::Process() {
  // Sleep a random time to simulate thread jitter.
  SleepRandomMs(3, rand_gen_);

  // Ensure that the number of render and capture calls do not
  // differ too much.
  if (frame_counters_->CaptureMinusRenderCounters() > kMaxCallDifference) {
    render_call_event_->Wait(rtc::Event::kForever);
  }

  // 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 to the render thread that another capture API call has occurred
  // by triggering this threads call event.
  capture_call_event_->Set();
}

// 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::ProcessStreamImplAudioFrame) {
    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);

  // Set the analog level.
  apm_->set_stream_analog_level(80);

  // Call the specified capture side API processing method.
  int result = AudioProcessing::kNoError;
  switch (test_config_->capture_api_function) {
    case CaptureApiImpl::ProcessStreamImplAudioFrame:
      result = apm_->ProcessStream(&frame_data_.frame);
      break;
    case CaptureApiImpl::ProcessStreamImplStreamConfig:
      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();
  }

  // Retrieve the new analog level.
  apm_->recommended_stream_analog_level();

  // 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_delay_offset_ms(15);
        EXPECT_EQ(apm_->delay_offset_ms(), 15);
      } else {
        ASSERT_EQ(AudioProcessing::Error::kNoError,
                  apm_->set_stream_delay_ms(50));
        apm_->set_stream_key_pressed(false);
        apm_->set_delay_offset_ms(20);
        EXPECT_EQ(apm_->delay_offset_ms(), 20);
        apm_->delay_offset_ms();
      }
      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,
                                 RandomGenerator* rand_gen,
                                 rtc::Event* render_call_event,
                                 rtc::Event* capture_call_event,
                                 FrameCounters* shared_counters_state,
                                 TestConfig* test_config,
                                 AudioProcessing* apm)
    : rand_gen_(rand_gen),
      render_call_event_(render_call_event),
      capture_call_event_(capture_call_event),
      frame_counters_(shared_counters_state),
      test_config_(test_config),
      apm_(apm),
      frame_data_(max_frame_size) {}

// Implements the callback functionality for the render thread.
void 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_call_) {
    capture_call_event_->Wait(rtc::Event::kForever);
    first_render_call_ = false;
  }

  // Sleep a random time to simulate thread jitter.
  SleepRandomMs(3, rand_gen_);

  // Ensure that the number of render and capture calls do not
  // differ too much.
  if (frame_counters_->RenderMinusCaptureCounters() > kMaxCallDifference) {
    capture_call_event_->Wait(rtc::Event::kForever);
  }

  // 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();

  // Flag to the capture thread that another render API call has occurred
  // by triggering this threads call event.
  render_call_event_->Set();
}

// 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::ProcessReverseStreamImplAudioFrame) ||
      (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::ProcessReverseStreamImplAudioFrame:
      result = apm_->ProcessReverseStream(&frame_data_.frame);
      break;
    case RenderApiImpl::ProcessReverseStreamImplStreamConfig:
      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::AnalyzeReverseStreamImplStreamConfig:
      result = apm_->AnalyzeReverseStream(&frame_data_.input_frame[0],
                                          frame_data_.input_stream_config);
      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_TRUE(RunTest());
}

// Instantiate tests from the extreme test configuration set.
INSTANTIATE_TEST_SUITE_P(
    DISABLED_AudioProcessingImplLockExtensive,
    AudioProcessingImplLockTest,
    ::testing::ValuesIn(TestConfig::GenerateExtensiveTestConfigs()));

INSTANTIATE_TEST_SUITE_P(
    AudioProcessingImplLockBrief,
    AudioProcessingImplLockTest,
    ::testing::ValuesIn(TestConfig::GenerateBriefTestConfigs()));

}  // namespace webrtc
