/*
 *  Copyright (c) 2012 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_CODING_NETEQ_BACKGROUND_NOISE_H_
#define MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_

#include <string.h>  // size_t

#include <memory>

#include "api/array_view.h"
#include "rtc_base/constructor_magic.h"

namespace webrtc {

// Forward declarations.
class AudioMultiVector;
class PostDecodeVad;

// This class handles estimation of background noise parameters.
class BackgroundNoise {
 public:
  // TODO(hlundin): For 48 kHz support, increase kMaxLpcOrder to 10.
  // Will work anyway, but probably sound a little worse.
  static constexpr size_t kMaxLpcOrder = 8;  // 32000 / 8000 + 4.

  explicit BackgroundNoise(size_t num_channels);
  virtual ~BackgroundNoise();

  void Reset();

  // Updates the parameter estimates based on the signal currently in the
  // `sync_buffer`, and on the latest decision in `vad` if it is running.
  // Returns true if the filter parameters are updated.
  bool Update(const AudioMultiVector& sync_buffer, const PostDecodeVad& vad);

  // Generates background noise given a random vector and writes the output to
  // `buffer`.
  void GenerateBackgroundNoise(rtc::ArrayView<const int16_t> random_vector,
                               size_t channel,
                               int mute_slope,
                               bool too_many_expands,
                               size_t num_noise_samples,
                               int16_t* buffer);

  // Returns `energy_` for `channel`.
  int32_t Energy(size_t channel) const;

  // Sets the value of `mute_factor_` for `channel` to `value`.
  void SetMuteFactor(size_t channel, int16_t value);

  // Returns `mute_factor_` for `channel`.
  int16_t MuteFactor(size_t channel) const;

  // Returns a pointer to `filter_` for `channel`.
  const int16_t* Filter(size_t channel) const;

  // Returns a pointer to `filter_state_` for `channel`.
  const int16_t* FilterState(size_t channel) const;

  // Copies `input` to the filter state. Will not copy more than `kMaxLpcOrder`
  // elements.
  void SetFilterState(size_t channel, rtc::ArrayView<const int16_t> input);

  // Returns `scale_` for `channel`.
  int16_t Scale(size_t channel) const;

  // Returns `scale_shift_` for `channel`.
  int16_t ScaleShift(size_t channel) const;

  // Accessors.
  bool initialized() const { return initialized_; }

 private:
  static const int kThresholdIncrement = 229;  // 0.0035 in Q16.
  static const size_t kVecLen = 256;
  static const int kLogVecLen = 8;  // log2(kVecLen).
  static const size_t kResidualLength = 64;
  static const int16_t kLogResidualLength = 6;  // log2(kResidualLength)

  struct ChannelParameters {
    // Constructor.
    ChannelParameters() { Reset(); }

    void Reset() {
      energy = 2500;
      max_energy = 0;
      energy_update_threshold = 500000;
      low_energy_update_threshold = 0;
      memset(filter_state, 0, sizeof(filter_state));
      memset(filter, 0, sizeof(filter));
      filter[0] = 4096;
      mute_factor = 0;
      scale = 20000;
      scale_shift = 24;
    }

    int32_t energy;
    int32_t max_energy;
    int32_t energy_update_threshold;
    int32_t low_energy_update_threshold;
    int16_t filter_state[kMaxLpcOrder];
    int16_t filter[kMaxLpcOrder + 1];
    int16_t mute_factor;
    int16_t scale;
    int16_t scale_shift;
  };

  int32_t CalculateAutoCorrelation(const int16_t* signal,
                                   size_t length,
                                   int32_t* auto_correlation) const;

  // Increments the energy threshold by a factor 1 + `kThresholdIncrement`.
  void IncrementEnergyThreshold(size_t channel, int32_t sample_energy);

  // Updates the filter parameters.
  void SaveParameters(size_t channel,
                      const int16_t* lpc_coefficients,
                      const int16_t* filter_state,
                      int32_t sample_energy,
                      int32_t residual_energy);

  size_t num_channels_;
  std::unique_ptr<ChannelParameters[]> channel_parameters_;
  bool initialized_;

  RTC_DISALLOW_COPY_AND_ASSIGN(BackgroundNoise);
};

}  // namespace webrtc
#endif  // MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
