/*
 *  Copyright (c) 2016 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/level_controller/gain_selector.h"

#include <math.h>
#include <algorithm>

#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/audio_processing/level_controller/level_controller_constants.h"
#include "webrtc/rtc_base/checks.h"

namespace webrtc {

GainSelector::GainSelector() {
  Initialize(AudioProcessing::kSampleRate48kHz);
}

void GainSelector::Initialize(int sample_rate_hz) {
  gain_ = 1.f;
  frame_length_ = rtc::CheckedDivExact(sample_rate_hz, 100);
  highly_nonstationary_signal_hold_counter_ = 0;
}

// Chooses the gain to apply by the level controller such that
// 1) The level of the stationary noise does not exceed
//    a predefined threshold.
// 2) The gain does not exceed the gain that has been found
//    to saturate the signal.
// 3) The peak level achieves the target peak level.
// 4) The gain is not below 1.
// 4) The gain is 1 if the signal has been classified as stationary
//    for a long time.
// 5) The gain is not above the maximum gain.
float GainSelector::GetNewGain(float peak_level,
                               float noise_energy,
                               float saturating_gain,
                               bool gain_jumpstart,
                               SignalClassifier::SignalType signal_type) {
  RTC_DCHECK_LT(0.f, peak_level);

  if (signal_type == SignalClassifier::SignalType::kHighlyNonStationary ||
      gain_jumpstart) {
    highly_nonstationary_signal_hold_counter_ = 100;
  } else {
    highly_nonstationary_signal_hold_counter_ =
        std::max(0, highly_nonstationary_signal_hold_counter_ - 1);
  }

  float desired_gain;
  if (highly_nonstationary_signal_hold_counter_ > 0) {
    // Compute a desired gain that ensures that the peak level is amplified to
    // the target level.
    desired_gain = kTargetLcPeakLevel / peak_level;

    // Limit the desired gain so that it does not amplify the noise too much.
    float max_noise_energy = kMaxLcNoisePower * frame_length_;
    if (noise_energy * desired_gain * desired_gain > max_noise_energy) {
      RTC_DCHECK_LE(0.f, noise_energy);
      desired_gain = sqrtf(max_noise_energy / noise_energy);
    }
  } else {
    // If the signal has been stationary for a long while, apply a gain of 1 to
    // avoid amplifying pure noise.
    desired_gain = 1.0f;
  }

  // Smootly update the gain towards the desired gain.
  gain_ += 0.2f * (desired_gain - gain_);

  // Limit the gain to not exceed the maximum and the saturating gains, and to
  // ensure that the lowest possible gain is 1.
  gain_ = std::min(gain_, saturating_gain);
  gain_ = std::min(gain_, kMaxLcGain);
  gain_ = std::max(gain_, 1.f);

  return gain_;
}

}  // namespace webrtc
