tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search

RFC 3951

 
 
 

Internet Low Bit Rate Codec (iLBC)

Part 6 of 6, p. 152 to 194
Prev RFC Part

 


prevText      Top      Up      ToC       Page 152 
A.33.  iCBSearch.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       iCBSearch.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_ICBSEARCH_H
   #define __iLBC_ICBSEARCH_H

Top      Up      ToC       Page 153 
   void iCBSearch(
       iLBC_Enc_Inst_t *iLBCenc_inst,
                           /* (i) the encoder state structure */
       int *index,         /* (o) Codebook indices */
       int *gain_index,/* (o) Gain quantization indices */
       float *intarget,/* (i) Target vector for encoding */
       float *mem,         /* (i) Buffer for codebook construction */
       int lMem,           /* (i) Length of buffer */
       int lTarget,    /* (i) Length of vector */
       int nStages,    /* (i) Number of codebook stages */
       float *weightDenum, /* (i) weighting filter coefficients */
       float *weightState, /* (i) weighting filter state */
       int block           /* (i) the sub-block number */
   );

   #endif

A.34.  iCBSearch.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       iCBSearch.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include <math.h>
   #include <string.h>

   #include "iLBC_define.h"
   #include "gainquant.h"
   #include "createCB.h"
   #include "filter.h"
   #include "constants.h"

   /*----------------------------------------------------------------*
    *  Search routine for codebook encoding and gain quantization.
    *---------------------------------------------------------------*/

   void iCBSearch(
       iLBC_Enc_Inst_t *iLBCenc_inst,
                           /* (i) the encoder state structure */
       int *index,         /* (o) Codebook indices */
       int *gain_index,/* (o) Gain quantization indices */

Top      Up      ToC       Page 154 
       float *intarget,/* (i) Target vector for encoding */
       float *mem,         /* (i) Buffer for codebook construction */
       int lMem,           /* (i) Length of buffer */
       int lTarget,    /* (i) Length of vector */
       int nStages,    /* (i) Number of codebook stages */
       float *weightDenum, /* (i) weighting filter coefficients */
       float *weightState, /* (i) weighting filter state */
       int block           /* (i) the sub-block number */
   ){
       int i, j, icount, stage, best_index, range, counter;
       float max_measure, gain, measure, crossDot, ftmp;
       float gains[CB_NSTAGES];
       float target[SUBL];
       int base_index, sInd, eInd, base_size;
       int sIndAug=0, eIndAug=0;
       float buf[CB_MEML+SUBL+2*LPC_FILTERORDER];
       float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128];
       float *pp, *ppi=0, *ppo=0, *ppe=0;
       float cbvectors[CB_MEML];
       float tene, cene, cvec[SUBL];
       float aug_vec[SUBL];

       memset(cvec,0,SUBL*sizeof(float));

       /* Determine size of codebook sections */

       base_size=lMem-lTarget+1;

       if (lTarget==SUBL) {
           base_size=lMem-lTarget+1+lTarget/2;
       }

       /* setup buffer for weighting */

       memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER);
       memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float));
       memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float));

       /* weighting */

       AllPoleFilter(buf+LPC_FILTERORDER, weightDenum,
           lMem+lTarget, LPC_FILTERORDER);

       /* Construct the codebook and target needed */

       memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));

       tene=0.0;

Top      Up      ToC       Page 155 
       for (i=0; i<lTarget; i++) {
           tene+=target[i]*target[i];
       }

       /* Prepare search over one more codebook section. This section
          is created by filtering the original buffer with a filter. */

       filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);

       /* The Main Loop over stages */

       for (stage=0; stage<nStages; stage++) {

           range = search_rangeTbl[block][stage];

           /* initialize search measure */

           max_measure = (float)-10000000.0;
           gain = (float)0.0;
           best_index = 0;

           /* Compute cross dot product between the target
              and the CB memory */

           crossDot=0.0;
           pp=buf+LPC_FILTERORDER+lMem-lTarget;
           for (j=0; j<lTarget; j++) {
               crossDot += target[j]*(*pp++);
           }

           if (stage==0) {

               /* Calculate energy in the first block of
                 'lTarget' samples. */
               ppe = energy;
               ppi = buf+LPC_FILTERORDER+lMem-lTarget-1;
               ppo = buf+LPC_FILTERORDER+lMem-1;

               *ppe=0.0;
               pp=buf+LPC_FILTERORDER+lMem-lTarget;
               for (j=0; j<lTarget; j++) {
                   *ppe+=(*pp)*(*pp++);
               }

               if (*ppe>0.0) {
                   invenergy[0] = (float) 1.0 / (*ppe + EPS);
               } else {
                   invenergy[0] = (float) 0.0;

Top      Up      ToC       Page 156 
               }
               ppe++;

               measure=(float)-10000000.0;

               if (crossDot > 0.0) {
                      measure = crossDot*crossDot*invenergy[0];
               }
           }
           else {
               measure = crossDot*crossDot*invenergy[0];
           }

           /* check if measure is better */
           ftmp = crossDot*invenergy[0];

           if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
               best_index = 0;
               max_measure = measure;
               gain = ftmp;
           }

           /* loop over the main first codebook section,
              full search */

           for (icount=1; icount<range; icount++) {

               /* calculate measure */

               crossDot=0.0;
               pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;

               for (j=0; j<lTarget; j++) {
                   crossDot += target[j]*(*pp++);
               }

               if (stage==0) {
                   *ppe++ = energy[icount-1] + (*ppi)*(*ppi) -
                       (*ppo)*(*ppo);
                   ppo--;
                   ppi--;

                   if (energy[icount]>0.0) {
                       invenergy[icount] =
                           (float)1.0/(energy[icount]+EPS);
                   } else {
                       invenergy[icount] = (float) 0.0;
                   }

Top      Up      ToC       Page 157 
                   measure=(float)-10000000.0;

                   if (crossDot > 0.0) {
                       measure = crossDot*crossDot*invenergy[icount];
                   }
               }
               else {
                   measure = crossDot*crossDot*invenergy[icount];
               }

               /* check if measure is better */
               ftmp = crossDot*invenergy[icount];

               if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
                   best_index = icount;
                   max_measure = measure;
                   gain = ftmp;
               }
           }

           /* Loop over augmented part in the first codebook
            * section, full search.
            * The vectors are interpolated.
            */

           if (lTarget==SUBL) {

               /* Search for best possible cb vector and
                  compute the CB-vectors' energy. */
               searchAugmentedCB(20, 39, stage, base_size-lTarget/2,
                   target, buf+LPC_FILTERORDER+lMem,
                   &max_measure, &best_index, &gain, energy,
                   invenergy);
           }

           /* set search range for following codebook sections */

           base_index=best_index;

           /* unrestricted search */

           if (CB_RESRANGE == -1) {
               sInd=0;
               eInd=range-1;
               sIndAug=20;
               eIndAug=39;
           }

Top      Up      ToC       Page 158 
           /* restricted search around best index from first
           codebook section */

           else {
               /* Initialize search indices */
               sIndAug=0;
               eIndAug=0;
               sInd=base_index-CB_RESRANGE/2;
               eInd=sInd+CB_RESRANGE;

               if (lTarget==SUBL) {

                   if (sInd<0) {

                       sIndAug = 40 + sInd;
                       eIndAug = 39;
                       sInd=0;

                   } else if ( base_index < (base_size-20) ) {

                       if (eInd > range) {
                           sInd -= (eInd-range);
                           eInd = range;
                       }
                   } else { /* base_index >= (base_size-20) */

                       if (sInd < (base_size-20)) {
                           sIndAug = 20;
                           sInd = 0;
                           eInd = 0;
                           eIndAug = 19 + CB_RESRANGE;

                           if(eIndAug > 39) {
                               eInd = eIndAug-39;
                               eIndAug = 39;
                           }
                       } else {
                           sIndAug = 20 + sInd - (base_size-20);
                           eIndAug = 39;
                           sInd = 0;
                           eInd = CB_RESRANGE - (eIndAug-sIndAug+1);
                       }
                   }

               } else { /* lTarget = 22 or 23 */

                   if (sInd < 0) {
                       eInd -= sInd;

Top      Up      ToC       Page 159 
                       sInd = 0;
                   }

                   if(eInd > range) {
                       sInd -= (eInd - range);
                       eInd = range;
                   }
               }
           }

           /* search of higher codebook section */

           /* index search range */
           counter = sInd;
           sInd += base_size;
           eInd += base_size;


           if (stage==0) {
               ppe = energy+base_size;
               *ppe=0.0;

               pp=cbvectors+lMem-lTarget;
               for (j=0; j<lTarget; j++) {
                   *ppe+=(*pp)*(*pp++);
               }

               ppi = cbvectors + lMem - 1 - lTarget;
               ppo = cbvectors + lMem - 1;

               for (j=0; j<(range-1); j++) {
                   *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo);
                   ppo--;
                   ppi--;
                   ppe++;
               }
           }

           /* loop over search range */

           for (icount=sInd; icount<eInd; icount++) {

               /* calculate measure */

               crossDot=0.0;
               pp=cbvectors + lMem - (counter++) - lTarget;

               for (j=0;j<lTarget;j++) {

Top      Up      ToC       Page 160 
                   crossDot += target[j]*(*pp++);
               }

               if (energy[icount]>0.0) {
                   invenergy[icount] =(float)1.0/(energy[icount]+EPS);
               } else {
                   invenergy[icount] =(float)0.0;
               }

               if (stage==0) {

                   measure=(float)-10000000.0;

                   if (crossDot > 0.0) {
                       measure = crossDot*crossDot*
                           invenergy[icount];
                   }
               }
               else {
                   measure = crossDot*crossDot*invenergy[icount];
               }

               /* check if measure is better */
               ftmp = crossDot*invenergy[icount];

               if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
                   best_index = icount;
                   max_measure = measure;
                   gain = ftmp;
               }
           }

           /* Search the augmented CB inside the limited range. */

           if ((lTarget==SUBL)&&(sIndAug!=0)) {
               searchAugmentedCB(sIndAug, eIndAug, stage,
                   2*base_size-20, target, cbvectors+lMem,
                   &max_measure, &best_index, &gain, energy,
                   invenergy);
           }

           /* record best index */

           index[stage] = best_index;

           /* gain quantization */

           if (stage==0){

Top      Up      ToC       Page 161 
               if (gain<0.0){
                   gain = 0.0;
               }

               if (gain>CB_MAXGAIN) {
                   gain = (float)CB_MAXGAIN;
               }
               gain = gainquant(gain, 1.0, 32, &gain_index[stage]);
           }
           else {
               if (stage==1) {
                   gain = gainquant(gain, (float)fabs(gains[stage-1]),
                       16, &gain_index[stage]);
               } else {
                   gain = gainquant(gain, (float)fabs(gains[stage-1]),
                       8, &gain_index[stage]);
               }
           }

           /* Extract the best (according to measure)
              codebook vector */

           if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {

               if (index[stage]<base_size) {
                   pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage];
               } else {
                   pp=cbvectors+lMem-lTarget-
                       index[stage]+base_size;
               }
           } else {

               if (index[stage]<base_size) {
                   if (index[stage]<(base_size-20)) {
                       pp=buf+LPC_FILTERORDER+lMem-
                           lTarget-index[stage];
                   } else {
                       createAugmentedVec(index[stage]-base_size+40,
                               buf+LPC_FILTERORDER+lMem,aug_vec);
                       pp=aug_vec;
                   }
               } else {
                   int filterno, position;

                   filterno=index[stage]/base_size;
                   position=index[stage]-filterno*base_size;

Top      Up      ToC       Page 162 
                   if (position<(base_size-20)) {
                       pp=cbvectors+filterno*lMem-lTarget-
                           index[stage]+filterno*base_size;
                   } else {
                       createAugmentedVec(
                           index[stage]-(filterno+1)*base_size+40,
                           cbvectors+filterno*lMem,aug_vec);
                       pp=aug_vec;
                   }
               }
           }

           /* Subtract the best codebook vector, according
              to measure, from the target vector */

           for (j=0;j<lTarget;j++) {
               cvec[j] += gain*(*pp);
               target[j] -= gain*(*pp++);
           }

           /* record quantized gain */

           gains[stage]=gain;

       }/* end of Main Loop. for (stage=0;... */

       /* Gain adjustment for energy matching */
       cene=0.0;
       for (i=0; i<lTarget; i++) {
           cene+=cvec[i]*cvec[i];
       }
       j=gain_index[0];

       for (i=gain_index[0]; i<32; i++) {
           ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];

           if ((ftmp<(tene*gains[0]*gains[0])) &&
               (gain_sq5Tbl[j]<(2.0*gains[0]))) {
               j=i;
           }
       }
       gain_index[0]=j;
   }

Top      Up      ToC       Page 163 
A.35.  LPCdecode.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       LPC_decode.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_LPC_DECODE_H
   #define __iLBC_LPC_DECODE_H

   void LSFinterpolate2a_dec(
       float *a,           /* (o) lpc coefficients for a sub-frame */
       float *lsf1,    /* (i) first lsf coefficient vector */
       float *lsf2,    /* (i) second lsf coefficient vector */
       float coef,         /* (i) interpolation weight */
       int length          /* (i) length of lsf vectors */
   );

   void SimplelsfDEQ(
       float *lsfdeq,      /* (o) dequantized lsf coefficients */
       int *index,         /* (i) quantization index */
       int lpc_n           /* (i) number of LPCs */
   );

   void DecoderInterpolateLSF(
       float *syntdenum,   /* (o) synthesis filter coefficients */
       float *weightdenum, /* (o) weighting denumerator
                                  coefficients */
       float *lsfdeq,      /* (i) dequantized lsf coefficients */
       int length,         /* (i) length of lsf coefficient vector */
       iLBC_Dec_Inst_t *iLBCdec_inst
                           /* (i) the decoder state structure */
   );

   #endif

Top      Up      ToC       Page 164 
A.36.  LPCdecode.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       LPC_decode.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include <math.h>
   #include <string.h>

   #include "helpfun.h"
   #include "lsf.h"
   #include "iLBC_define.h"
   #include "constants.h"

   /*---------------------------------------------------------------*
    *  interpolation of lsf coefficients for the decoder
    *--------------------------------------------------------------*/

   void LSFinterpolate2a_dec(
       float *a,           /* (o) lpc coefficients for a sub-frame */
       float *lsf1,    /* (i) first lsf coefficient vector */
       float *lsf2,    /* (i) second lsf coefficient vector */
       float coef,         /* (i) interpolation weight */
       int length          /* (i) length of lsf vectors */
   ){
       float  lsftmp[LPC_FILTERORDER];

       interpolate(lsftmp, lsf1, lsf2, coef, length);
       lsf2a(a, lsftmp);
   }

   /*---------------------------------------------------------------*
    *  obtain dequantized lsf coefficients from quantization index
    *--------------------------------------------------------------*/

   void SimplelsfDEQ(
       float *lsfdeq,    /* (o) dequantized lsf coefficients */
       int *index,         /* (i) quantization index */
       int lpc_n           /* (i) number of LPCs */
   ){
       int i, j, pos, cb_pos;

Top      Up      ToC       Page 165 
       /* decode first LSF */

       pos = 0;
       cb_pos = 0;
       for (i = 0; i < LSF_NSPLIT; i++) {
           for (j = 0; j < dim_lsfCbTbl[i]; j++) {
               lsfdeq[pos + j] = lsfCbTbl[cb_pos +
                   (long)(index[i])*dim_lsfCbTbl[i] + j];
           }
           pos += dim_lsfCbTbl[i];
           cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
       }

       if (lpc_n>1) {

           /* decode last LSF */

           pos = 0;
           cb_pos = 0;
           for (i = 0; i < LSF_NSPLIT; i++) {
               for (j = 0; j < dim_lsfCbTbl[i]; j++) {
                   lsfdeq[LPC_FILTERORDER + pos + j] =
                       lsfCbTbl[cb_pos +
                       (long)(index[LSF_NSPLIT + i])*
                       dim_lsfCbTbl[i] + j];
               }
               pos += dim_lsfCbTbl[i];
               cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
           }
       }
   }

   /*----------------------------------------------------------------*
    *  obtain synthesis and weighting filters form lsf coefficients
    *---------------------------------------------------------------*/

   void DecoderInterpolateLSF(
       float *syntdenum, /* (o) synthesis filter coefficients */
       float *weightdenum, /* (o) weighting denumerator
                                  coefficients */
       float *lsfdeq,       /* (i) dequantized lsf coefficients */
       int length,         /* (i) length of lsf coefficient vector */
       iLBC_Dec_Inst_t *iLBCdec_inst
                           /* (i) the decoder state structure */
   ){
       int    i, pos, lp_length;
       float  lp[LPC_FILTERORDER + 1], *lsfdeq2;

Top      Up      ToC       Page 166 
       lsfdeq2 = lsfdeq + length;
       lp_length = length + 1;

       if (iLBCdec_inst->mode==30) {
           /* sub-frame 1: Interpolation between old and first */

           LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,
               lsf_weightTbl_30ms[0], length);
           memcpy(syntdenum,lp,lp_length*sizeof(float));
           bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM,
               lp_length);

           /* sub-frames 2 to 6: interpolation between first
              and last LSF */

           pos = lp_length;
           for (i = 1; i < 6; i++) {
               LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2,
                   lsf_weightTbl_30ms[i], length);
               memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
               bwexpand(weightdenum + pos, lp,
                   LPC_CHIRP_WEIGHTDENUM, lp_length);
               pos += lp_length;
           }
       }
       else {
           pos = 0;
           for (i = 0; i < iLBCdec_inst->nsub; i++) {
               LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold,
                   lsfdeq, lsf_weightTbl_20ms[i], length);
               memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
               bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM,
                   lp_length);
               pos += lp_length;
           }
       }

       /* update memory */

       if (iLBCdec_inst->mode==30)
           memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2,
                       length*sizeof(float));
       else
           memcpy(iLBCdec_inst->lsfdeqold, lsfdeq,
                       length*sizeof(float));

   }

Top      Up      ToC       Page 167 
A.37.  LPCencode.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       LPCencode.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_LPCENCOD_H
   #define __iLBC_LPCENCOD_H

   void LPCencode(
       float *syntdenum,   /* (i/o) synthesis filter coefficients
                                  before/after encoding */
       float *weightdenum, /* (i/o) weighting denumerator coefficients
                                  before/after encoding */
       int *lsf_index,     /* (o) lsf quantization index */
       float *data,    /* (i) lsf coefficients to quantize */
       iLBC_Enc_Inst_t *iLBCenc_inst
                           /* (i/o) the encoder state structure */
   );

   #endif

A.38.  LPCencode.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       LPCencode.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include <string.h>

   #include "iLBC_define.h"
   #include "helpfun.h"
   #include "lsf.h"
   #include "constants.h"

Top      Up      ToC       Page 168 
   /*----------------------------------------------------------------*
    *  lpc analysis (subrutine to LPCencode)
    *---------------------------------------------------------------*/

   void SimpleAnalysis(
       float *lsf,         /* (o) lsf coefficients */
       float *data,    /* (i) new data vector */
       iLBC_Enc_Inst_t *iLBCenc_inst
                           /* (i/o) the encoder state structure */
   ){
       int k, is;
       float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1];
       float lp2[LPC_FILTERORDER + 1];
       float r[LPC_FILTERORDER + 1];

       is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
       memcpy(iLBCenc_inst->lpc_buffer+is,data,
           iLBCenc_inst->blockl*sizeof(float));

       /* No lookahead, last window is asymmetric */

       for (k = 0; k < iLBCenc_inst->lpc_n; k++) {

           is = LPC_LOOKBACK;

           if (k < (iLBCenc_inst->lpc_n - 1)) {
               window(temp, lpc_winTbl,
                   iLBCenc_inst->lpc_buffer, BLOCKL_MAX);
           } else {
               window(temp, lpc_asymwinTbl,
                   iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX);
           }

           autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER);
           window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);

           levdurb(lp, temp, r, LPC_FILTERORDER);
           bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);

           a2lsf(lsf + k*LPC_FILTERORDER, lp2);
       }
       is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
       memmove(iLBCenc_inst->lpc_buffer,
           iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is,
           is*sizeof(float));
   }

   /*----------------------------------------------------------------*

Top      Up      ToC       Page 169 
    *  lsf interpolator and conversion from lsf to a coefficients
    *  (subrutine to SimpleInterpolateLSF)
    *---------------------------------------------------------------*/

   void LSFinterpolate2a_enc(
       float *a,       /* (o) lpc coefficients */
       float *lsf1,/* (i) first set of lsf coefficients */
       float *lsf2,/* (i) second set of lsf coefficients */
       float coef,     /* (i) weighting coefficient to use between
                              lsf1 and lsf2 */
       long length      /* (i) length of coefficient vectors */
   ){
       float  lsftmp[LPC_FILTERORDER];

       interpolate(lsftmp, lsf1, lsf2, coef, length);
       lsf2a(a, lsftmp);
   }

   /*----------------------------------------------------------------*
    *  lsf interpolator (subrutine to LPCencode)
    *---------------------------------------------------------------*/

   void SimpleInterpolateLSF(
       float *syntdenum,   /* (o) the synthesis filter denominator
                                  resulting from the quantized
                                  interpolated lsf */
       float *weightdenum, /* (o) the weighting filter denominator
                                  resulting from the unquantized
                                  interpolated lsf */
       float *lsf,         /* (i) the unquantized lsf coefficients */
       float *lsfdeq,      /* (i) the dequantized lsf coefficients */
       float *lsfold,      /* (i) the unquantized lsf coefficients of
                                  the previous signal frame */
       float *lsfdeqold, /* (i) the dequantized lsf coefficients of
                                  the previous signal frame */
       int length,         /* (i) should equate LPC_FILTERORDER */
       iLBC_Enc_Inst_t *iLBCenc_inst
                           /* (i/o) the encoder state structure */
   ){
       int    i, pos, lp_length;
       float  lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2;

       lsf2 = lsf + length;
       lsfdeq2 = lsfdeq + length;
       lp_length = length + 1;

       if (iLBCenc_inst->mode==30) {
           /* sub-frame 1: Interpolation between old and first

Top      Up      ToC       Page 170 
              set of lsf coefficients */

           LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
               lsf_weightTbl_30ms[0], length);
           memcpy(syntdenum,lp,lp_length*sizeof(float));
           LSFinterpolate2a_enc(lp, lsfold, lsf,
               lsf_weightTbl_30ms[0], length);
           bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);

           /* sub-frame 2 to 6: Interpolation between first
              and second set of lsf coefficients */

           pos = lp_length;
           for (i = 1; i < iLBCenc_inst->nsub; i++) {
               LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2,
                   lsf_weightTbl_30ms[i], length);
               memcpy(syntdenum + pos,lp,lp_length*sizeof(float));

               LSFinterpolate2a_enc(lp, lsf, lsf2,
                   lsf_weightTbl_30ms[i], length);
               bwexpand(weightdenum + pos, lp,
                   LPC_CHIRP_WEIGHTDENUM, lp_length);
               pos += lp_length;
           }
       }
       else {
           pos = 0;
           for (i = 0; i < iLBCenc_inst->nsub; i++) {
               LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
                   lsf_weightTbl_20ms[i], length);
               memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
               LSFinterpolate2a_enc(lp, lsfold, lsf,
                   lsf_weightTbl_20ms[i], length);
               bwexpand(weightdenum+pos, lp,
                   LPC_CHIRP_WEIGHTDENUM, lp_length);
               pos += lp_length;
           }
       }

       /* update memory */

       if (iLBCenc_inst->mode==30) {
           memcpy(lsfold, lsf2, length*sizeof(float));
           memcpy(lsfdeqold, lsfdeq2, length*sizeof(float));
       }
       else {
           memcpy(lsfold, lsf, length*sizeof(float));
           memcpy(lsfdeqold, lsfdeq, length*sizeof(float));

Top      Up      ToC       Page 171 
       }
   }

   /*----------------------------------------------------------------*
    *  lsf quantizer (subrutine to LPCencode)
    *---------------------------------------------------------------*/

   void SimplelsfQ(
       float *lsfdeq,    /* (o) dequantized lsf coefficients
                              (dimension FILTERORDER) */
       int *index,     /* (o) quantization index */
       float *lsf,      /* (i) the lsf coefficient vector to be
                              quantized (dimension FILTERORDER ) */
       int lpc_n     /* (i) number of lsf sets to quantize */
   ){
       /* Quantize first LSF with memoryless split VQ */
       SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT,
           dim_lsfCbTbl, size_lsfCbTbl);

       if (lpc_n==2) {
           /* Quantize second LSF with memoryless split VQ */
           SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT,
               lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT,
               dim_lsfCbTbl, size_lsfCbTbl);
       }
   }

   /*----------------------------------------------------------------*
    *  lpc encoder
    *---------------------------------------------------------------*/

   void LPCencode(
       float *syntdenum, /* (i/o) synthesis filter coefficients
                                  before/after encoding */
       float *weightdenum, /* (i/o) weighting denumerator
                                  coefficients before/after
                                  encoding */
       int *lsf_index,     /* (o) lsf quantization index */
       float *data,    /* (i) lsf coefficients to quantize */
       iLBC_Enc_Inst_t *iLBCenc_inst
                           /* (i/o) the encoder state structure */
   ){
       float lsf[LPC_FILTERORDER * LPC_N_MAX];
       float lsfdeq[LPC_FILTERORDER * LPC_N_MAX];
       int change=0;

       SimpleAnalysis(lsf, data, iLBCenc_inst);
       SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);

Top      Up      ToC       Page 172 
       change=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n);
       SimpleInterpolateLSF(syntdenum, weightdenum,
           lsf, lsfdeq, iLBCenc_inst->lsfold,
           iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst);
   }

A.39.  lsf.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       lsf.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_LSF_H
   #define __iLBC_LSF_H

   void a2lsf(
       float *freq,/* (o) lsf coefficients */
       float *a    /* (i) lpc coefficients */
   );

   void lsf2a(
       float *a_coef,  /* (o) lpc coefficients */
       float *freq     /* (i) lsf coefficients */
   );

   #endif

A.40.  lsf.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       lsf.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include <string.h>

Top      Up      ToC       Page 173 
   #include <math.h>

   #include "iLBC_define.h"

   /*----------------------------------------------------------------*
    *  conversion from lpc coefficients to lsf coefficients
    *---------------------------------------------------------------*/

   void a2lsf(
       float *freq,/* (o) lsf coefficients */
       float *a    /* (i) lpc coefficients */
   ){
       float steps[LSF_NUMBER_OF_STEPS] =
           {(float)0.00635, (float)0.003175, (float)0.0015875,
           (float)0.00079375};
       float step;
       int step_idx;
       int lsp_index;
       float p[LPC_HALFORDER];
       float q[LPC_HALFORDER];
       float p_pre[LPC_HALFORDER];
       float q_pre[LPC_HALFORDER];
       float old_p, old_q, *old;
       float *pq_coef;
       float omega, old_omega;
       int i;
       float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;

       for (i=0; i<LPC_HALFORDER; i++) {
           p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]);
           q[i] = a[LPC_FILTERORDER - i] - a[i + 1];
       }

       p_pre[0] = (float)-1.0 - p[0];
       p_pre[1] = - p_pre[0] - p[1];
       p_pre[2] = - p_pre[1] - p[2];
       p_pre[3] = - p_pre[2] - p[3];
       p_pre[4] = - p_pre[3] - p[4];
       p_pre[4] = p_pre[4] / 2;

       q_pre[0] = (float)1.0 - q[0];
       q_pre[1] = q_pre[0] - q[1];
       q_pre[2] = q_pre[1] - q[2];
       q_pre[3] = q_pre[2] - q[3];
       q_pre[4] = q_pre[3] - q[4];
       q_pre[4] = q_pre[4] / 2;

       omega = 0.0;

Top      Up      ToC       Page 174 
       old_omega = 0.0;

       old_p = FLOAT_MAX;
       old_q = FLOAT_MAX;

       /* Here we loop through lsp_index to find all the
          LPC_FILTERORDER roots for omega. */

       for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) {

           /* Depending on lsp_index being even or odd, we
           alternatively solve the roots for the two LSP equations. */


           if ((lsp_index & 0x1) == 0) {
               pq_coef = p_pre;
               old = &old_p;
           } else {
               pq_coef = q_pre;
               old = &old_q;
           }

           /* Start with low resolution grid */

           for (step_idx = 0, step = steps[step_idx];
               step_idx < LSF_NUMBER_OF_STEPS;){

               /*  cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +
               pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */

               hlp = (float)cos(omega * TWO_PI);
               hlp1 = (float)2.0 * hlp + pq_coef[0];
               hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 +
                   pq_coef[1];
               hlp3 = (float)2.0 * hlp * hlp2 - hlp1 + pq_coef[2];
               hlp4 = (float)2.0 * hlp * hlp3 - hlp2 + pq_coef[3];
               hlp5 = hlp * hlp4 - hlp3 + pq_coef[4];


               if (((hlp5 * (*old)) <= 0.0) || (omega >= 0.5)){

                   if (step_idx == (LSF_NUMBER_OF_STEPS - 1)){

                       if (fabs(hlp5) >= fabs(*old)) {
                           freq[lsp_index] = omega - step;
                       } else {
                           freq[lsp_index] = omega;
                       }

Top      Up      ToC       Page 175 
                       if ((*old) >= 0.0){
                           *old = (float)-1.0 * FLOAT_MAX;
                       } else {
                           *old = FLOAT_MAX;
                       }

                       omega = old_omega;
                       step_idx = 0;

                       step_idx = LSF_NUMBER_OF_STEPS;
                   } else {

                       if (step_idx == 0) {
                           old_omega = omega;
                       }

                       step_idx++;
                       omega -= steps[step_idx];

                       /* Go back one grid step */

                       step = steps[step_idx];
                   }
               } else {

               /* increment omega until they are of different sign,
               and we know there is at least one root between omega
               and old_omega */
                   *old = hlp5;
                   omega += step;
               }
           }
       }

       for (i = 0; i<LPC_FILTERORDER; i++) {
           freq[i] = freq[i] * TWO_PI;
       }
   }

   /*----------------------------------------------------------------*
    *  conversion from lsf coefficients to lpc coefficients
    *---------------------------------------------------------------*/

   void lsf2a(
       float *a_coef,  /* (o) lpc coefficients */
       float *freq     /* (i) lsf coefficients */

Top      Up      ToC       Page 176 
   ){
       int i, j;
       float hlp;
       float p[LPC_HALFORDER], q[LPC_HALFORDER];
       float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER],
           a2[LPC_HALFORDER];
       float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER],
           b2[LPC_HALFORDER];

       for (i=0; i<LPC_FILTERORDER; i++) {
           freq[i] = freq[i] * PI2;
       }

       /* Check input for ill-conditioned cases.  This part is not
       found in the TIA standard.  It involves the following 2 IF
       blocks.  If "freq" is judged ill-conditioned, then we first
       modify freq[0] and freq[LPC_HALFORDER-1] (normally
       LPC_HALFORDER = 10 for LPC applications), then we adjust
       the other "freq" values slightly */


       if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){


           if (freq[0] <= 0.0) {
               freq[0] = (float)0.022;
           }


           if (freq[LPC_FILTERORDER - 1] >= 0.5) {
               freq[LPC_FILTERORDER - 1] = (float)0.499;
           }

           hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) /
               (float) (LPC_FILTERORDER - 1);

           for (i=1; i<LPC_FILTERORDER; i++) {
               freq[i] = freq[i - 1] + hlp;
           }
       }

       memset(a1, 0, LPC_HALFORDER*sizeof(float));
       memset(a2, 0, LPC_HALFORDER*sizeof(float));
       memset(b1, 0, LPC_HALFORDER*sizeof(float));
       memset(b2, 0, LPC_HALFORDER*sizeof(float));
       memset(a, 0, (LPC_HALFORDER+1)*sizeof(float));
       memset(b, 0, (LPC_HALFORDER+1)*sizeof(float));

Top      Up      ToC       Page 177 
       /* p[i] and q[i] compute cos(2*pi*omega_{2j}) and
       cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2.
       Note that for this code p[i] specifies the coefficients
       used in .Q_A(z) while q[i] specifies the coefficients used
       in .P_A(z) */

       for (i=0; i<LPC_HALFORDER; i++) {
           p[i] = (float)cos(TWO_PI * freq[2 * i]);
           q[i] = (float)cos(TWO_PI * freq[2 * i + 1]);
       }

       a[0] = 0.25;
       b[0] = 0.25;

       for (i= 0; i<LPC_HALFORDER; i++) {
           a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];
           b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
           a2[i] = a1[i];
           a1[i] = a[i];
           b2[i] = b1[i];
           b1[i] = b[i];
       }

       for (j=0; j<LPC_FILTERORDER; j++) {

           if (j == 0) {
               a[0] = 0.25;
               b[0] = -0.25;
           } else {
               a[0] = b[0] = 0.0;
           }

           for (i=0; i<LPC_HALFORDER; i++) {
               a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];
               b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
               a2[i] = a1[i];
               a1[i] = a[i];
               b2[i] = b1[i];
               b1[i] = b[i];
           }

           a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]);
       }

       a_coef[0] = 1.0;
   }

Top      Up      ToC       Page 178 
A.41.  packing.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       packing.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __PACKING_H
   #define __PACKING_H

   void packsplit(
       int *index,                 /* (i) the value to split */
       int *firstpart,             /* (o) the value specified by most
                                          significant bits */
       int *rest,                  /* (o) the value specified by least
                                          significant bits */
       int bitno_firstpart,    /* (i) number of bits in most
                                          significant part */
       int bitno_total             /* (i) number of bits in full range
                                          of value */
   );

   void packcombine(
       int *index,                 /* (i/o) the msb value in the
                                          combined value out */
       int rest,                   /* (i) the lsb value */
       int bitno_rest              /* (i) the number of bits in the
                                          lsb part */
   );

   void dopack(
       unsigned char **bitstream,  /* (i/o) on entrance pointer to
                                          place in bitstream to pack
                                          new data, on exit pointer
                                          to place in bitstream to
                                          pack future data */
       int index,                  /* (i) the value to pack */
       int bitno,                  /* (i) the number of bits that the
                                          value will fit within */
       int *pos                /* (i/o) write position in the
                                          current byte */
   );

Top      Up      ToC       Page 179 
   void unpack(
       unsigned char **bitstream,  /* (i/o) on entrance pointer to
                                          place in bitstream to
                                          unpack new data from, on
                                          exit pointer to place in
                                          bitstream to unpack future
                                          data from */
       int *index,                 /* (o) resulting value */
       int bitno,                  /* (i) number of bits used to
                                          represent the value */
       int *pos                /* (i/o) read position in the
                                          current byte */
   );

   #endif

A.42.  packing.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       packing.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

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

   #include "iLBC_define.h"
   #include "constants.h"
   #include "helpfun.h"
   #include "string.h"

   /*----------------------------------------------------------------*
    *  splitting an integer into first most significant bits and
    *  remaining least significant bits
    *---------------------------------------------------------------*/

   void packsplit(
       int *index,                 /* (i) the value to split */
       int *firstpart,             /* (o) the value specified by most
                                          significant bits */
       int *rest,                  /* (o) the value specified by least
                                          significant bits */

Top      Up      ToC       Page 180 
       int bitno_firstpart,    /* (i) number of bits in most
                                          significant part */
       int bitno_total             /* (i) number of bits in full range
                                          of value */
   ){
       int bitno_rest = bitno_total-bitno_firstpart;

       *firstpart = *index>>(bitno_rest);
       *rest = *index-(*firstpart<<(bitno_rest));
   }

   /*----------------------------------------------------------------*
    *  combining a value corresponding to msb's with a value
    *  corresponding to lsb's
    *---------------------------------------------------------------*/

   void packcombine(
       int *index,                 /* (i/o) the msb value in the
                                          combined value out */
       int rest,                   /* (i) the lsb value */
       int bitno_rest              /* (i) the number of bits in the
                                          lsb part */
   ){
       *index = *index<<bitno_rest;
       *index += rest;
   }

   /*----------------------------------------------------------------*
    *  packing of bits into bitstream, i.e., vector of bytes
    *---------------------------------------------------------------*/

   void dopack(
       unsigned char **bitstream,  /* (i/o) on entrance pointer to
                                          place in bitstream to pack
                                          new data, on exit pointer
                                          to place in bitstream to
                                          pack future data */
       int index,                  /* (i) the value to pack */
       int bitno,                  /* (i) the number of bits that the
                                          value will fit within */
       int *pos                /* (i/o) write position in the
                                          current byte */
   ){
       int posLeft;

       /* Clear the bits before starting in a new byte */

       if ((*pos)==0) {

Top      Up      ToC       Page 181 
           **bitstream=0;
       }

       while (bitno>0) {

           /* Jump to the next byte if end of this byte is reached*/

           if (*pos==8) {
               *pos=0;
               (*bitstream)++;
               **bitstream=0;
           }

           posLeft=8-(*pos);

           /* Insert index into the bitstream */

           if (bitno <= posLeft) {
               **bitstream |= (unsigned char)(index<<(posLeft-bitno));
               *pos+=bitno;
               bitno=0;
           } else {
               **bitstream |= (unsigned char)(index>>(bitno-posLeft));

               *pos=8;
               index-=((index>>(bitno-posLeft))<<(bitno-posLeft));

               bitno-=posLeft;
           }
       }
   }

   /*----------------------------------------------------------------*
    *  unpacking of bits from bitstream, i.e., vector of bytes
    *---------------------------------------------------------------*/

   void unpack(
       unsigned char **bitstream,  /* (i/o) on entrance pointer to
                                          place in bitstream to
                                          unpack new data from, on
                                          exit pointer to place in
                                          bitstream to unpack future
                                          data from */
       int *index,                 /* (o) resulting value */
       int bitno,                  /* (i) number of bits used to
                                          represent the value */
       int *pos                /* (i/o) read position in the
                                          current byte */

Top      Up      ToC       Page 182 
   ){
       int BitsLeft;

       *index=0;

       while (bitno>0) {

           /* move forward in bitstream when the end of the
              byte is reached */

           if (*pos==8) {
               *pos=0;
               (*bitstream)++;
           }

           BitsLeft=8-(*pos);

           /* Extract bits to index */

           if (BitsLeft>=bitno) {
               *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));

               *pos+=bitno;
               bitno=0;
           } else {

               if ((8-bitno)>0) {
                   *index+=((((**bitstream)<<(*pos)) & 0xFF)>>
                       (8-bitno));
                   *pos=8;
               } else {
                   *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<<
                       (bitno-8));
                   *pos=8;
               }
               bitno-=BitsLeft;
           }
       }
   }

A.43.  StateConstructW.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       StateConstructW.h

Top      Up      ToC       Page 183 
       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_STATECONSTRUCTW_H
   #define __iLBC_STATECONSTRUCTW_H

   void StateConstructW(
       int idxForMax,      /* (i) 6-bit index for the quantization of
                                  max amplitude */
       int *idxVec,    /* (i) vector of quantization indexes */
       float *syntDenum,   /* (i) synthesis filter denumerator */
       float *out,         /* (o) the decoded state vector */
       int len             /* (i) length of a state vector */
   );

   #endif

A.44.  StateConstructW.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       StateConstructW.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include <math.h>
   #include <string.h>

   #include "iLBC_define.h"
   #include "constants.h"
   #include "filter.h"

   /*----------------------------------------------------------------*
    *  decoding of the start state
    *---------------------------------------------------------------*/

   void StateConstructW(
       int idxForMax,      /* (i) 6-bit index for the quantization of
                                  max amplitude */
       int *idxVec,    /* (i) vector of quantization indexes */
       float *syntDenum,   /* (i) synthesis filter denumerator */

Top      Up      ToC       Page 184 
       float *out,         /* (o) the decoded state vector */
       int len             /* (i) length of a state vector */
   ){
       float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp,
           numerator[LPC_FILTERORDER+1];
       float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout;
       int k,tmpi;

       /* decoding of the maximum value */

       maxVal = state_frgqTbl[idxForMax];
       maxVal = (float)pow(10,maxVal)/(float)4.5;

       /* initialization of buffers and coefficients */

       memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
       memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
       for (k=0; k<LPC_FILTERORDER; k++) {
           numerator[k]=syntDenum[LPC_FILTERORDER-k];
       }
       numerator[LPC_FILTERORDER]=syntDenum[0];
       tmp = &tmpbuf[LPC_FILTERORDER];
       fout = &foutbuf[LPC_FILTERORDER];

       /* decoding of the sample values */

       for (k=0; k<len; k++) {
           tmpi = len-1-k;
           /* maxVal = 1/scal */
           tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]];
       }

       /* circular convolution with all-pass filter */

       memset(tmp+len, 0, len*sizeof(float));
       ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
           LPC_FILTERORDER, fout);
       for (k=0;k<len;k++) {
           out[k] = fout[len-1-k]+fout[2*len-1-k];
       }
   }

Top      Up      ToC       Page 185 
A.45.  StateSearchW.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       StateSearchW.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_STATESEARCHW_H
   #define __iLBC_STATESEARCHW_H

   void AbsQuantW(
       iLBC_Enc_Inst_t *iLBCenc_inst,
                           /* (i) Encoder instance */
       float *in,          /* (i) vector to encode */
       float *syntDenum,   /* (i) denominator of synthesis filter */
       float *weightDenum, /* (i) denominator of weighting filter */
       int *out,           /* (o) vector of quantizer indexes */
       int len,        /* (i) length of vector to encode and
                                  vector of quantizer indexes */
       int state_first     /* (i) position of start state in the
                                  80 vec */
   );

   void StateSearchW(
       iLBC_Enc_Inst_t *iLBCenc_inst,
                           /* (i) Encoder instance */
       float *residual,/* (i) target residual vector */
       float *syntDenum,   /* (i) lpc synthesis filter */
       float *weightDenum, /* (i) weighting filter denuminator */
       int *idxForMax,     /* (o) quantizer index for maximum
                                  amplitude */
       int *idxVec,    /* (o) vector of quantization indexes */
       int len,        /* (i) length of all vectors */
       int state_first     /* (i) position of start state in the
                                  80 vec */
   );


   #endif

Top      Up      ToC       Page 186 
A.46.  StateSearchW.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       StateSearchW.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include <math.h>
   #include <string.h>

   #include "iLBC_define.h"
   #include "constants.h"
   #include "filter.h"
   #include "helpfun.h"

   /*----------------------------------------------------------------*
    *  predictive noise shaping encoding of scaled start state
    *  (subrutine for StateSearchW)
    *---------------------------------------------------------------*/

   void AbsQuantW(
       iLBC_Enc_Inst_t *iLBCenc_inst,
                           /* (i) Encoder instance */
       float *in,          /* (i) vector to encode */
       float *syntDenum,   /* (i) denominator of synthesis filter */
       float *weightDenum, /* (i) denominator of weighting filter */
       int *out,           /* (o) vector of quantizer indexes */
       int len,        /* (i) length of vector to encode and
                                  vector of quantizer indexes */
       int state_first     /* (i) position of start state in the
                                  80 vec */
   ){
       float *syntOut;
       float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];
       float toQ, xq;
       int n;
       int index;

       /* initialization of buffer for filtering */

       memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));

Top      Up      ToC       Page 187 
       /* initialization of pointer for filtering */

       syntOut = &syntOutBuf[LPC_FILTERORDER];

       /* synthesis and weighting filters on input */

       if (state_first) {
           AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER);
       } else {
           AllPoleFilter (in, weightDenum,
               iLBCenc_inst->state_short_len-SUBL,
               LPC_FILTERORDER);
       }

       /* encoding loop */

       for (n=0; n<len; n++) {

           /* time update of filter coefficients */

           if ((state_first)&&(n==SUBL)){
               syntDenum += (LPC_FILTERORDER+1);
               weightDenum += (LPC_FILTERORDER+1);

               /* synthesis and weighting filters on input */
               AllPoleFilter (&in[n], weightDenum, len-n,
                   LPC_FILTERORDER);

           } else if ((state_first==0)&&
               (n==(iLBCenc_inst->state_short_len-SUBL))) {
               syntDenum += (LPC_FILTERORDER+1);
               weightDenum += (LPC_FILTERORDER+1);

               /* synthesis and weighting filters on input */
               AllPoleFilter (&in[n], weightDenum, len-n,
                   LPC_FILTERORDER);

           }

           /* prediction of synthesized and weighted input */

           syntOut[n] = 0.0;
           AllPoleFilter (&syntOut[n], weightDenum, 1,
               LPC_FILTERORDER);

           /* quantization */

           toQ = in[n]-syntOut[n];

Top      Up      ToC       Page 188 
           sort_sq(&xq, &index, toQ, state_sq3Tbl, 8);
           out[n]=index;
           syntOut[n] = state_sq3Tbl[out[n]];

           /* update of the prediction filter */

           AllPoleFilter(&syntOut[n], weightDenum, 1,
               LPC_FILTERORDER);
       }
   }

   /*----------------------------------------------------------------*
    *  encoding of start state
    *---------------------------------------------------------------*/

   void StateSearchW(
       iLBC_Enc_Inst_t *iLBCenc_inst,
                           /* (i) Encoder instance */
       float *residual,/* (i) target residual vector */
       float *syntDenum,   /* (i) lpc synthesis filter */
       float *weightDenum, /* (i) weighting filter denuminator */
       int *idxForMax,     /* (o) quantizer index for maximum
                                  amplitude */
       int *idxVec,    /* (o) vector of quantization indexes */
       int len,        /* (i) length of all vectors */
       int state_first     /* (i) position of start state in the
                                  80 vec */
   ){
       float dtmp, maxVal;
       float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS];
       float *tmp, numerator[1+LPC_FILTERORDER];
       float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout;
       int k;
       float qmax, scal;

       /* initialization of buffers and filter coefficients */

       memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
       memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
       for (k=0; k<LPC_FILTERORDER; k++) {
           numerator[k]=syntDenum[LPC_FILTERORDER-k];
       }
       numerator[LPC_FILTERORDER]=syntDenum[0];
       tmp = &tmpbuf[LPC_FILTERORDER];
       fout = &foutbuf[LPC_FILTERORDER];

       /* circular convolution with the all-pass filter */

Top      Up      ToC       Page 189 
       memcpy(tmp, residual, len*sizeof(float));
       memset(tmp+len, 0, len*sizeof(float));
       ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
           LPC_FILTERORDER, fout);
       for (k=0; k<len; k++) {
           fout[k] += fout[k+len];
       }

       /* identification of the maximum amplitude value */

       maxVal = fout[0];
       for (k=1; k<len; k++) {

           if (fout[k]*fout[k] > maxVal*maxVal){
               maxVal = fout[k];
           }
       }
       maxVal=(float)fabs(maxVal);

       /* encoding of the maximum amplitude value */

       if (maxVal < 10.0) {
           maxVal = 10.0;
       }
       maxVal = (float)log10(maxVal);
       sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64);

       /* decoding of the maximum amplitude representation value,
          and corresponding scaling of start state */

       maxVal=state_frgqTbl[*idxForMax];
       qmax = (float)pow(10,maxVal);
       scal = (float)(4.5)/qmax;
       for (k=0; k<len; k++){
           fout[k] *= scal;
       }

       /* predictive noise shaping encoding of scaled start state */

       AbsQuantW(iLBCenc_inst, fout,syntDenum,
           weightDenum,idxVec, len, state_first);
   }

Top      Up      ToC       Page 190 
A.47.  syntFilter.h

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       syntFilter.h

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #ifndef __iLBC_SYNTFILTER_H
   #define __iLBC_SYNTFILTER_H

   void syntFilter(
       float *Out,     /* (i/o) Signal to be filtered */
       float *a,       /* (i) LP parameters */
       int len,    /* (i) Length of signal */
       float *mem      /* (i/o) Filter state */
   );

   #endif

A.48.  syntFilter.c

   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       syntFilter.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

   #include "iLBC_define.h"

   /*----------------------------------------------------------------*
    *  LP synthesis filter.
    *---------------------------------------------------------------*/

   void syntFilter(
       float *Out,     /* (i/o) Signal to be filtered */
       float *a,       /* (i) LP parameters */
       int len,    /* (i) Length of signal */

Top      Up      ToC       Page 191 
       float *mem      /* (i/o) Filter state */
   ){
       int i, j;
       float *po, *pi, *pa, *pm;

       po=Out;

       /* Filter first part using memory from past */

       for (i=0; i<LPC_FILTERORDER; i++) {
           pi=&Out[i-1];
           pa=&a[1];
           pm=&mem[LPC_FILTERORDER-1];
           for (j=1; j<=i; j++) {
               *po-=(*pa++)*(*pi--);
           }
           for (j=i+1; j<LPC_FILTERORDER+1; j++) {
               *po-=(*pa++)*(*pm--);
           }
           po++;
       }

       /* Filter last part where the state is entirely in
          the output vector */

       for (i=LPC_FILTERORDER; i<len; i++) {
           pi=&Out[i-1];
           pa=&a[1];
           for (j=1; j<LPC_FILTERORDER+1; j++) {
               *po-=(*pa++)*(*pi--);
           }
           po++;
       }

       /* Update state vector */

       memcpy(mem, &Out[len-LPC_FILTERORDER],
           LPC_FILTERORDER*sizeof(float));
   }

Top      Up      ToC       Page 192 
Authors' Addresses

   Soren Vang Andersen
   Department of Communication Technology
   Aalborg University
   Fredrik Bajers Vej 7A
   9200 Aalborg
   Denmark

   Phone:  ++45 9 6358627
   EMail:  sva@kom.auc.dk


   Alan Duric
   Telio AS
   Stoperigt. 2
   Oslo, N-0250
   Norway

   Phone:  +47 21673555
   EMail:  alan.duric@telio.no


   Henrik Astrom
   Global IP Sound AB
   Olandsgatan 42
   Stockholm, S-11663
   Sweden

   Phone:  +46 8 54553040
   EMail:  henrik.astrom@globalipsound.com


   Roar Hagen
   Global IP Sound AB
   Olandsgatan 42
   Stockholm, S-11663
   Sweden

   Phone:  +46 8 54553040
   EMail:  roar.hagen@globalipsound.com

Top      Up      ToC       Page 193 
   W. Bastiaan Kleijn
   Global IP Sound AB
   Olandsgatan 42
   Stockholm, S-11663
   Sweden

   Phone:  +46 8 54553040
   EMail:  bastiaan.kleijn@globalipsound.com


   Jan Linden
   Global IP Sound Inc.
   900 Kearny Street, suite 500
   San Francisco, CA-94133
   USA

   Phone: +1 415 397 2555
   EMail: jan.linden@globalipsound.com

Top      Up      ToC       Page 194 
Full Copyright Statement

   Copyright (C) The Internet Society (2004).

   This document is subject to the rights, licenses and restrictions
   contained in BCP 78, and except as set forth therein, the authors
   retain all their rights.

   This document and the information contained herein are provided on an
   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

   The IETF takes no position regarding the validity or scope of any
   Intellectual Property Rights or other rights that might be claimed to
   pertain to the implementation or use of the technology described in
   this document or the extent to which any license under such rights
   might or might not be available; nor does it represent that it has
   made any independent effort to identify any such rights.  Information
   on the IETF's procedures with respect to rights in IETF Documents can
   be found in BCP 78 and BCP 79.

   Copies of IPR disclosures made to the IETF Secretariat and any
   assurances of licenses to be made available, or the result of an
   attempt made to obtain a general license or permission for the use of
   such proprietary rights by implementers or users of this
   specification can be obtained from the IETF on-line IPR repository at
   http://www.ietf.org/ipr.

   The IETF invites any interested party to bring to its attention any
   copyrights, patents or patent applications, or other proprietary
   rights that may cover technology that may be required to implement
   this standard.  Please address the information to the IETF at ietf-
   ipr@ietf.org.


Acknowledgement

   Funding for the RFC Editor function is currently provided by the
   Internet Society.