16f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/*
26f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
36f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *
46f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  Use of this source code is governed by a BSD-style license
56f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  that can be found in the LICENSE file in the root of the source
66f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  tree. An additional intellectual property rights grant can be found
76f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  in the file PATENTS.  All contributing project authors may
86f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  be found in the AUTHORS file in the root of the source tree.
96f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */
106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include <memory.h>
126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#ifdef WEBRTC_ANDROID
136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include <stdlib.h>
146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#endif
156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "pitch_estimator.h"
166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "lpc_analysis.h"
176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "codec.h"
186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_AllPoleFilter(double *InOut, double *Coef, int lengthInOut, int orderCoef){
226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* the state of filter is assumed to be in InOut[-1] to InOut[-orderCoef] */
246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double scal;
256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double sum;
266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int n,k;
276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //if (fabs(Coef[0]-1.0)<0.001) {
296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if ( (Coef[0] > 0.9999) && (Coef[0] < 1.0001) )
306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for(n = 0; n < lengthInOut; n++)
326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      sum = Coef[1] * InOut[-1];
346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      for(k = 2; k <= orderCoef; k++){
356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        sum += Coef[k] * InOut[-k];
366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      *InOut++ -= sum;
386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    scal = 1.0 / Coef[0];
436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for(n=0;n<lengthInOut;n++)
446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      *InOut *= scal;
466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      for(k=1;k<=orderCoef;k++){
476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        *InOut -= scal*Coef[k]*InOut[-k];
486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      InOut++;
506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_AllZeroFilter(double *In, double *Coef, int lengthInOut, int orderCoef, double *Out){
566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* the state of filter is assumed to be in In[-1] to In[-orderCoef] */
586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int n, k;
606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double tmp;
616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for(n = 0; n < lengthInOut; n++)
636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    tmp = In[0] * Coef[0];
656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for(k = 1; k <= orderCoef; k++){
676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      tmp += Coef[k] * In[-k];
686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *Out++ = tmp;
716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    In++;
726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_ZeroPoleFilter(double *In, double *ZeroCoef, double *PoleCoef, int lengthInOut, int orderCoef, double *Out){
786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* the state of the zero section is assumed to be in In[-1] to In[-orderCoef] */
806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* the state of the pole section is assumed to be in Out[-1] to Out[-orderCoef] */
816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtcIsac_AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);
836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtcIsac_AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef);
846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_AutoCorr(
886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    double *r,
896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const double *x,
906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    int N,
916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    int order
926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                        )
936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int  lag, n;
956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double sum, prod;
966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double *x_lag;
976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (lag = 0; lag <= order; lag++)
996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
1006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    sum = 0.0f;
1016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    x_lag = &x[lag];
1026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    prod = x[0] * x_lag[0];
1036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for (n = 1; n < N - lag; n++) {
1046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      sum += prod;
1056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      prod = x[n] * x_lag[n];
1066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
1076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    sum += prod;
1086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    r[lag] = sum;
1096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_BwExpand(double *out, double *in, double coef, short length) {
1156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int i;
1166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  chirp;
1176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  chirp = coef;
1196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  out[0] = in[0];
1216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (i = 1; i < length; i++) {
1226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    out[i] = chirp * in[i];
1236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    chirp *= coef;
1246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_WeightingFilter(const double *in, double *weiout, double *whiout, WeightFiltstr *wfdata) {
1286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  tmpbuffer[PITCH_FRAME_LEN + PITCH_WLPCBUFLEN];
1306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  corr[PITCH_WLPCORDER+1], rc[PITCH_WLPCORDER+1];
1316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double apol[PITCH_WLPCORDER+1], apolr[PITCH_WLPCORDER+1];
1326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  rho=0.9, *inp, *dp, *dp2;
1336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  whoutbuf[PITCH_WLPCBUFLEN + PITCH_WLPCORDER];
1346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  weoutbuf[PITCH_WLPCBUFLEN + PITCH_WLPCORDER];
1356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double  *weo, *who, opol[PITCH_WLPCORDER+1], ext[PITCH_WLPCWINLEN];
1366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int     k, n, endpos, start;
1376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Set up buffer and states */
1396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  memcpy(tmpbuffer, wfdata->buffer, sizeof(double) * PITCH_WLPCBUFLEN);
1406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  memcpy(tmpbuffer+PITCH_WLPCBUFLEN, in, sizeof(double) * PITCH_FRAME_LEN);
1416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  memcpy(wfdata->buffer, tmpbuffer+PITCH_FRAME_LEN, sizeof(double) * PITCH_WLPCBUFLEN);
1426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  dp=weoutbuf;
1446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  dp2=whoutbuf;
1456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (k=0;k<PITCH_WLPCORDER;k++) {
1466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *dp++ = wfdata->weostate[k];
1476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *dp2++ = wfdata->whostate[k];
1486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    opol[k]=0.0;
1496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  opol[0]=1.0;
1516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  opol[PITCH_WLPCORDER]=0.0;
1526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  weo=dp;
1536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  who=dp2;
1546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  endpos=PITCH_WLPCBUFLEN + PITCH_SUBFRAME_LEN;
1566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  inp=tmpbuffer + PITCH_WLPCBUFLEN;
1576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (n=0; n<PITCH_SUBFRAMES; n++) {
1596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* Windowing */
1606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    start=endpos-PITCH_WLPCWINLEN;
1616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for (k=0; k<PITCH_WLPCWINLEN; k++) {
1626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      ext[k]=wfdata->window[k]*tmpbuffer[start+k];
1636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
1646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* Get LPC polynomial */
1666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtcIsac_AutoCorr(corr, ext, PITCH_WLPCWINLEN, PITCH_WLPCORDER);
1676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    corr[0]=1.01*corr[0]+1.0; /* White noise correction */
1686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtcIsac_LevDurb(apol, rc, corr, PITCH_WLPCORDER);
1696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtcIsac_BwExpand(apolr, apol, rho, PITCH_WLPCORDER+1);
1706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* Filtering */
1726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtcIsac_ZeroPoleFilter(inp, apol, apolr, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, weo);
1736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtcIsac_ZeroPoleFilter(inp, apolr, opol, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, who);
1746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    inp+=PITCH_SUBFRAME_LEN;
1766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    endpos+=PITCH_SUBFRAME_LEN;
1776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    weo+=PITCH_SUBFRAME_LEN;
1786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    who+=PITCH_SUBFRAME_LEN;
1796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Export filter states */
1826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (k=0;k<PITCH_WLPCORDER;k++) {
1836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    wfdata->weostate[k]=weoutbuf[PITCH_FRAME_LEN+k];
1846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    wfdata->whostate[k]=whoutbuf[PITCH_FRAME_LEN+k];
1856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Export output data */
1886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  memcpy(weiout, weoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN);
1896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  memcpy(whiout, whoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN);
1906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const double APupper[ALLPASSSECTIONS] = {0.0347, 0.3826};
1946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const double APlower[ALLPASSSECTIONS] = {0.1544, 0.744};
1956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_AllpassFilterForDec(double *InOut,
1996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                   const double *APSectionFactors,
2006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                   int lengthInOut,
2016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                   double *FilterState)
2026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
2036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //This performs all-pass filtering--a series of first order all-pass sections are used
2046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //to filter the input in a cascade manner.
2056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int n,j;
2066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double temp;
2076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (j=0; j<ALLPASSSECTIONS; j++){
2086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for (n=0;n<lengthInOut;n+=2){
2096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      temp = InOut[n]; //store input
2106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      InOut[n] = FilterState[j] + APSectionFactors[j]*temp;
2116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      FilterState[j] = -APSectionFactors[j]*InOut[n] + temp;
2126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
2146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_DecimateAllpass(const double *in,
2176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                double *state_in,        /* array of size: 2*ALLPASSSECTIONS+1 */
2186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                int N,                   /* number of input samples */
2196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                double *out)             /* array of size N/2 */
2206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
2216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int n;
2226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double data_vec[PITCH_FRAME_LEN];
2236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* copy input */
2256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  memcpy(data_vec+1, in, sizeof(double) * (N-1));
2266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  data_vec[0] = state_in[2*ALLPASSSECTIONS];   //the z^(-1) state
2286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  state_in[2*ALLPASSSECTIONS] = in[N-1];
2296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtcIsac_AllpassFilterForDec(data_vec+1, APupper, N, state_in);
2316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtcIsac_AllpassFilterForDec(data_vec, APlower, N, state_in+ALLPASSSECTIONS);
2326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (n=0;n<N/2;n++)
2346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    out[n] = data_vec[2*n] + data_vec[2*n+1];
2356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* create high-pass filter ocefficients
2416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * z = 0.998 * exp(j*2*pi*35/8000);
2426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * p = 0.94 * exp(j*2*pi*140/8000);
2436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * HP_b = [1, -2*real(z), abs(z)^2];
2446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * HP_a = [1, -2*real(p), abs(p)^2]; */
2456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const double a_coef[2] = { 1.86864659625574, -0.88360000000000};
2466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const double b_coef[2] = {-1.99524591718270,  0.99600400000000};
2476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const float a_coef_float[2] = { 1.86864659625574f, -0.88360000000000f};
2486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const float b_coef_float[2] = {-1.99524591718270f,  0.99600400000000f};
2496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* second order high-pass filter */
2516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_Highpass(const double *in, double *out, double *state, int N)
2526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
2536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int k;
2546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (k=0; k<N; k++) {
2566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *out = *in + state[1];
2576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    state[1] = state[0] + b_coef[0] * *in + a_coef[0] * *out;
2586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    state[0] = b_coef[1] * *in++ + a_coef[1] * *out++;
2596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
2606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_Highpass_float(const float *in, double *out, double *state, int N)
2636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
2646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int k;
2656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (k=0; k<N; k++) {
2676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *out = (double)*in + state[1];
2686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    state[1] = state[0] + b_coef_float[0] * *in + a_coef_float[0] * *out;
2696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    state[0] = b_coef_float[1] * (double)*in++ + a_coef_float[1] * *out++;
2706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
2716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
272