/*
 *  Copyright (c) 2011 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 "pitch_estimator.h"
#include "os_specific_inline.h"

#include <stdlib.h>
#include <memory.h>
#include <math.h>

static const double kDampFilter[PITCH_DAMPORDER] = {-0.07, 0.25, 0.64, 0.25, -0.07};

/* interpolation coefficients; generated by design_pitch_filter.m */
static const double kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
  {-0.02239172458614,  0.06653315052934, -0.16515880017569,  0.60701333734125, 0.64671399919202, -0.20249000396417,  0.09926548334755, -0.04765933793109,  0.01754159521746},
  {-0.01985640750434,  0.05816126837866, -0.13991265473714,  0.44560418147643, 0.79117042386876, -0.20266133815188,  0.09585268418555, -0.04533310458084,  0.01654127246314},
  {-0.01463300534216,  0.04229888475060, -0.09897034715253,  0.28284326017787, 0.90385267956632, -0.16976950138649,  0.07704272393639, -0.03584218578311,  0.01295781500709},
  {-0.00764851320885,  0.02184035544377, -0.04985561057281,  0.13083306574393, 0.97545011664662, -0.10177807997561,  0.04400901776474, -0.02010737175166,  0.00719783432422},
  {-0.00000000000000,  0.00000000000000, -0.00000000000001,  0.00000000000001, 0.99999999999999,  0.00000000000001, -0.00000000000001,  0.00000000000000, -0.00000000000000},
  { 0.00719783432422, -0.02010737175166,  0.04400901776474, -0.10177807997562, 0.97545011664663,  0.13083306574393, -0.04985561057280,  0.02184035544377, -0.00764851320885},
  { 0.01295781500710, -0.03584218578312,  0.07704272393640, -0.16976950138650, 0.90385267956634,  0.28284326017785, -0.09897034715252,  0.04229888475059, -0.01463300534216},
  { 0.01654127246315, -0.04533310458085,  0.09585268418557, -0.20266133815190, 0.79117042386878,  0.44560418147640, -0.13991265473712,  0.05816126837865, -0.01985640750433}
};


void WebRtcIsac_PitchfilterPre(double *indat,
                                double *outdat,
                                PitchFiltstr *pfp,
                                double *lags,
                                double *gains)
{

  double ubuf[PITCH_INTBUFFSIZE];
  const double *fracoeff = NULL;
  double curgain, curlag, gaindelta, lagdelta;
  double sum, inystate[PITCH_DAMPORDER];
  double ftmp, oldlag, oldgain;
  int    k, n, m, pos, ind, pos2, Li, frc;

  Li = 0;
  /* Set up buffer and states */
  memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);

  oldlag = *pfp->oldlagp;
  oldgain = *pfp->oldgainp;

  /* No interpolation if pitch lag step is big */
  if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
    oldlag = lags[0];
    oldgain = gains[0];
  }

  ind=0;
  for (k=0;k<PITCH_SUBFRAMES;k++) {

    /* Calculate interpolation steps */
    lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
    curlag=oldlag ;
    gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
    curgain=oldgain ;
    oldlag=lags[k];
    oldgain=gains[k];

    for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
      if ((ind % PITCH_UPDATE) == 0) { /* Update parameters */
        curgain += gaindelta;
        curlag += lagdelta;
        Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
        ftmp = Li - (curlag+PITCH_FILTDELAY);
        frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
        fracoeff = kIntrpCoef[frc];
      }

      /* shift low pass filter state */
      for (m=PITCH_DAMPORDER-1;m>0;m--)
        inystate[m] = inystate[m-1];

      /* Filter to get fractional pitch */
      pos = ind + PITCH_BUFFSIZE;
      pos2 = pos - Li;
      sum=0;
      for (m=0;m<PITCH_FRACORDER;m++)
        sum += ubuf[pos2+m] * fracoeff[m];
      inystate[0] = curgain * sum;  /* Multiply with gain */

      /* Low pass filter */
      sum=0;
      for (m=0;m<PITCH_DAMPORDER;m++)
        sum += inystate[m] * kDampFilter[m];

      /* Subtract from input and update buffer */
      outdat[ind] = indat[ind] - sum;
      ubuf[pos] = indat[ind] + outdat[ind];
      ind++;
    }
  }

  /* Export buffer and states */
  memcpy(pfp->ubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER);

  *pfp->oldlagp = oldlag;
  *pfp->oldgainp = oldgain;

}


void WebRtcIsac_PitchfilterPre_la(double *indat,
                                   double *outdat,
                                   PitchFiltstr *pfp,
                                   double *lags,
                                   double *gains)
{
  double ubuf[PITCH_INTBUFFSIZE+QLOOKAHEAD];
  const double *fracoeff = NULL;
  double curgain, curlag, gaindelta, lagdelta;
  double sum, inystate[PITCH_DAMPORDER];
  double ftmp;
  double oldlag, oldgain;
  int    k, n, m, pos, ind, pos2, Li, frc;

  Li = 0;
  /* Set up buffer and states */
  memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);

  oldlag = *pfp->oldlagp;
  oldgain = *pfp->oldgainp;

  /* No interpolation if pitch lag step is big */
  if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
    oldlag = lags[0];
    oldgain = gains[0];
  }


  ind=0;
  for (k=0;k<PITCH_SUBFRAMES;k++) {

    /* Calculate interpolation steps */
    lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
    curlag=oldlag ;
    gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
    curgain=oldgain ;
    oldlag=lags[k];
    oldgain=gains[k];

    for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
      if ((ind % PITCH_UPDATE) == 0) {   /* Update parameters */
        curgain += gaindelta;
        curlag += lagdelta;
        Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
        ftmp = Li - (curlag+PITCH_FILTDELAY);
        frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
        fracoeff = kIntrpCoef[frc];
      }

      /* shift low pass filter state */
      for (m=PITCH_DAMPORDER-1;m>0;m--)
        inystate[m] = inystate[m-1];

      /* Filter to get fractional pitch */
      pos = ind + PITCH_BUFFSIZE;
      pos2 = pos - Li;
      sum=0.0;
      for (m=0;m<PITCH_FRACORDER;m++)
        sum += ubuf[pos2+m] * fracoeff[m];
      inystate[0] = curgain * sum; /* Multiply with gain */

      /* Low pass filter */
      sum=0.0;
      for (m=0;m<PITCH_DAMPORDER;m++)
        sum += inystate[m] * kDampFilter[m];

      /* Subtract from input and update buffer */
      outdat[ind] = indat[ind] - sum;
      ubuf[pos] = indat[ind] + outdat[ind];
      ind++;
    }
  }

  /* Export buffer and states */
  memcpy(pfp->ubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER);

  *pfp->oldlagp = oldlag;
  *pfp->oldgainp = oldgain;


  /* Filter look-ahead segment */
  for (n=0;n<QLOOKAHEAD;n++) {
    /* shift low pass filter state */
    for (m=PITCH_DAMPORDER-1;m>0;m--)
      inystate[m] = inystate[m-1];

    /* Filter to get fractional pitch */
    pos = ind + PITCH_BUFFSIZE;
    pos2 = pos - Li;
    sum=0.0;
    for (m=0;m<PITCH_FRACORDER;m++)
      sum += ubuf[pos2+m] * fracoeff[m];
    inystate[0] = curgain * sum; /* Multiply with gain */

    /* Low pass filter */
    sum=0.0;
    for (m=0;m<PITCH_DAMPORDER;m++)
      sum += inystate[m] * kDampFilter[m];

    /* Subtract from input and update buffer */
    outdat[ind] = indat[ind] - sum;
    ubuf[pos] = indat[ind] + outdat[ind];
    ind++;
  }
}


void WebRtcIsac_PitchfilterPre_gains(double *indat,
                                      double *outdat,
                                      double out_dG[][PITCH_FRAME_LEN + QLOOKAHEAD],
                                      PitchFiltstr *pfp,
                                      double *lags,
                                      double *gains)
{
  double ubuf[PITCH_INTBUFFSIZE+QLOOKAHEAD];
  double inystate_dG[4][PITCH_DAMPORDER];
  double gain_mult[4];
  const double *fracoeff = NULL;
  double curgain, curlag, gaindelta, lagdelta;
  double sum, sum2, inystate[PITCH_DAMPORDER];
  double ftmp, oldlag, oldgain;
  int    k, n, m, m_tmp, j, pos, ind, pos2, Li, frc;

  Li = 0;

  /* Set up buffer and states */
  memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);

  /* clear some buffers */
  for (k = 0; k < 4; k++) {
    gain_mult[k] = 0.0;
    for (n = 0; n < PITCH_DAMPORDER; n++)
      inystate_dG[k][n] = 0.0;
  }

  oldlag = *pfp->oldlagp;
  oldgain = *pfp->oldgainp;

  /* No interpolation if pitch lag step is big */
  if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
    oldlag = lags[0];
    oldgain = gains[0];
    gain_mult[0] = 1.0;
  }


  ind=0;
  for (k=0;k<PITCH_SUBFRAMES;k++) {

    /* Calculate interpolation steps */
    lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
    curlag=oldlag ;
    gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
    curgain=oldgain ;
    oldlag=lags[k];
    oldgain=gains[k];

    for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
      if ((ind % PITCH_UPDATE) == 0) {   /* Update parameters */
        curgain += gaindelta;
        curlag += lagdelta;
        Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
        ftmp = Li - (curlag+PITCH_FILTDELAY);
        frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
        fracoeff = kIntrpCoef[frc];
        gain_mult[k] += 0.2;
        if (gain_mult[k] > 1.0) gain_mult[k] = 1.0;
        if (k > 0) gain_mult[k-1] -= 0.2;
      }

      /* shift low pass filter states */
      for (m=PITCH_DAMPORDER-1;m>0;m--) {
        inystate[m] = inystate[m-1];
        for (j = 0; j < 4; j++)
          inystate_dG[j][m] = inystate_dG[j][m-1];
      }

      pos = ind + PITCH_BUFFSIZE;
      pos2 = pos - Li;

      /* Filter to get fractional pitch */
      sum=0.0;
      for (m=0;m<PITCH_FRACORDER;m++)
        sum += ubuf[pos2+m] * fracoeff[m];
      inystate[0] = curgain * sum;  /* Multiply with gain */
      m_tmp = (Li-ind > 0) ? Li-ind : 0;
      for (j = 0; j < k+1; j++) {
        /* filter */
        sum2 = 0.0;
        for (m = PITCH_FRACORDER-1; m >= m_tmp; m--)
          sum2 += out_dG[j][ind-Li + m] * fracoeff[m];
        inystate_dG[j][0] = gain_mult[j] * sum + curgain * sum2;
      }

      /* Low pass filter */
      sum=0.0;
      for (m=0;m<PITCH_DAMPORDER;m++)
        sum += inystate[m] * kDampFilter[m];

      /* Subtract from input and update buffer */
      outdat[ind] = indat[ind] - sum;
      ubuf[pos] = indat[ind] + outdat[ind];

      for (j = 0; j < k+1; j++) {
        sum = 0.0;
        for (m=0;m<PITCH_DAMPORDER;m++)
          sum -= inystate_dG[j][m] * kDampFilter[m];
        out_dG[j][ind] = sum;
      }
      for (j = k+1; j < 4; j++)
        out_dG[j][ind] = 0.0;


      ind++;
    }
  }

  /* Filter look-ahead segment */
  for (n=0;n<QLOOKAHEAD;n++) {
    /* shift low pass filter states */
    for (m=PITCH_DAMPORDER-1;m>0;m--) {
      inystate[m] = inystate[m-1];
      for (j = 0; j < 4; j++)
        inystate_dG[j][m] = inystate_dG[j][m-1];
    }

    pos = ind + PITCH_BUFFSIZE;
    pos2 = pos - Li;

    /* Filter to get fractional pitch */
    sum=0.0;
    for (m=0;m<PITCH_FRACORDER;m++)
      sum += ubuf[pos2+m] * fracoeff[m];
    inystate[0] = curgain * sum;  /* Multiply with gain */
    m_tmp = (Li-ind > 0) ? Li-ind : 0;
    for (j = 0; (j<k+1)&&(j<4); j++) {
      /* filter */
      sum2 = 0.0;
      for (m = PITCH_FRACORDER-1; m >= m_tmp; m--)
        sum2 += out_dG[j][ind-Li + m] * fracoeff[m];
      inystate_dG[j][0] = gain_mult[j] * sum + curgain * sum2;
    }

    /* Low pass filter */
    sum=0.0;
    for (m=0;m<PITCH_DAMPORDER;m++)
      sum += inystate[m] * kDampFilter[m];

    /* Subtract from input and update buffer */
    outdat[ind] = indat[ind] - sum;
    ubuf[pos] = indat[ind] + outdat[ind];

    for (j = 0; (j<k+1)&&(j<4); j++) {
      sum = 0.0;
      for (m=0;m<PITCH_DAMPORDER;m++)
        sum -= inystate_dG[j][m] * kDampFilter[m];
      out_dG[j][ind] = sum;
    }

    ind++;
  }
}


void WebRtcIsac_PitchfilterPost(double *indat,
                                 double *outdat,
                                 PitchFiltstr *pfp,
                                 double *lags,
                                 double *gains)
{

  double ubuf[PITCH_INTBUFFSIZE];
  const double *fracoeff = NULL;
  double curgain, curlag, gaindelta, lagdelta;
  double sum, inystate[PITCH_DAMPORDER];
  double ftmp, oldlag, oldgain;
  int    k, n, m, pos, ind, pos2, Li, frc;

  Li = 0;

  /* Set up buffer and states */
  memcpy(ubuf, pfp->ubuf, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(inystate, pfp->ystate, sizeof(double) * PITCH_DAMPORDER);

  oldlag = *pfp->oldlagp;
  oldgain = *pfp->oldgainp;

  /* make output more periodic */
  for (k=0;k<PITCH_SUBFRAMES;k++)
    gains[k] *= 1.3;

  /* No interpolation if pitch lag step is big */
  if ((lags[0] > (PITCH_UPSTEP * oldlag)) || (lags[0] < (PITCH_DOWNSTEP * oldlag))) {
    oldlag = lags[0];
    oldgain = gains[0];
  }


  ind=0;
  for (k=0;k<PITCH_SUBFRAMES;k++) {

    /* Calculate interpolation steps */
    lagdelta=(lags[k]-oldlag) / PITCH_GRAN_PER_SUBFRAME;
    curlag=oldlag ;
    gaindelta=(gains[k]-oldgain) / PITCH_GRAN_PER_SUBFRAME;
    curgain=oldgain ;
    oldlag=lags[k];
    oldgain=gains[k];

    for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
      if ((ind % PITCH_UPDATE) == 0) {   /* Update parameters */
        curgain += gaindelta;
        curlag += lagdelta;
        Li = WebRtcIsac_lrint(curlag+PITCH_FILTDELAY + 0.5);
        ftmp = Li - (curlag+PITCH_FILTDELAY);
        frc = WebRtcIsac_lrint(PITCH_FRACS * ftmp - 0.5);
        fracoeff = kIntrpCoef[frc];
      }

      /* shift low pass filter state */
      for (m=PITCH_DAMPORDER-1;m>0;m--)
        inystate[m] = inystate[m-1];

      /* Filter to get fractional pitch */
      pos = ind + PITCH_BUFFSIZE;
      pos2 = pos - Li;
      sum=0.0;
      for (m=0;m<PITCH_FRACORDER;m++)
        sum += ubuf[pos2+m] * fracoeff[m];
      inystate[0] = curgain * sum; /* Multiply with gain */

      /* Low pass filter */
      sum=0.0;
      for (m=0;m<PITCH_DAMPORDER;m++)
        sum += inystate[m] * kDampFilter[m];

      /* Add to input and update buffer */
      outdat[ind] = indat[ind] + sum;
      ubuf[pos] = indat[ind] + outdat[ind];
      ind++;
    }
  }

  /* Export buffer and states */
  memcpy(pfp->ubuf, ubuf+PITCH_FRAME_LEN, sizeof(double) * PITCH_BUFFSIZE);
  memcpy(pfp->ystate, inystate, sizeof(double) * PITCH_DAMPORDER);

  *pfp->oldlagp = oldlag;
  *pfp->oldgainp = oldgain;

}
