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

#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"

#include <algorithm>

#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/rtc_base/safe_conversions.h"

namespace webrtc {

namespace {

const size_t kCngMaxOutsizeOrder = 640;

// TODO(ossu): Rename the left-over WebRtcCng according to style guide.
void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a);

const int32_t WebRtcCng_kDbov[94] = {
  1081109975, 858756178, 682134279, 541838517, 430397633, 341876992,
  271562548,  215709799, 171344384, 136103682, 108110997, 85875618,
  68213428,   54183852,  43039763,  34187699,  27156255,  21570980,
  17134438,   13610368,  10811100,  8587562,   6821343,   5418385,
  4303976,    3418770,   2715625,   2157098,   1713444,   1361037,
  1081110,    858756,    682134,    541839,    430398,    341877,
  271563,     215710,    171344,    136104,    108111,    85876,
  68213,      54184,     43040,     34188,     27156,     21571,
  17134,      13610,     10811,     8588,      6821,      5418,
  4304,       3419,      2716,      2157,      1713,      1361,
  1081,       859,       682,       542,       430,       342,
  272,        216,       171,       136,       108,       86,
  68,         54,        43,        34,        27,        22,
  17,         14,        11,        9,         7,         5,
  4,          3,         3,         2,         2,         1,
  1,          1,         1,         1
};

const int16_t WebRtcCng_kCorrWindow[WEBRTC_CNG_MAX_LPC_ORDER] = {
  32702, 32636, 32570, 32505, 32439, 32374,
  32309, 32244, 32179, 32114, 32049, 31985
};

}  // namespace

ComfortNoiseDecoder::ComfortNoiseDecoder() {
  /* Needed to get the right function pointers in SPLIB. */
  WebRtcSpl_Init();
  Reset();
}

void ComfortNoiseDecoder::Reset() {
  dec_seed_ = 7777;  /* For debugging only. */
  dec_target_energy_ = 0;
  dec_used_energy_ = 0;
  for (auto& c : dec_target_reflCoefs_)
    c = 0;
  for (auto& c : dec_used_reflCoefs_)
    c = 0;
  for (auto& c : dec_filtstate_)
    c = 0;
  for (auto& c : dec_filtstateLow_)
    c = 0;
  dec_order_ = 5;
  dec_target_scale_factor_ = 0;
  dec_used_scale_factor_ = 0;
}

void ComfortNoiseDecoder::UpdateSid(rtc::ArrayView<const uint8_t> sid) {
  int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER];
  int32_t targetEnergy;
  size_t length = sid.size();
  /* Throw away reflection coefficients of higher order than we can handle. */
  if (length > (WEBRTC_CNG_MAX_LPC_ORDER + 1))
    length = WEBRTC_CNG_MAX_LPC_ORDER + 1;

  dec_order_ = static_cast<uint16_t>(length - 1);

  uint8_t sid0 = std::min<uint8_t>(sid[0], 93);
  targetEnergy = WebRtcCng_kDbov[sid0];
  /* Take down target energy to 75%. */
  targetEnergy = targetEnergy >> 1;
  targetEnergy += targetEnergy >> 2;

  dec_target_energy_ = targetEnergy;

  /* Reconstruct coeffs with tweak for WebRtc implementation of RFC3389. */
  if (dec_order_ == WEBRTC_CNG_MAX_LPC_ORDER) {
    for (size_t i = 0; i < (dec_order_); i++) {
      refCs[i] = sid[i + 1] << 8; /* Q7 to Q15*/
      dec_target_reflCoefs_[i] = refCs[i];
    }
  } else {
    for (size_t i = 0; i < (dec_order_); i++) {
      refCs[i] = (sid[i + 1] - 127) << 8; /* Q7 to Q15. */
      dec_target_reflCoefs_[i] = refCs[i];
    }
  }

  for (size_t i = (dec_order_); i < WEBRTC_CNG_MAX_LPC_ORDER; i++) {
    refCs[i] = 0;
    dec_target_reflCoefs_[i] = refCs[i];
  }
}

bool ComfortNoiseDecoder::Generate(rtc::ArrayView<int16_t> out_data,
                                   bool new_period) {
  int16_t excitation[kCngMaxOutsizeOrder];
  int16_t low[kCngMaxOutsizeOrder];
  int16_t lpPoly[WEBRTC_CNG_MAX_LPC_ORDER + 1];
  int16_t ReflBetaStd = 26214;  /* 0.8 in q15. */
  int16_t ReflBetaCompStd = 6553;  /* 0.2 in q15. */
  int16_t ReflBetaNewP = 19661;  /* 0.6 in q15. */
  int16_t ReflBetaCompNewP = 13107;  /* 0.4 in q15. */
  int16_t Beta, BetaC;  /* These are in Q15. */
  int32_t targetEnergy;
  int16_t En;
  int16_t temp16;
  const size_t num_samples = out_data.size();

  if (num_samples > kCngMaxOutsizeOrder) {
    return false;
  }

  if (new_period) {
    dec_used_scale_factor_ = dec_target_scale_factor_;
    Beta = ReflBetaNewP;
    BetaC = ReflBetaCompNewP;
  } else {
    Beta = ReflBetaStd;
    BetaC = ReflBetaCompStd;
  }

  /* Calculate new scale factor in Q13 */
  dec_used_scale_factor_ =
      rtc::checked_cast<int16_t>(
          WEBRTC_SPL_MUL_16_16_RSFT(dec_used_scale_factor_, Beta >> 2, 13) +
          WEBRTC_SPL_MUL_16_16_RSFT(dec_target_scale_factor_, BetaC >> 2, 13));

  dec_used_energy_  = dec_used_energy_ >> 1;
  dec_used_energy_ += dec_target_energy_ >> 1;

  /* Do the same for the reflection coeffs, albeit in Q15. */
  for (size_t i = 0; i < WEBRTC_CNG_MAX_LPC_ORDER; i++) {
    dec_used_reflCoefs_[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
        dec_used_reflCoefs_[i], Beta, 15);
    dec_used_reflCoefs_[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
        dec_target_reflCoefs_[i], BetaC, 15);
  }

  /* Compute the polynomial coefficients. */
  WebRtcCng_K2a16(dec_used_reflCoefs_, WEBRTC_CNG_MAX_LPC_ORDER, lpPoly);


  targetEnergy = dec_used_energy_;

  /* Calculate scaling factor based on filter energy. */
  En = 8192;  /* 1.0 in Q13. */
  for (size_t i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER); i++) {
    /* Floating point value for reference.
       E *= 1.0 - (dec_used_reflCoefs_[i] / 32768.0) *
       (dec_used_reflCoefs_[i] / 32768.0);
     */

    /* Same in fixed point. */
    /* K(i).^2 in Q15. */
    temp16 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
        dec_used_reflCoefs_[i], dec_used_reflCoefs_[i], 15);
    /* 1 - K(i).^2 in Q15. */
    temp16 = 0x7fff - temp16;
    En = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(En, temp16, 15);
  }

  /* float scaling= sqrt(E * dec_target_energy_ / (1 << 24)); */

  /* Calculate sqrt(En * target_energy / excitation energy) */
  targetEnergy = WebRtcSpl_Sqrt(dec_used_energy_);

  En = (int16_t) WebRtcSpl_Sqrt(En) << 6;
  En = (En * 3) >> 1;  /* 1.5 estimates sqrt(2). */
  dec_used_scale_factor_ = (int16_t)((En * targetEnergy) >> 12);

  /* Generate excitation. */
  /* Excitation energy per sample is 2.^24 - Q13 N(0,1). */
  for (size_t i = 0; i < num_samples; i++) {
    excitation[i] = WebRtcSpl_RandN(&dec_seed_) >> 1;
  }

  /* Scale to correct energy. */
  WebRtcSpl_ScaleVector(excitation, excitation, dec_used_scale_factor_,
                        num_samples, 13);

  /* |lpPoly| - Coefficients in Q12.
   * |excitation| - Speech samples.
   * |nst->dec_filtstate| - State preservation.
   * |out_data| - Filtered speech samples. */
  WebRtcSpl_FilterAR(lpPoly, WEBRTC_CNG_MAX_LPC_ORDER + 1, excitation,
                     num_samples, dec_filtstate_, WEBRTC_CNG_MAX_LPC_ORDER,
                     dec_filtstateLow_, WEBRTC_CNG_MAX_LPC_ORDER,
                     out_data.data(), low, num_samples);

  return true;
}

ComfortNoiseEncoder::ComfortNoiseEncoder(int fs, int interval, int quality)
    : enc_nrOfCoefs_(quality),
      enc_sampfreq_(fs),
      enc_interval_(interval),
      enc_msSinceSid_(0),
      enc_Energy_(0),
      enc_reflCoefs_{0},
      enc_corrVector_{0},
      enc_seed_(7777)  /* For debugging only. */ {
  RTC_CHECK_GT(quality, 0);
  RTC_CHECK_LE(quality, WEBRTC_CNG_MAX_LPC_ORDER);
  /* Needed to get the right function pointers in SPLIB. */
  WebRtcSpl_Init();
}

void ComfortNoiseEncoder::Reset(int fs, int interval, int quality) {
  RTC_CHECK_GT(quality, 0);
  RTC_CHECK_LE(quality, WEBRTC_CNG_MAX_LPC_ORDER);
  enc_nrOfCoefs_ = quality;
  enc_sampfreq_ = fs;
  enc_interval_ = interval;
  enc_msSinceSid_ = 0;
  enc_Energy_ = 0;
  for (auto& c : enc_reflCoefs_)
    c = 0;
  for (auto& c : enc_corrVector_)
    c = 0;
  enc_seed_ = 7777;  /* For debugging only. */
}

size_t ComfortNoiseEncoder::Encode(rtc::ArrayView<const int16_t> speech,
                                   bool force_sid,
                                   rtc::Buffer* output) {
  int16_t arCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
  int32_t corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1];
  int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
  int16_t hanningW[kCngMaxOutsizeOrder];
  int16_t ReflBeta = 19661;     /* 0.6 in q15. */
  int16_t ReflBetaComp = 13107; /* 0.4 in q15. */
  int32_t outEnergy;
  int outShifts;
  size_t i;
  int stab;
  int acorrScale;
  size_t index;
  size_t ind, factor;
  int32_t* bptr;
  int32_t blo, bhi;
  int16_t negate;
  const int16_t* aptr;
  int16_t speechBuf[kCngMaxOutsizeOrder];

  const size_t num_samples = speech.size();
  RTC_CHECK_LE(num_samples, kCngMaxOutsizeOrder);

  for (i = 0; i < num_samples; i++) {
    speechBuf[i] = speech[i];
  }

  factor = num_samples;

  /* Calculate energy and a coefficients. */
  outEnergy = WebRtcSpl_Energy(speechBuf, num_samples, &outShifts);
  while (outShifts > 0) {
    /* We can only do 5 shifts without destroying accuracy in
     * division factor. */
    if (outShifts > 5) {
      outEnergy <<= (outShifts - 5);
      outShifts = 5;
    } else {
      factor /= 2;
      outShifts--;
    }
  }
  outEnergy = WebRtcSpl_DivW32W16(outEnergy, (int16_t)factor);

  if (outEnergy > 1) {
    /* Create Hanning Window. */
    WebRtcSpl_GetHanningWindow(hanningW, num_samples / 2);
    for (i = 0; i < (num_samples / 2); i++)
      hanningW[num_samples - i - 1] = hanningW[i];

    WebRtcSpl_ElementwiseVectorMult(speechBuf, hanningW, speechBuf, num_samples,
                                    14);

    WebRtcSpl_AutoCorrelation(speechBuf, num_samples, enc_nrOfCoefs_,
                              corrVector, &acorrScale);

    if (*corrVector == 0)
      *corrVector = WEBRTC_SPL_WORD16_MAX;

    /* Adds the bandwidth expansion. */
    aptr = WebRtcCng_kCorrWindow;
    bptr = corrVector;

    /* (zzz) lpc16_1 = 17+1+820+2+2 = 842 (ordo2=700). */
    for (ind = 0; ind < enc_nrOfCoefs_; ind++) {
      /* The below code multiplies the 16 b corrWindow values (Q15) with
       * the 32 b corrvector (Q0) and shifts the result down 15 steps. */
      negate = *bptr < 0;
      if (negate)
        *bptr = -*bptr;

      blo = (int32_t) * aptr * (*bptr & 0xffff);
      bhi = ((blo >> 16) & 0xffff)
          + ((int32_t)(*aptr++) * ((*bptr >> 16) & 0xffff));
      blo = (blo & 0xffff) | ((bhi & 0xffff) << 16);

      *bptr = (((bhi >> 16) & 0x7fff) << 17) | ((uint32_t) blo >> 15);
      if (negate)
        *bptr = -*bptr;
      bptr++;
    }
    /* End of bandwidth expansion. */

    stab = WebRtcSpl_LevinsonDurbin(corrVector, arCoefs, refCs,
                                    enc_nrOfCoefs_);

    if (!stab) {
      /* Disregard from this frame */
      return 0;
    }

  } else {
    for (i = 0; i < enc_nrOfCoefs_; i++)
      refCs[i] = 0;
  }

  if (force_sid) {
    /* Read instantaneous values instead of averaged. */
    for (i = 0; i < enc_nrOfCoefs_; i++)
      enc_reflCoefs_[i] = refCs[i];
    enc_Energy_ = outEnergy;
  } else {
    /* Average history with new values. */
    for (i = 0; i < enc_nrOfCoefs_; i++) {
      enc_reflCoefs_[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
          enc_reflCoefs_[i], ReflBeta, 15);
      enc_reflCoefs_[i] +=
          (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(refCs[i], ReflBetaComp, 15);
    }
    enc_Energy_ =
        (outEnergy >> 2) + (enc_Energy_ >> 1) + (enc_Energy_ >> 2);
  }

  if (enc_Energy_ < 1) {
    enc_Energy_ = 1;
  }

  if ((enc_msSinceSid_ > (enc_interval_ - 1)) || force_sid) {
    /* Search for best dbov value. */
    index = 0;
    for (i = 1; i < 93; i++) {
      /* Always round downwards. */
      if ((enc_Energy_ - WebRtcCng_kDbov[i]) > 0) {
        index = i;
        break;
      }
    }
    if ((i == 93) && (index == 0))
      index = 94;

    const size_t output_coefs = enc_nrOfCoefs_ + 1;
    output->AppendData(output_coefs, [&] (rtc::ArrayView<uint8_t> output) {
        output[0] = (uint8_t)index;

        /* Quantize coefficients with tweak for WebRtc implementation of
         * RFC3389. */
        if (enc_nrOfCoefs_ == WEBRTC_CNG_MAX_LPC_ORDER) {
          for (i = 0; i < enc_nrOfCoefs_; i++) {
            /* Q15 to Q7 with rounding. */
            output[i + 1] = ((enc_reflCoefs_[i] + 128) >> 8);
          }
        } else {
          for (i = 0; i < enc_nrOfCoefs_; i++) {
            /* Q15 to Q7 with rounding. */
            output[i + 1] = (127 + ((enc_reflCoefs_[i] + 128) >> 8));
          }
        }

        return output_coefs;
      });

    enc_msSinceSid_ =
        static_cast<int16_t>((1000 * num_samples) / enc_sampfreq_);
    return output_coefs;
  } else {
    enc_msSinceSid_ +=
        static_cast<int16_t>((1000 * num_samples) / enc_sampfreq_);
    return 0;
  }
}

namespace {
/* Values in |k| are Q15, and |a| Q12. */
void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a) {
  int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
  int16_t* aptr;
  int16_t* aptr2;
  int16_t* anyptr;
  const int16_t* kptr;
  int m, i;

  kptr = k;
  *a = 4096; /* i.e., (Word16_MAX >> 3) + 1 */
  *any = *a;
  a[1] = (*k + 4) >> 3;
  for (m = 1; m < useOrder; m++) {
    kptr++;
    aptr = a;
    aptr++;
    aptr2 = &a[m];
    anyptr = any;
    anyptr++;

    any[m + 1] = (*kptr + 4) >> 3;
    for (i = 0; i < m; i++) {
      *anyptr++ =
          (*aptr++) +
          (int16_t)((((int32_t)(*aptr2--) * (int32_t)*kptr) + 16384) >> 15);
    }

    aptr = a;
    anyptr = any;
    for (i = 0; i < (m + 2); i++) {
      *aptr++ = *anyptr++;
    }
  }
}

}  // namespace

}  // namespace webrtc
