Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /*
     12  * lattice.c
     13  *
     14  * contains the normalized lattice filter routines (MA and AR) for iSAC codec
     15  *
     16  */
     17 #include "settings.h"
     18 #include "codec.h"
     19 
     20 #include <math.h>
     21 #include <memory.h>
     22 #include <string.h>
     23 #ifdef WEBRTC_ANDROID
     24 #include <stdlib.h>
     25 #endif
     26 
     27 /* filter the signal using normalized lattice filter */
     28 /* MA filter */
     29 void WebRtcIsac_NormLatticeFilterMa(int orderCoef,
     30                                      float *stateF,
     31                                      float *stateG,
     32                                      float *lat_in,
     33                                      double *filtcoeflo,
     34                                      double *lat_out)
     35 {
     36   int n,k,i,u,temp1;
     37   int ord_1 = orderCoef+1;
     38   float sth[MAX_AR_MODEL_ORDER];
     39   float cth[MAX_AR_MODEL_ORDER];
     40   float inv_cth[MAX_AR_MODEL_ORDER];
     41   double a[MAX_AR_MODEL_ORDER+1];
     42   float f[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], g[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
     43   float gain1;
     44 
     45   for (u=0;u<SUBFRAMES;u++)
     46   {
     47     /* set the Direct Form coefficients */
     48     temp1 = u*ord_1;
     49     a[0] = 1;
     50     memcpy(a+1, filtcoeflo+temp1+1, sizeof(double) * (ord_1-1));
     51 
     52     /* compute lattice filter coefficients */
     53     WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
     54 
     55     /* compute the gain */
     56     gain1 = (float)filtcoeflo[temp1];
     57     for (k=0;k<orderCoef;k++)
     58     {
     59       gain1 *= cth[k];
     60       inv_cth[k] = 1/cth[k];
     61     }
     62 
     63     /* normalized lattice filter */
     64     /*****************************/
     65 
     66     /* initial conditions */
     67     for (i=0;i<HALF_SUBFRAMELEN;i++)
     68     {
     69       f[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
     70       g[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
     71     }
     72 
     73     /* get the state of f&g for the first input, for all orders */
     74     for (i=1;i<ord_1;i++)
     75     {
     76       f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]);
     77       g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0];
     78     }
     79 
     80     /* filtering */
     81     for(k=0;k<orderCoef;k++)
     82     {
     83       for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
     84       {
     85         f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]);
     86         g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1];
     87       }
     88     }
     89 
     90     for(n=0;n<HALF_SUBFRAMELEN;n++)
     91     {
     92       lat_out[n + u * HALF_SUBFRAMELEN] = gain1 * f[orderCoef][n];
     93     }
     94 
     95     /* save the states */
     96     for (i=0;i<ord_1;i++)
     97     {
     98       stateF[i] = f[i][HALF_SUBFRAMELEN-1];
     99       stateG[i] = g[i][HALF_SUBFRAMELEN-1];
    100     }
    101     /* process next frame */
    102   }
    103 
    104   return;
    105 }
    106 
    107 
    108 /*///////////////////AR filter ///////////////////////////////*/
    109 /* filter the signal using normalized lattice filter */
    110 void WebRtcIsac_NormLatticeFilterAr(int orderCoef,
    111                                      float *stateF,
    112                                      float *stateG,
    113                                      double *lat_in,
    114                                      double *lo_filt_coef,
    115                                      float *lat_out)
    116 {
    117   int n,k,i,u,temp1;
    118   int ord_1 = orderCoef+1;
    119   float sth[MAX_AR_MODEL_ORDER];
    120   float cth[MAX_AR_MODEL_ORDER];
    121   double a[MAX_AR_MODEL_ORDER+1];
    122   float ARf[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], ARg[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
    123   float gain1,inv_gain1;
    124 
    125   for (u=0;u<SUBFRAMES;u++)
    126   {
    127     /* set the denominator and numerator of the Direct Form */
    128     temp1 = u*ord_1;
    129     a[0] = 1;
    130 
    131     memcpy(a+1, lo_filt_coef+temp1+1, sizeof(double) * (ord_1-1));
    132 
    133     WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
    134 
    135     gain1 = (float)lo_filt_coef[temp1];
    136     for (k=0;k<orderCoef;k++)
    137     {
    138       gain1 = cth[k]*gain1;
    139     }
    140 
    141     /* initial conditions */
    142     inv_gain1 = 1/gain1;
    143     for (i=0;i<HALF_SUBFRAMELEN;i++)
    144     {
    145       ARf[orderCoef][i] = (float)lat_in[i + u * HALF_SUBFRAMELEN]*inv_gain1;
    146     }
    147 
    148 
    149     for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
    150     {
    151       ARf[i][0] = cth[i]*ARf[i+1][0] - sth[i]*stateG[i];
    152       ARg[i+1][0] = sth[i]*ARf[i+1][0] + cth[i]* stateG[i];
    153     }
    154     ARg[0][0] = ARf[0][0];
    155 
    156     for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
    157     {
    158       for(k=orderCoef-1;k>=0;k--)
    159       {
    160         ARf[k][n+1] = cth[k]*ARf[k+1][n+1] - sth[k]*ARg[k][n];
    161         ARg[k+1][n+1] = sth[k]*ARf[k+1][n+1] + cth[k]* ARg[k][n];
    162       }
    163       ARg[0][n+1] = ARf[0][n+1];
    164     }
    165 
    166     memcpy(lat_out+u * HALF_SUBFRAMELEN, &(ARf[0][0]), sizeof(float) * HALF_SUBFRAMELEN);
    167 
    168     /* cannot use memcpy in the following */
    169     for (i=0;i<ord_1;i++)
    170     {
    171       stateF[i] = ARf[i][HALF_SUBFRAMELEN-1];
    172       stateG[i] = ARg[i][HALF_SUBFRAMELEN-1];
    173     }
    174 
    175   }
    176 
    177   return;
    178 }
    179 
    180 
    181 /* compute the reflection coefficients using the step-down procedure*/
    182 /* converts the direct form parameters to lattice form.*/
    183 /* a and b are vectors which contain the direct form coefficients,
    184    according to
    185    A(z) = a(1) + a(2)*z + a(3)*z^2 + ... + a(M+1)*z^M
    186    B(z) = b(1) + b(2)*z + b(3)*z^2 + ... + b(M+1)*z^M
    187 */
    188 
    189 void WebRtcIsac_Dir2Lat(double *a,
    190                         int orderCoef,
    191                         float *sth,
    192                         float *cth)
    193 {
    194   int m, k;
    195   float tmp[MAX_AR_MODEL_ORDER];
    196   float tmp_inv, cth2;
    197 
    198   sth[orderCoef-1] = (float)a[orderCoef];
    199   cth2 = 1.0f - sth[orderCoef-1] * sth[orderCoef-1];
    200   cth[orderCoef-1] = (float)sqrt(cth2);
    201   for (m=orderCoef-1; m>0; m--)
    202   {
    203     tmp_inv = 1.0f / cth2;
    204     for (k=1; k<=m; k++)
    205     {
    206       tmp[k] = ((float)a[k] - sth[m] * (float)a[m-k+1]) * tmp_inv;
    207     }
    208 
    209     for (k=1; k<m; k++)
    210     {
    211       a[k] = tmp[k];
    212     }
    213 
    214     sth[m-1] = tmp[m];
    215     cth2 = 1 - sth[m-1] * sth[m-1];
    216     cth[m-1] = (float)sqrt(cth2);
    217   }
    218 }
    219