/*
 *  Copyright (c) 2018 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 "modules/audio_processing/agc2/fixed_gain_controller.h"

#include <algorithm>
#include <cmath>

#include "api/array_view.h"
#include "common_audio/include/audio_util.h"
#include "modules/audio_processing/agc2/agc2_common.h"
#include "modules/audio_processing/agc2/interpolated_gain_curve.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_minmax.h"

namespace webrtc {
namespace {

// Returns true when the gain factor is so close to 1 that it would
// not affect int16 samples.
bool CloseToOne(float gain_factor) {
  return 1.f - 1.f / kMaxFloatS16Value <= gain_factor &&
         gain_factor <= 1.f + 1.f / kMaxFloatS16Value;
}
}  // namespace

FixedGainController::FixedGainController(ApmDataDumper* apm_data_dumper)
    : apm_data_dumper_(apm_data_dumper),
      gain_curve_applier_(48000, apm_data_dumper_) {}

void FixedGainController::SetGain(float gain_to_apply_db) {
  // Changes in gain_to_apply_ cause discontinuities. We assume
  // gain_to_apply_ is set in the beginning of the call. If it is
  // frequently changed, we should add interpolation between the
  // values.
  // The gain
  RTC_DCHECK_LE(-50.f, gain_to_apply_db);
  RTC_DCHECK_LE(gain_to_apply_db, 50.f);
  gain_to_apply_ = DbToRatio(gain_to_apply_db);
  RTC_DCHECK_LT(0.f, gain_to_apply_);
  RTC_DLOG(LS_INFO) << "Gain to apply: " << gain_to_apply_db << " db.";
}

void FixedGainController::SetSampleRate(size_t sample_rate_hz) {
  gain_curve_applier_.SetSampleRate(sample_rate_hz);
}

void FixedGainController::Process(AudioFrameView<float> signal) {
  // Apply fixed digital gain. One of the
  // planned usages of the FGC is to only use the limiter. In that
  // case, the gain would be 1.0. Not doing the multiplications speeds
  // it up considerably. Hence the check.
  if (!CloseToOne(gain_to_apply_)) {
    for (size_t k = 0; k < signal.num_channels(); ++k) {
      rtc::ArrayView<float> channel_view = signal.channel(k);
      for (auto& sample : channel_view) {
        sample *= gain_to_apply_;
      }
    }
  }

  // Use the limiter.
  gain_curve_applier_.Process(signal);

  // Dump data for debug.
  const auto channel_view = signal.channel(0);
  apm_data_dumper_->DumpRaw("agc2_fixed_digital_gain_curve_applier",
                            channel_view.size(), channel_view.data());
  // Hard-clipping.
  for (size_t k = 0; k < signal.num_channels(); ++k) {
    rtc::ArrayView<float> channel_view = signal.channel(k);
    for (auto& sample : channel_view) {
      sample = rtc::SafeClamp(sample, kMinFloatS16Value, kMaxFloatS16Value);
    }
  }
}
}  // namespace webrtc
