/*
 *  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.
 */

#ifndef MODULES_AUDIO_PROCESSING_AGC2_INTERPOLATED_GAIN_CURVE_H_
#define MODULES_AUDIO_PROCESSING_AGC2_INTERPOLATED_GAIN_CURVE_H_

#include <array>
#include <string>

#include "modules/audio_processing/agc2/agc2_common.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/gtest_prod_util.h"
#include "system_wrappers/include/metrics.h"

namespace webrtc {

class ApmDataDumper;

constexpr float kInputLevelScalingFactor = 32768.0f;

// Defined as DbfsToLinear(kLimiterMaxInputLevelDbFs)
constexpr float kMaxInputLevelLinear = static_cast<float>(36766.300710566735);

// Interpolated gain curve using under-approximation to avoid saturation.
//
// The goal of this class is allowing fast look ups to get an accurate
// estimates of the gain to apply given an estimated input level.
class InterpolatedGainCurve {
 public:
  enum class GainCurveRegion {
    kIdentity = 0,
    kKnee = 1,
    kLimiter = 2,
    kSaturation = 3
  };

  struct Stats {
    // Region in which the output level equals the input one.
    size_t look_ups_identity_region = 0;
    // Smoothing between the identity and the limiter regions.
    size_t look_ups_knee_region = 0;
    // Limiter region in which the output and input levels are linearly related.
    size_t look_ups_limiter_region = 0;
    // Region in which saturation may occur since the input level is beyond the
    // maximum expected by the limiter.
    size_t look_ups_saturation_region = 0;
    // True if stats have been populated.
    bool available = false;

    // The current region, and for how many frames the level has been
    // in that region.
    GainCurveRegion region = GainCurveRegion::kIdentity;
    int64_t region_duration_frames = 0;
  };

  InterpolatedGainCurve(ApmDataDumper* apm_data_dumper,
                        const std::string& histogram_name_prefix);
  ~InterpolatedGainCurve();

  Stats get_stats() const { return stats_; }

  // Given a non-negative input level (linear scale), a scalar factor to apply
  // to a sub-frame is returned.
  // Levels above kLimiterMaxInputLevelDbFs will be reduced to 0 dBFS
  // after applying this gain
  float LookUpGainToApply(float input_level) const;

 private:
  // For comparing 'approximation_params_*_' with ones computed by
  // ComputeInterpolatedGainCurve.
  FRIEND_TEST_ALL_PREFIXES(AutomaticGainController2InterpolatedGainCurve,
                           CheckApproximationParams);

  struct RegionLogger {
    metrics::Histogram* identity_histogram;
    metrics::Histogram* knee_histogram;
    metrics::Histogram* limiter_histogram;
    metrics::Histogram* saturation_histogram;

    RegionLogger(const std::string& identity_histogram_name,
                 const std::string& knee_histogram_name,
                 const std::string& limiter_histogram_name,
                 const std::string& saturation_histogram_name);

    ~RegionLogger();

    void LogRegionStats(const InterpolatedGainCurve::Stats& stats) const;
  } region_logger_;

  void UpdateStats(float input_level) const;

  ApmDataDumper* const apm_data_dumper_;

  static constexpr std::array<float, kInterpolatedGainCurveTotalPoints>
      approximation_params_x_ = {
          {30057.296875,    30148.986328125, 30240.67578125,  30424.052734375,
           30607.4296875,   30790.806640625, 30974.18359375,  31157.560546875,
           31340.939453125, 31524.31640625,  31707.693359375, 31891.0703125,
           32074.447265625, 32257.82421875,  32441.201171875, 32624.580078125,
           32807.95703125,  32991.33203125,  33174.7109375,   33358.08984375,
           33541.46484375,  33724.84375,     33819.53515625,  34009.5390625,
           34200.05859375,  34389.81640625,  34674.48828125,  35054.375,
           35434.86328125,  35814.81640625,  36195.16796875,  36575.03125}};
  static constexpr std::array<float, kInterpolatedGainCurveTotalPoints>
      approximation_params_m_ = {
          {-3.515235675877192989e-07, -1.050251626111275982e-06,
           -2.085213736791047268e-06, -3.443004743530764244e-06,
           -4.773849468620028347e-06, -6.077375928725814447e-06,
           -7.353257842623861507e-06, -8.601219633419532329e-06,
           -9.821013009059242904e-06, -1.101243378798244521e-05,
           -1.217532644659513608e-05, -1.330956911260727793e-05,
           -1.441507538402220234e-05, -1.549179251014720649e-05,
           -1.653970684856176376e-05, -1.755882840370759368e-05,
           -1.854918446042574942e-05, -1.951086778717581183e-05,
           -2.044398024736437947e-05, -2.1348627342376858e-05,
           -2.222496914328075945e-05, -2.265374678245279938e-05,
           -2.242570917587727308e-05, -2.220122041762806475e-05,
           -2.19802095671184361e-05,  -2.176260204578284174e-05,
           -2.133731686626560986e-05, -2.092481918225530535e-05,
           -2.052459603874012828e-05, -2.013615448959171772e-05,
           -1.975903069251216948e-05, -1.939277899509761482e-05}};

  static constexpr std::array<float, kInterpolatedGainCurveTotalPoints>
      approximation_params_q_ = {
          {1.010565876960754395, 1.031631827354431152, 1.062929749488830566,
           1.104239225387573242, 1.144973039627075195, 1.185109615325927734,
           1.224629044532775879, 1.263512492179870605, 1.301741957664489746,
           1.339300632476806641, 1.376173257827758789, 1.412345528602600098,
           1.447803974151611328, 1.482536554336547852, 1.516532182693481445,
           1.549780607223510742, 1.582272171974182129, 1.613999366760253906,
           1.644955039024353027, 1.675132393836975098, 1.704526185989379883,
           1.718986630439758301, 1.711274504661560059, 1.703639745712280273,
           1.696081161499023438, 1.688597679138183594, 1.673851132392883301,
           1.659391283988952637, 1.645209431648254395, 1.631297469139099121,
           1.617647409439086914, 1.604251742362976074}};

  // Stats.
  mutable Stats stats_;

  RTC_DISALLOW_COPY_AND_ASSIGN(InterpolatedGainCurve);
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_PROCESSING_AGC2_INTERPOLATED_GAIN_CURVE_H_
