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  * entropy_coding.c
     13  *
     14  * This file contains all functions used to arithmetically
     15  * encode the iSAC bistream.
     16  *
     17  */
     18 
     19 #include <stddef.h>
     20 
     21 #include "arith_routins.h"
     22 #include "spectrum_ar_model_tables.h"
     23 #include "pitch_gain_tables.h"
     24 #include "pitch_lag_tables.h"
     25 #include "entropy_coding.h"
     26 #include "lpc_tables.h"
     27 #include "settings.h"
     28 #include "signal_processing_library.h"
     29 
     30 
     31 /*
     32   This function implements the fix-point correspondant function to lrint.
     33 
     34   FLP: (WebRtc_Word32)floor(flt+.499999999999)
     35   FIP: (fixVal+roundVal)>>qDomain
     36 
     37   where roundVal = 2^(qDomain-1) = 1<<(qDomain-1)
     38 
     39 */
     40 static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) {
     41   WebRtc_Word32 intgr;
     42   WebRtc_Word32 roundVal;
     43 
     44   roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1);
     45   intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain);
     46 
     47   return intgr;
     48 }
     49 
     50 /*
     51   __inline WebRtc_UWord32 stepwise(WebRtc_Word32 dinQ10) {
     52 
     53   WebRtc_Word32 ind, diQ10, dtQ10;
     54 
     55   diQ10 = dinQ10;
     56   if (diQ10 < DPMIN_Q10)
     57   diQ10 = DPMIN_Q10;
     58   if (diQ10 >= DPMAX_Q10)
     59   diQ10 = DPMAX_Q10 - 1;
     60 
     61   dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */
     62 /* ind = (dtQ10 * 5) >> 10;  */ /* 2^10 / 5 = 0.2 in Q10  */
     63 /* Q10 -> Q0 */
     64 
     65 /* return rpointsFIX_Q10[ind];
     66 
     67    }
     68 */
     69 
     70 /* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */
     71 /* The input argument X to logN(X) is 2^17 times higher than the
     72    input floating point argument Y to log(Y), since the X value
     73    is a Q17 value. This can be compensated for after the call, by
     74    subraction a value Z for each Q-step. One Q-step means that
     75    X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
     76    177.445678 should be subtracted (since logN() returns a Q8 value).
     77    For a X value in Q17, the value 177.445678*17 = 3017 should be
     78    subtracted */
     79 static WebRtc_Word16 CalcLogN(WebRtc_Word32 arg) {
     80   WebRtc_Word16 zeros, log2, frac, logN;
     81 
     82   zeros=WebRtcSpl_NormU32(arg);
     83   frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_LSHIFT_W32(arg, zeros)&0x7FFFFFFF, 23);
     84   log2=(WebRtc_Word16)(WEBRTC_SPL_LSHIFT_W32(31-zeros, 8)+frac); // log2(x) in Q8
     85   logN=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2,22713,15); //Q8*Q15 log(2) = 0.693147 = 22713 in Q15
     86   logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x.
     87 
     88   return logN;
     89 }
     90 
     91 
     92 /*
     93   expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695
     94 
     95   Input:  Q8  (WebRtc_Word16)
     96   Output: Q17 (WebRtc_Word32)
     97 
     98   a = log2(e) = log2(exp(1)) ~= 1.442695  ==>  a = 23637 in Q14 (1.442688)
     99   To this value, 700 is added or subtracted in order to get an average error
    100   nearer zero, instead of always same-sign.
    101 */
    102 
    103 static WebRtc_Word32 CalcExpN(WebRtc_Word16 x) {
    104   WebRtc_Word16 ax, axINT, axFRAC;
    105   WebRtc_Word16 exp16;
    106   WebRtc_Word32 exp;
    107 
    108   if (x>=0) {
    109     //  ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637-700, 14); //Q8
    110     ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8
    111     axINT = WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0
    112     axFRAC = ax&0x00FF;
    113     exp16 = WEBRTC_SPL_LSHIFT_W32(1, axINT); //Q0
    114     axFRAC = axFRAC+256; //Q8
    115     exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q0*Q8 = Q8
    116     exp = WEBRTC_SPL_LSHIFT_W32(exp, 9); //Q17
    117   } else {
    118     //  ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637+700, 14); //Q8
    119     ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8
    120     ax = -ax;
    121     axINT = 1 + WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0
    122     axFRAC = 0x00FF - (ax&0x00FF);
    123     exp16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15
    124     axFRAC = axFRAC+256; //Q8
    125     exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23
    126     exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17
    127   }
    128 
    129   return exp;
    130 }
    131 
    132 
    133 /* compute correlation from power spectrum */
    134 static void CalcCorrelation(WebRtc_Word32 *PSpecQ12, WebRtc_Word32 *CorrQ7)
    135 {
    136   WebRtc_Word32 summ[FRAMESAMPLES/8];
    137   WebRtc_Word32 diff[FRAMESAMPLES/8];
    138   WebRtc_Word32 sum;
    139   int k, n;
    140 
    141   for (k = 0; k < FRAMESAMPLES/8; k++) {
    142     summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
    143     diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
    144   }
    145 
    146   sum = 2;
    147   for (n = 0; n < FRAMESAMPLES/8; n++)
    148     sum += summ[n];
    149   CorrQ7[0] = sum;
    150 
    151   for (k = 0; k < AR_ORDER; k += 2) {
    152     sum = 0;
    153     for (n = 0; n < FRAMESAMPLES/8; n++)
    154       sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9);
    155     CorrQ7[k+1] = sum;
    156   }
    157 
    158   for (k=1; k<AR_ORDER; k+=2) {
    159     sum = 0;
    160     for (n = 0; n < FRAMESAMPLES/8; n++)
    161       sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9);
    162     CorrQ7[k+1] = sum;
    163   }
    164 }
    165 
    166 
    167 /* compute inverse AR power spectrum */
    168 static void CalcInvArSpec(const WebRtc_Word16 *ARCoefQ12,
    169                           const WebRtc_Word32 gainQ10,
    170                           WebRtc_Word32 *CurveQ16)
    171 {
    172   WebRtc_Word32 CorrQ11[AR_ORDER+1];
    173   WebRtc_Word32 sum, tmpGain;
    174   WebRtc_Word32 diffQ16[FRAMESAMPLES/8];
    175   const WebRtc_Word16 *CS_ptrQ9;
    176   int k, n;
    177   WebRtc_Word16 round, shftVal = 0, sh;
    178 
    179   sum = 0;
    180   for (n = 0; n < AR_ORDER+1; n++)
    181     sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]);    /* Q24 */
    182   sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16);    /* result in Q8 */
    183   CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
    184 
    185   /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
    186   if(gainQ10>400000){
    187     tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
    188     round = 32;
    189     shftVal = 6;
    190   } else {
    191     tmpGain = gainQ10;
    192     round = 256;
    193     shftVal = 9;
    194   }
    195 
    196   for (k = 1; k < AR_ORDER+1; k++) {
    197     sum = 16384;
    198     for (n = k; n < AR_ORDER+1; n++)
    199       sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]);  /* Q24 */
    200     sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
    201     CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
    202   }
    203   sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
    204   for (n = 0; n < FRAMESAMPLES/8; n++)
    205     CurveQ16[n] = sum;
    206 
    207   for (k = 1; k < AR_ORDER; k += 2) {
    208     for (n = 0; n < FRAMESAMPLES/8; n++)
    209       CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2);
    210   }
    211 
    212   CS_ptrQ9 = WebRtcIsacfix_kCos[0];
    213 
    214   /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */
    215   sh=WebRtcSpl_NormW32(CorrQ11[1]);
    216   if (CorrQ11[1]==0) /* Use next correlation */
    217     sh=WebRtcSpl_NormW32(CorrQ11[2]);
    218 
    219   if (sh<9)
    220     shftVal = 9 - sh;
    221   else
    222     shftVal = 0;
    223 
    224   for (n = 0; n < FRAMESAMPLES/8; n++)
    225     diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
    226   for (k = 2; k < AR_ORDER; k += 2) {
    227     CS_ptrQ9 = WebRtcIsacfix_kCos[k];
    228     for (n = 0; n < FRAMESAMPLES/8; n++)
    229       diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
    230   }
    231 
    232   for (k=0; k<FRAMESAMPLES/8; k++) {
    233     CurveQ16[FRAMESAMPLES/4-1 - k] = CurveQ16[k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
    234     CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
    235   }
    236 }
    237 
    238 static void CalcRootInvArSpec(const WebRtc_Word16 *ARCoefQ12,
    239                               const WebRtc_Word32 gainQ10,
    240                               WebRtc_UWord16 *CurveQ8)
    241 {
    242   WebRtc_Word32 CorrQ11[AR_ORDER+1];
    243   WebRtc_Word32 sum, tmpGain;
    244   WebRtc_Word32 summQ16[FRAMESAMPLES/8];
    245   WebRtc_Word32 diffQ16[FRAMESAMPLES/8];
    246 
    247   const WebRtc_Word16 *CS_ptrQ9;
    248   int k, n, i;
    249   WebRtc_Word16 round, shftVal = 0, sh;
    250   WebRtc_Word32 res, in_sqrt, newRes;
    251 
    252   sum = 0;
    253   for (n = 0; n < AR_ORDER+1; n++)
    254     sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]);    /* Q24 */
    255   sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16);    /* result in Q8 */
    256   CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
    257 
    258   /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
    259   if(gainQ10>400000){
    260     tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
    261     round = 32;
    262     shftVal = 6;
    263   } else {
    264     tmpGain = gainQ10;
    265     round = 256;
    266     shftVal = 9;
    267   }
    268 
    269   for (k = 1; k < AR_ORDER+1; k++) {
    270     sum = 16384;
    271     for (n = k; n < AR_ORDER+1; n++)
    272       sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]);  /* Q24 */
    273     sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
    274     CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
    275   }
    276   sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
    277   for (n = 0; n < FRAMESAMPLES/8; n++)
    278     summQ16[n] = sum;
    279 
    280   for (k = 1; k < (AR_ORDER); k += 2) {
    281     for (n = 0; n < FRAMESAMPLES/8; n++)
    282       summQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(CorrQ11[k+1],WebRtcIsacfix_kCos[k][n]) + 2, 2);
    283   }
    284 
    285   CS_ptrQ9 = WebRtcIsacfix_kCos[0];
    286 
    287   /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */
    288   sh=WebRtcSpl_NormW32(CorrQ11[1]);
    289   if (CorrQ11[1]==0) /* Use next correlation */
    290     sh=WebRtcSpl_NormW32(CorrQ11[2]);
    291 
    292   if (sh<9)
    293     shftVal = 9 - sh;
    294   else
    295     shftVal = 0;
    296 
    297   for (n = 0; n < FRAMESAMPLES/8; n++)
    298     diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
    299   for (k = 2; k < AR_ORDER; k += 2) {
    300     CS_ptrQ9 = WebRtcIsacfix_kCos[k];
    301     for (n = 0; n < FRAMESAMPLES/8; n++)
    302       diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
    303   }
    304 
    305   in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal);
    306 
    307   /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB)  */
    308   res = WEBRTC_SPL_LSHIFT_W32(1, WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(in_sqrt), 1));
    309 
    310   for (k = 0; k < FRAMESAMPLES/8; k++)
    311   {
    312     in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
    313     i = 10;
    314 
    315     /* make in_sqrt positive to prohibit sqrt of negative values */
    316     if(in_sqrt<0)
    317       in_sqrt=-in_sqrt;
    318 
    319     newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
    320     do
    321     {
    322       res = newRes;
    323       newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
    324     } while (newRes != res && i-- > 0);
    325 
    326     CurveQ8[k] = (WebRtc_Word16)newRes;
    327   }
    328   for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) {
    329 
    330     in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal);
    331     i = 10;
    332 
    333     /* make in_sqrt positive to prohibit sqrt of negative values */
    334     if(in_sqrt<0)
    335       in_sqrt=-in_sqrt;
    336 
    337     newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
    338     do
    339     {
    340       res = newRes;
    341       newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
    342     } while (newRes != res && i-- > 0);
    343 
    344     CurveQ8[k] = (WebRtc_Word16)newRes;
    345   }
    346 
    347 }
    348 
    349 
    350 
    351 /* generate array of dither samples in Q7 */
    352 static void GenerateDitherQ7(WebRtc_Word16 *bufQ7,
    353                              WebRtc_UWord32 seed,
    354                              WebRtc_Word16 length,
    355                              WebRtc_Word16 AvgPitchGain_Q12)
    356 {
    357   int   k;
    358   WebRtc_Word16 dither1_Q7, dither2_Q7, dither_gain_Q14, shft;
    359 
    360   if (AvgPitchGain_Q12 < 614)  /* this threshold should be equal to that in decode_spec() */
    361   {
    362     for (k = 0; k < length-2; k += 3)
    363     {
    364       /* new random unsigned WebRtc_Word32 */
    365       seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
    366 
    367       /* fixed-point dither sample between -64 and 64 (Q7) */
    368       dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25); // * 128/4294967295
    369 
    370       /* new random unsigned WebRtc_Word32 */
    371       seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
    372 
    373       /* fixed-point dither sample between -64 and 64 */
    374       dither2_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25);
    375 
    376       shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15);
    377       if (shft < 5)
    378       {
    379         bufQ7[k]   = dither1_Q7;
    380         bufQ7[k+1] = dither2_Q7;
    381         bufQ7[k+2] = 0;
    382       }
    383       else if (shft < 10)
    384       {
    385         bufQ7[k]   = dither1_Q7;
    386         bufQ7[k+1] = 0;
    387         bufQ7[k+2] = dither2_Q7;
    388       }
    389       else
    390       {
    391         bufQ7[k]   = 0;
    392         bufQ7[k+1] = dither1_Q7;
    393         bufQ7[k+2] = dither2_Q7;
    394       }
    395     }
    396   }
    397   else
    398   {
    399     dither_gain_Q14 = (WebRtc_Word16)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12));
    400 
    401     /* dither on half of the coefficients */
    402     for (k = 0; k < length-1; k += 2)
    403     {
    404       /* new random unsigned WebRtc_Word32 */
    405       seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
    406 
    407       /* fixed-point dither sample between -64 and 64 */
    408       dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25);
    409 
    410       /* dither sample is placed in either even or odd index */
    411       shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1);     /* either 0 or 1 */
    412 
    413       bufQ7[k + shft] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14);
    414       bufQ7[k + 1 - shft] = 0;
    415     }
    416   }
    417 }
    418 
    419 
    420 
    421 
    422 /*
    423  * function to decode the complex spectrum from the bitstream
    424  * returns the total number of bytes in the stream
    425  */
    426 WebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata,
    427                                        WebRtc_Word16 *frQ7,
    428                                        WebRtc_Word16 *fiQ7,
    429                                        WebRtc_Word16 AvgPitchGain_Q12)
    430 {
    431   WebRtc_Word16  data[FRAMESAMPLES];
    432   WebRtc_Word32  invARSpec2_Q16[FRAMESAMPLES/4];
    433   WebRtc_Word16  ARCoefQ12[AR_ORDER+1];
    434   WebRtc_Word16  RCQ15[AR_ORDER];
    435   WebRtc_Word16  gainQ10;
    436   WebRtc_Word32  gain2_Q10;
    437   WebRtc_Word16  len;
    438   int          k;
    439 
    440   /* create dither signal */
    441   GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */
    442 
    443   /* decode model parameters */
    444   if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0)
    445     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
    446 
    447 
    448   WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
    449 
    450   if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0)
    451     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
    452 
    453   /* compute inverse AR power spectrum */
    454   CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
    455 
    456   /* arithmetic decoding of spectrum */
    457   /* 'data' input and output. Input = Dither */
    458   len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (WebRtc_Word16)FRAMESAMPLES);
    459 
    460   if (len<1)
    461     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
    462 
    463   /* subtract dither and scale down spectral samples with low SNR */
    464   if (AvgPitchGain_Q12 <= 614)
    465   {
    466     for (k = 0; k < FRAMESAMPLES; k += 4)
    467     {
    468       gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)30, 10),
    469                                               (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2195456, 16));
    470       *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
    471       *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
    472       *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
    473       *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
    474     }
    475   }
    476   else
    477   {
    478     for (k = 0; k < FRAMESAMPLES; k += 4)
    479     {
    480       gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)36, 10),
    481                                               (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2654208, 16));
    482       *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
    483       *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
    484       *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
    485       *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
    486     }
    487   }
    488 
    489   return len;
    490 }
    491 
    492 
    493 int WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr,
    494                              const WebRtc_Word16 *fi,
    495                              Bitstr_enc *streamdata,
    496                              WebRtc_Word16 AvgPitchGain_Q12)
    497 {
    498   WebRtc_Word16  dataQ7[FRAMESAMPLES];
    499   WebRtc_Word32  PSpec[FRAMESAMPLES/4];
    500   WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES/4];
    501   WebRtc_Word32  CorrQ7[AR_ORDER+1];
    502   WebRtc_Word32  CorrQ7_norm[AR_ORDER+1];
    503   WebRtc_Word16  RCQ15[AR_ORDER];
    504   WebRtc_Word16  ARCoefQ12[AR_ORDER+1];
    505   WebRtc_Word32  gain2_Q10;
    506   WebRtc_Word16  val;
    507   WebRtc_Word32  nrg;
    508   WebRtc_UWord32 sum;
    509   WebRtc_Word16  lft_shft;
    510   WebRtc_Word16  status;
    511   int          k, n, j;
    512 
    513 
    514   /* create dither_float signal */
    515   GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12);
    516 
    517   /* add dither and quantize, and compute power spectrum */
    518   /* Vector dataQ7 contains Dither in Q7 */
    519   for (k = 0; k < FRAMESAMPLES; k += 4)
    520   {
    521     val = ((*fr++ + dataQ7[k]   + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */
    522     dataQ7[k] = val;            /* New value in Data */
    523     sum = WEBRTC_SPL_UMUL(val, val);
    524 
    525     val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */
    526     dataQ7[k+1] = val;            /* New value in Data */
    527     sum += WEBRTC_SPL_UMUL(val, val);
    528 
    529     val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */
    530     dataQ7[k+2] = val;            /* New value in Data */
    531     sum += WEBRTC_SPL_UMUL(val, val);
    532 
    533     val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */
    534     dataQ7[k+3] = val;            /* New value in Data */
    535     sum += WEBRTC_SPL_UMUL(val, val);
    536 
    537     PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2);
    538   }
    539 
    540   /* compute correlation from power spectrum */
    541   CalcCorrelation(PSpec, CorrQ7);
    542 
    543 
    544   /* find AR coefficients */
    545   /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */
    546   lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
    547 
    548   if (lft_shft > 0) {
    549     for (k=0; k<AR_ORDER+1; k++)
    550       CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft);
    551   } else {
    552     for (k=0; k<AR_ORDER+1; k++)
    553       CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft);
    554   }
    555 
    556   /* find RC coefficients */
    557   WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15);
    558 
    559   /* quantize & code RC Coef */
    560   status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata);
    561   if (status < 0) {
    562     return status;
    563   }
    564 
    565   /* RC -> AR coefficients */
    566   WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
    567 
    568   /* compute ARCoef' * Corr * ARCoef in Q19 */
    569   nrg = 0;
    570   for (j = 0; j <= AR_ORDER; j++) {
    571     for (n = 0; n <= j; n++)
    572       nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3);
    573     for (n = j+1; n <= AR_ORDER; n++)
    574       nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3);
    575   }
    576 
    577   if (lft_shft > 0)
    578     nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft);
    579   else
    580     nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft);
    581 
    582   if(nrg>131072)
    583     gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg);  /* also shifts 31 bits to the left! */
    584   else
    585     gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2);
    586 
    587   /* quantize & code gain2_Q10 */
    588   if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata))
    589     return -1;
    590 
    591   /* compute inverse AR magnitude spectrum */
    592   CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8);
    593 
    594 
    595   /* arithmetic coding of spectrum */
    596   status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (WebRtc_Word16)FRAMESAMPLES);
    597   if ( status )
    598     return( status );
    599 
    600   return 0;
    601 }
    602 
    603 
    604 /* Matlab's LAR definition */
    605 static void Rc2LarFix(const WebRtc_Word16 *rcQ15, WebRtc_Word32 *larQ17, WebRtc_Word16 order) {
    606 
    607   /*
    608 
    609     This is a piece-wise implemenetation of a rc2lar-function (all values in the comment
    610     are Q15 values and  are based on [0 24956/32768 30000/32768 32500/32768], i.e.
    611     [0.76159667968750   0.91552734375000   0.99182128906250]
    612 
    613     x0  x1           a                 k              x0(again)         b
    614     ==================================================================================
    615     0.00 0.76:   0                  2.625997508581   0                  0
    616     0.76 0.91:   2.000012018559     7.284502668663   0.761596679688    -3.547841027073
    617     0.91 0.99:   3.121320351712    31.115835041229   0.915527343750   -25.366077452148
    618     0.99 1.00:   5.495270168700   686.663805654056   0.991821289063  -675.552510708011
    619 
    620     The implementation is y(x)= a + (x-x0)*k, but this can be simplified to
    621 
    622     y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k
    623 
    624     akx=[0                 2.625997508581   0
    625     2.000012018559     7.284502668663   0.761596679688
    626     3.121320351712    31.115835041229   0.915527343750
    627     5.495270168700   686.663805654056   0.991821289063];
    628 
    629     b = akx(:,1) - akx(:,3).*akx(:,2)
    630 
    631     [ 0.0
    632     -3.547841027073
    633     -25.366077452148
    634     -675.552510708011]
    635 
    636   */
    637 
    638   int k;
    639   WebRtc_Word16 rc;
    640   WebRtc_Word32 larAbsQ17;
    641 
    642   for (k = 0; k < order; k++) {
    643 
    644     rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15
    645 
    646     /* Calculate larAbsQ17 in Q17 from rc in Q15 */
    647 
    648     if (rc<24956) {  //0.7615966 in Q15
    649       // (Q15*Q13)>>11 = Q17
    650       larAbsQ17 = WEBRTC_SPL_MUL_16_16_RSFT(rc, 21512, 11);
    651     } else if (rc<30000) { //0.91552734375 in Q15
    652       // Q17 + (Q15*Q12)>>10 = Q17
    653       larAbsQ17 = -465024 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 29837, 10);
    654     } else if (rc<32500) { //0.99182128906250 in Q15
    655       // Q17 + (Q15*Q10)>>8 = Q17
    656       larAbsQ17 = -3324784 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 31863, 8);
    657     } else  {
    658       // Q17 + (Q15*Q5)>>3 = Q17
    659       larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3);
    660     }
    661 
    662     if (rcQ15[k]>0) {
    663       larQ17[k] = larAbsQ17;
    664     } else {
    665       larQ17[k] = -larAbsQ17;
    666     }
    667   }
    668 }
    669 
    670 
    671 static void Lar2RcFix(const WebRtc_Word32 *larQ17, WebRtc_Word16 *rcQ15,  WebRtc_Word16 order) {
    672 
    673   /*
    674     This is a piece-wise implemenetation of a lar2rc-function
    675     See comment in Rc2LarFix() about details.
    676   */
    677 
    678   int k;
    679   WebRtc_Word16 larAbsQ11;
    680   WebRtc_Word32 rc;
    681 
    682   for (k = 0; k < order; k++) {
    683 
    684     larAbsQ11 = (WebRtc_Word16) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11
    685 
    686     if (larAbsQ11<4097) { //2.000012018559 in Q11
    687       // Q11*Q16>>12 = Q15
    688       rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12);
    689     } else if (larAbsQ11<6393) { //3.121320351712 in Q11
    690       // (Q11*Q17 + Q13)>>13 = Q15
    691       rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13);
    692     } else if (larAbsQ11<11255) { //5.495270168700 in Q11
    693       // (Q11*Q19 + Q30)>>15 = Q15
    694       rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15);
    695     } else  {
    696       // (Q11*Q24>>16 + Q19)>>4 = Q15
    697       rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4);
    698     }
    699 
    700     if (larQ17[k]<=0) {
    701       rc = -rc;
    702     }
    703 
    704     rcQ15[k] = (WebRtc_Word16) rc;  // Q15
    705   }
    706 }
    707 
    708 static void Poly2LarFix(WebRtc_Word16 *lowbandQ15,
    709                         WebRtc_Word16 orderLo,
    710                         WebRtc_Word16 *hibandQ15,
    711                         WebRtc_Word16 orderHi,
    712                         WebRtc_Word16 Nsub,
    713                         WebRtc_Word32 *larsQ17) {
    714 
    715   int k, n;
    716   WebRtc_Word32 *outpQ17;
    717   WebRtc_Word16 orderTot;
    718   WebRtc_Word32 larQ17[MAX_ORDER];   // Size 7+6 is enough
    719 
    720   orderTot = (orderLo + orderHi);
    721   outpQ17 = larsQ17;
    722   for (k = 0; k < Nsub; k++) {
    723 
    724     Rc2LarFix(lowbandQ15, larQ17, orderLo);
    725 
    726     for (n = 0; n < orderLo; n++)
    727       outpQ17[n] = larQ17[n]; //Q17
    728 
    729     Rc2LarFix(hibandQ15, larQ17, orderHi);
    730 
    731     for (n = 0; n < orderHi; n++)
    732       outpQ17[n + orderLo] = larQ17[n]; //Q17;
    733 
    734     outpQ17 += orderTot;
    735     lowbandQ15 += orderLo;
    736     hibandQ15 += orderHi;
    737   }
    738 }
    739 
    740 
    741 static void Lar2polyFix(WebRtc_Word32 *larsQ17,
    742                         WebRtc_Word16 *lowbandQ15,
    743                         WebRtc_Word16 orderLo,
    744                         WebRtc_Word16 *hibandQ15,
    745                         WebRtc_Word16 orderHi,
    746                         WebRtc_Word16 Nsub) {
    747 
    748   int k, n;
    749   WebRtc_Word16 orderTot;
    750   WebRtc_Word16 *outplQ15, *outphQ15;
    751   WebRtc_Word32 *inpQ17;
    752   WebRtc_Word16 rcQ15[7+6];
    753 
    754   orderTot = (orderLo + orderHi);
    755   outplQ15 = lowbandQ15;
    756   outphQ15 = hibandQ15;
    757   inpQ17 = larsQ17;
    758   for (k = 0; k < Nsub; k++) {
    759 
    760     /* gains not handled here as in the FLP version */
    761 
    762     /* Low band */
    763     Lar2RcFix(&inpQ17[0], rcQ15, orderLo);
    764     for (n = 0; n < orderLo; n++)
    765       outplQ15[n] = rcQ15[n]; // Refl. coeffs
    766 
    767     /* High band */
    768     Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi);
    769     for (n = 0; n < orderHi; n++)
    770       outphQ15[n] = rcQ15[n]; // Refl. coeffs
    771 
    772     inpQ17 += orderTot;
    773     outplQ15 += orderLo;
    774     outphQ15 += orderHi;
    775   }
    776 }
    777 
    778 int WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
    779                             WebRtc_Word16 *LPCCoef_loQ15,
    780                             WebRtc_Word16 *LPCCoef_hiQ15,
    781                             Bitstr_dec *streamdata,
    782                             WebRtc_Word16 *outmodel) {
    783 
    784   WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES
    785   int err;
    786 
    787   err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel);
    788   if (err<0)  // error check
    789     return -ISAC_RANGE_ERROR_DECODE_LPC;
    790 
    791   Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES);
    792 
    793   return 0;
    794 }
    795 
    796 /* decode & dequantize LPC Coef */
    797 int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata,
    798                                 WebRtc_Word32 *LPCCoefQ17,
    799                                 WebRtc_Word32 *gain_lo_hiQ17,
    800                                 WebRtc_Word16 *outmodel)
    801 {
    802   int j, k, n;
    803   int err;
    804   WebRtc_Word16 pos, pos2, posg, poss, offsg, offss, offs2;
    805   WebRtc_Word16 gainpos;
    806   WebRtc_Word16 model;
    807   WebRtc_Word16 index_QQ[KLT_ORDER_SHAPE];
    808   WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
    809   WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
    810   WebRtc_Word16 tmpcoeffs_sQ10[KLT_ORDER_SHAPE];
    811   WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE];
    812   WebRtc_Word32 tmpcoeffs2_sQ18[KLT_ORDER_SHAPE];
    813   WebRtc_Word32 sumQQ;
    814   WebRtc_Word16 sumQQ16;
    815   WebRtc_Word32 tmp32;
    816 
    817 
    818 
    819   /* entropy decoding of model number */
    820   err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1);
    821   if (err<0)  // error check
    822     return err;
    823 
    824   /* entropy decoding of quantization indices */
    825   err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE);
    826   if (err<0)  // error check
    827     return err;
    828   /* find quantization levels for coefficients */
    829   for (k=0; k<KLT_ORDER_SHAPE; k++) {
    830     tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]];
    831   }
    832 
    833   err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN);
    834   if (err<0)  // error check
    835     return err;
    836   /* find quantization levels for coefficients */
    837   for (k=0; k<KLT_ORDER_GAIN; k++) {
    838     tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]];
    839   }
    840 
    841 
    842   /* inverse KLT  */
    843 
    844   /* left transform */  // Transpose matrix!
    845   offsg = 0;
    846   offss = 0;
    847   posg = 0;
    848   poss = 0;
    849   for (j=0; j<SUBFRAMES; j++) {
    850     offs2 = 0;
    851     for (k=0; k<2; k++) {
    852       sumQQ = 0;
    853       pos = offsg;
    854       pos2 = offs2;
    855       for (n=0; n<2; n++) {
    856         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[model][pos2], tmpcoeffs_gQ17[pos]<<5)); // (Q15*Q17)>>(16-5) = Q21
    857         pos++;
    858         pos2++;
    859       }
    860       tmpcoeffs2_gQ21[posg] = sumQQ; //Q21
    861       posg++;
    862       offs2 += 2;
    863     }
    864     offs2 = 0;
    865 
    866     for (k=0; k<LPC_SHAPE_ORDER; k++) {
    867       sumQQ = 0;
    868       pos = offss;
    869       pos2 = offs2;
    870       for (n=0; n<LPC_SHAPE_ORDER; n++) {
    871         sumQQ += WEBRTC_SPL_MUL_16_16_RSFT(tmpcoeffs_sQ10[pos], WebRtcIsacfix_kT1ShapeQ15[model][pos2], 7); // (Q10*Q15)>>7 = Q18
    872         pos++;
    873         pos2++;
    874       }
    875       tmpcoeffs2_sQ18[poss] = sumQQ; //Q18
    876       poss++;
    877       offs2 += LPC_SHAPE_ORDER;
    878     }
    879     offsg += 2;
    880     offss += LPC_SHAPE_ORDER;
    881   }
    882 
    883   /* right transform */ // Transpose matrix
    884   offsg = 0;
    885   offss = 0;
    886   posg = 0;
    887   poss = 0;
    888   for (j=0; j<SUBFRAMES; j++) {
    889     posg = offsg;
    890     for (k=0; k<2; k++) {
    891       sumQQ = 0;
    892       pos = k;
    893       pos2 = j;
    894       for (n=0; n<SUBFRAMES; n++) {
    895         sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[model][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
    896         pos += 2;
    897         pos2 += SUBFRAMES;
    898 
    899       }
    900       tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
    901       posg++;
    902     }
    903     poss = offss;
    904     for (k=0; k<LPC_SHAPE_ORDER; k++) {
    905       sumQQ = 0;
    906       pos = k;
    907       pos2 = j;
    908       for (n=0; n<SUBFRAMES; n++) {
    909         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[model][pos2], tmpcoeffs2_sQ18[pos])); // (Q15*Q18)>>16 = Q17
    910         pos += LPC_SHAPE_ORDER;
    911         pos2 += SUBFRAMES;
    912       }
    913       tmpcoeffs_sQ17[poss] = sumQQ;
    914       poss++;
    915     }
    916     offsg += 2;
    917     offss += LPC_SHAPE_ORDER;
    918   }
    919 
    920   /* scaling, mean addition, and gain restoration */
    921   gainpos = 0;
    922   posg = 0;poss = 0;pos=0;
    923   for (k=0; k<SUBFRAMES; k++) {
    924 
    925     /* log gains */
    926     sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
    927     sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
    928     sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
    929     gain_lo_hiQ17[gainpos] = sumQQ; //Q17
    930     gainpos++;
    931     posg++;
    932 
    933     sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
    934     sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
    935     sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
    936     gain_lo_hiQ17[gainpos] = sumQQ; //Q17
    937     gainpos++;
    938     posg++;
    939 
    940     /* lo band LAR coeffs */
    941     for (n=0; n<ORDERLO; n++, pos++, poss++) {
    942       tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16
    943       tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17
    944       LPCCoefQ17[pos] = tmp32;
    945     }
    946 
    947     /* hi band LAR coeffs */
    948     for (n=0; n<ORDERHI; n++, pos++, poss++) {
    949       tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13
    950       tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17
    951       LPCCoefQ17[pos] = tmp32;
    952     }
    953   }
    954 
    955 
    956   *outmodel=model;
    957 
    958   return 0;
    959 }
    960 
    961 /* estimate codel length of LPC Coef */
    962 static int EstCodeLpcCoef(WebRtc_Word32 *LPCCoefQ17,
    963                           WebRtc_Word32 *gain_lo_hiQ17,
    964                           WebRtc_Word16 *model,
    965                           WebRtc_Word32 *sizeQ11,
    966                           Bitstr_enc *streamdata,
    967                           ISAC_SaveEncData_t* encData,
    968                           transcode_obj *transcodingParam) {
    969   int j, k, n;
    970   WebRtc_Word16 posQQ, pos2QQ, gainpos;
    971   WebRtc_Word16  pos, pos2, poss, posg, offsg, offss, offs2;
    972   WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN], index_sQQ[KLT_ORDER_SHAPE];
    973   WebRtc_Word16 index_ovr_gQQ[KLT_ORDER_GAIN], index_ovr_sQQ[KLT_ORDER_SHAPE];
    974   WebRtc_Word32 BitsQQ;
    975 
    976   WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN];
    977   WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
    978   WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE];
    979   WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
    980   WebRtc_Word32 tmpcoeffs2_sQ17[KLT_ORDER_SHAPE];
    981   WebRtc_Word32 sumQQ;
    982   WebRtc_Word32 tmp32;
    983   WebRtc_Word16 sumQQ16;
    984   int status = 0;
    985 
    986   /* write LAR coefficients to statistics file */
    987   /* Save data for creation of multiple bitstreams (and transcoding) */
    988   if (encData != NULL) {
    989     for (k=0; k<KLT_ORDER_GAIN; k++) {
    990       encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k];
    991     }
    992   }
    993 
    994   /* log gains, mean removal and scaling */
    995   posg = 0;poss = 0;pos=0; gainpos=0;
    996 
    997   for (k=0; k<SUBFRAMES; k++) {
    998     /* log gains */
    999 
   1000     /* The input argument X to logN(X) is 2^17 times higher than the
   1001        input floating point argument Y to log(Y), since the X value
   1002        is a Q17 value. This can be compensated for after the call, by
   1003        subraction a value Z for each Q-step. One Q-step means that
   1004        X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
   1005        177.445678 should be subtracted (since logN() returns a Q8 value).
   1006        For a X value in Q17, the value 177.445678*17 = 3017 should be
   1007        subtracted */
   1008     tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
   1009     tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
   1010     posg++; gainpos++;
   1011 
   1012     tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
   1013     tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
   1014     posg++; gainpos++;
   1015 
   1016     /* lo band LAR coeffs */
   1017     for (n=0; n<ORDERLO; n++, poss++, pos++) {
   1018       tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17
   1019       tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32
   1020       tmpcoeffs_sQ17[poss] = tmp32; //Q17
   1021     }
   1022 
   1023     /* hi band LAR coeffs */
   1024     for (n=0; n<ORDERHI; n++, poss++, pos++) {
   1025       tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17
   1026       tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32
   1027       tmpcoeffs_sQ17[poss] = tmp32; //Q17
   1028     }
   1029 
   1030   }
   1031 
   1032 
   1033   /* KLT  */
   1034 
   1035   /* left transform */
   1036   offsg = 0;
   1037   offss = 0;
   1038   for (j=0; j<SUBFRAMES; j++) {
   1039     posg = offsg;
   1040     for (k=0; k<2; k++) {
   1041       sumQQ = 0;
   1042       pos = offsg;
   1043       pos2 = k;
   1044       for (n=0; n<2; n++) {
   1045         sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15
   1046         pos++;
   1047         pos2 += 2;
   1048       }
   1049       tmpcoeffs2_gQ21[posg] = sumQQ;
   1050       posg++;
   1051     }
   1052     poss = offss;
   1053     for (k=0; k<LPC_SHAPE_ORDER; k++) {
   1054       sumQQ = 0;
   1055       pos = offss;
   1056       pos2 = k;
   1057       for (n=0; n<LPC_SHAPE_ORDER; n++) {
   1058         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1ShapeQ15[0][pos2], tmpcoeffs_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
   1059         pos++;
   1060         pos2 += LPC_SHAPE_ORDER;
   1061       }
   1062       tmpcoeffs2_sQ17[poss] = sumQQ; //Q17
   1063       poss++;
   1064     }
   1065     offsg += 2;
   1066     offss += LPC_SHAPE_ORDER;
   1067   }
   1068 
   1069   /* right transform */
   1070   offsg = 0;
   1071   offss = 0;
   1072   offs2 = 0;
   1073   for (j=0; j<SUBFRAMES; j++) {
   1074     posg = offsg;
   1075     for (k=0; k<2; k++) {
   1076       sumQQ = 0;
   1077       pos = k;
   1078       pos2 = offs2;
   1079       for (n=0; n<SUBFRAMES; n++) {
   1080         sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
   1081         pos += 2;
   1082         pos2++;
   1083       }
   1084       tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
   1085       posg++;
   1086     }
   1087     poss = offss;
   1088     for (k=0; k<LPC_SHAPE_ORDER; k++) {
   1089       sumQQ = 0;
   1090       pos = k;
   1091       pos2 = offs2;
   1092       for (n=0; n<SUBFRAMES; n++) {
   1093         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[0][pos2], tmpcoeffs2_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
   1094         pos += LPC_SHAPE_ORDER;
   1095         pos2++;
   1096       }
   1097       tmpcoeffs_sQ17[poss] = sumQQ;
   1098       poss++;
   1099     }
   1100     offs2 += SUBFRAMES;
   1101     offsg += 2;
   1102     offss += LPC_SHAPE_ORDER;
   1103   }
   1104 
   1105   /* quantize coefficients */
   1106 
   1107   BitsQQ = 0;
   1108   for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
   1109   {
   1110     posQQ = WebRtcIsacfix_kSelIndGain[k];
   1111     pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
   1112 
   1113     index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
   1114     if (index_gQQ[k] < 0) {
   1115       index_gQQ[k] = 0;
   1116     }
   1117     else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
   1118       index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
   1119     }
   1120     index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k];
   1121     posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k];
   1122 
   1123     /* Save data for creation of multiple bitstreams */
   1124     if (encData != NULL) {
   1125       encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k];
   1126     }
   1127 
   1128     /* determine number of bits */
   1129     sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11
   1130     BitsQQ += sumQQ;
   1131   }
   1132 
   1133   for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok?
   1134   {
   1135     index_sQQ[k] = (WebRtc_Word16)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok?
   1136 
   1137     if (index_sQQ[k] < 0)
   1138       index_sQQ[k] = 0;
   1139     else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k])
   1140       index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k];
   1141     index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k];
   1142 
   1143     posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k];
   1144     sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11
   1145     BitsQQ += sumQQ;
   1146   }
   1147 
   1148 
   1149 
   1150   *model = 0;
   1151   *sizeQ11=BitsQQ;
   1152 
   1153   /* entropy coding of model number */
   1154   status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1);
   1155   if (status < 0) {
   1156     return status;
   1157   }
   1158 
   1159   /* entropy coding of quantization indices - shape only */
   1160   status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
   1161   if (status < 0) {
   1162     return status;
   1163   }
   1164 
   1165   /* Save data for creation of multiple bitstreams */
   1166   if (encData != NULL) {
   1167     for (k=0; k<KLT_ORDER_SHAPE; k++)
   1168     {
   1169       encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k];
   1170     }
   1171   }
   1172   /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */
   1173   transcodingParam->full         = streamdata->full;
   1174   transcodingParam->stream_index = streamdata->stream_index;
   1175   transcodingParam->streamval    = streamdata->streamval;
   1176   transcodingParam->W_upper      = streamdata->W_upper;
   1177   transcodingParam->beforeLastWord     = streamdata->stream[streamdata->stream_index-1];
   1178   transcodingParam->lastWord     = streamdata->stream[streamdata->stream_index];
   1179 
   1180   /* entropy coding of index */
   1181   status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
   1182   if (status < 0) {
   1183     return status;
   1184   }
   1185 
   1186   /* find quantization levels for shape coefficients */
   1187   for (k=0; k<KLT_ORDER_SHAPE; k++) {
   1188     tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]);
   1189 
   1190   }
   1191   /* inverse KLT  */
   1192 
   1193   /* left transform */  // Transpose matrix!
   1194   offss = 0;
   1195   poss = 0;
   1196   for (j=0; j<SUBFRAMES; j++) {
   1197     offs2 = 0;
   1198     for (k=0; k<LPC_SHAPE_ORDER; k++) {
   1199       sumQQ = 0;
   1200       pos = offss;
   1201       pos2 = offs2;
   1202       for (n=0; n<LPC_SHAPE_ORDER; n++) {
   1203         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1ShapeQ15[0][pos2], tmpcoeffs_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
   1204         pos++;
   1205         pos2++;
   1206       }
   1207       tmpcoeffs2_sQ17[poss] = sumQQ;
   1208 
   1209       poss++;
   1210       offs2 += LPC_SHAPE_ORDER;
   1211     }
   1212     offss += LPC_SHAPE_ORDER;
   1213   }
   1214 
   1215 
   1216   /* right transform */ // Transpose matrix
   1217   offss = 0;
   1218   poss = 0;
   1219   for (j=0; j<SUBFRAMES; j++) {
   1220     poss = offss;
   1221     for (k=0; k<LPC_SHAPE_ORDER; k++) {
   1222       sumQQ = 0;
   1223       pos = k;
   1224       pos2 = j;
   1225       for (n=0; n<SUBFRAMES; n++) {
   1226         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[0][pos2], tmpcoeffs2_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
   1227         pos += LPC_SHAPE_ORDER;
   1228         pos2 += SUBFRAMES;
   1229       }
   1230       tmpcoeffs_sQ17[poss] = sumQQ;
   1231       poss++;
   1232     }
   1233     offss += LPC_SHAPE_ORDER;
   1234   }
   1235 
   1236   /* scaling, mean addition, and gain restoration */
   1237   poss = 0;pos=0;
   1238   for (k=0; k<SUBFRAMES; k++) {
   1239 
   1240     /* lo band LAR coeffs */
   1241     for (n=0; n<ORDERLO; n++, pos++, poss++) {
   1242       tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16
   1243       tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17
   1244       LPCCoefQ17[pos] = tmp32;
   1245     }
   1246 
   1247     /* hi band LAR coeffs */
   1248     for (n=0; n<ORDERHI; n++, pos++, poss++) {
   1249       tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13
   1250       tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17
   1251       LPCCoefQ17[pos] = tmp32;
   1252     }
   1253 
   1254   }
   1255 
   1256   //to update tmpcoeffs_gQ17 to the proper state
   1257   for (k=0; k<KLT_ORDER_GAIN; k++) {
   1258     tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]];
   1259   }
   1260 
   1261 
   1262 
   1263   /* find quantization levels for coefficients */
   1264 
   1265   /* left transform */
   1266   offsg = 0;
   1267   posg = 0;
   1268   for (j=0; j<SUBFRAMES; j++) {
   1269     offs2 = 0;
   1270     for (k=0; k<2; k++) {
   1271       sumQQ = 0;
   1272       pos = offsg;
   1273       pos2 = offs2;
   1274       for (n=0; n<2; n++) {
   1275         sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][pos2], tmpcoeffs_gQ17[pos])<<1); // (Q15*Q17)>>(16-1) = Q17
   1276         pos++;
   1277         pos2++;
   1278       }
   1279       tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); //Q17<<4 = Q21
   1280       posg++;
   1281       offs2 += 2;
   1282     }
   1283     offsg += 2;
   1284   }
   1285 
   1286   /* right transform */ // Transpose matrix
   1287   offsg = 0;
   1288   posg = 0;
   1289   for (j=0; j<SUBFRAMES; j++) {
   1290     posg = offsg;
   1291     for (k=0; k<2; k++) {
   1292       sumQQ = 0;
   1293       pos = k;
   1294       pos2 = j;
   1295       for (n=0; n<SUBFRAMES; n++) {
   1296         sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
   1297         pos += 2;
   1298         pos2 += SUBFRAMES;
   1299       }
   1300       tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
   1301       posg++;
   1302     }
   1303     offsg += 2;
   1304   }
   1305 
   1306   /* scaling, mean addition, and gain restoration */
   1307   posg = 0;
   1308   gainpos = 0;
   1309   for (k=0; k<2*SUBFRAMES; k++) {
   1310 
   1311     sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
   1312     sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg];
   1313     sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
   1314     gain_lo_hiQ17[gainpos] = sumQQ; //Q17
   1315 
   1316     gainpos++;
   1317     pos++;posg++;
   1318   }
   1319 
   1320   return 0;
   1321 }
   1322 
   1323 int WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17,
   1324                                  Bitstr_enc *streamdata,
   1325                                  ISAC_SaveEncData_t* encData) {
   1326   int j, k, n;
   1327   WebRtc_Word16 posQQ, pos2QQ, gainpos;
   1328   WebRtc_Word16  pos, pos2, posg, offsg, offs2;
   1329   WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN];
   1330 
   1331   WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN];
   1332   WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
   1333   WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
   1334   WebRtc_Word32 sumQQ;
   1335   int status = 0;
   1336 
   1337   /* write LAR coefficients to statistics file */
   1338   /* Save data for creation of multiple bitstreams (and transcoding) */
   1339   if (encData != NULL) {
   1340     for (k=0; k<KLT_ORDER_GAIN; k++) {
   1341       encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k];
   1342     }
   1343   }
   1344 
   1345   /* log gains, mean removal and scaling */
   1346   posg = 0; pos = 0; gainpos = 0;
   1347 
   1348   for (k=0; k<SUBFRAMES; k++) {
   1349     /* log gains */
   1350 
   1351     /* The input argument X to logN(X) is 2^17 times higher than the
   1352        input floating point argument Y to log(Y), since the X value
   1353        is a Q17 value. This can be compensated for after the call, by
   1354        subraction a value Z for each Q-step. One Q-step means that
   1355        X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
   1356        177.445678 should be subtracted (since logN() returns a Q8 value).
   1357        For a X value in Q17, the value 177.445678*17 = 3017 should be
   1358        subtracted */
   1359     tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
   1360     tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
   1361     posg++; gainpos++;
   1362 
   1363     tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
   1364     tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
   1365     posg++; gainpos++;
   1366   }
   1367 
   1368 
   1369   /* KLT  */
   1370 
   1371   /* left transform */
   1372   offsg = 0;
   1373   for (j=0; j<SUBFRAMES; j++) {
   1374     posg = offsg;
   1375     for (k=0; k<2; k++) {
   1376       sumQQ = 0;
   1377       pos = offsg;
   1378       pos2 = k;
   1379       for (n=0; n<2; n++) {
   1380         sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15
   1381         pos++;
   1382         pos2 += 2;
   1383       }
   1384       tmpcoeffs2_gQ21[posg] = sumQQ;
   1385       posg++;
   1386     }
   1387     offsg += 2;
   1388   }
   1389 
   1390   /* right transform */
   1391   offsg = 0;
   1392   offs2 = 0;
   1393   for (j=0; j<SUBFRAMES; j++) {
   1394     posg = offsg;
   1395     for (k=0; k<2; k++) {
   1396       sumQQ = 0;
   1397       pos = k;
   1398       pos2 = offs2;
   1399       for (n=0; n<SUBFRAMES; n++) {
   1400         sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
   1401         pos += 2;
   1402         pos2++;
   1403       }
   1404       tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
   1405       posg++;
   1406     }
   1407     offsg += 2;
   1408     offs2 += SUBFRAMES;
   1409   }
   1410 
   1411   /* quantize coefficients */
   1412 
   1413   for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
   1414   {
   1415     posQQ = WebRtcIsacfix_kSelIndGain[k];
   1416     pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
   1417 
   1418     index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
   1419     if (index_gQQ[k] < 0) {
   1420       index_gQQ[k] = 0;
   1421     }
   1422     else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
   1423       index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
   1424     }
   1425 
   1426     /* Save data for creation of multiple bitstreams */
   1427     if (encData != NULL) {
   1428       encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k];
   1429     }
   1430   }
   1431 
   1432   /* entropy coding of index */
   1433   status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
   1434   if (status < 0) {
   1435     return status;
   1436   }
   1437 
   1438   return 0;
   1439 }
   1440 
   1441 
   1442 int WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
   1443                             WebRtc_Word16 *LPCCoef_loQ15,
   1444                             WebRtc_Word16 *LPCCoef_hiQ15,
   1445                             WebRtc_Word16 *model,
   1446                             WebRtc_Word32 *sizeQ11,
   1447                             Bitstr_enc *streamdata,
   1448                             ISAC_SaveEncData_t* encData,
   1449                             transcode_obj *transcodeParam)
   1450 {
   1451   int status = 0;
   1452   WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES
   1453   // = (6+12)*6 == 108
   1454 
   1455   Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17);
   1456 
   1457   status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, streamdata, encData, transcodeParam);
   1458   if (status < 0) {
   1459     return (status);
   1460   }
   1461 
   1462   Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES);
   1463 
   1464   return 0;
   1465 }
   1466 
   1467 
   1468 /* decode & dequantize RC */
   1469 int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, WebRtc_Word16 *RCQ15)
   1470 {
   1471   int k, err;
   1472   WebRtc_Word16 index[AR_ORDER];
   1473 
   1474   /* entropy decoding of quantization indices */
   1475   err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER);
   1476   if (err<0)  // error check
   1477     return err;
   1478 
   1479   /* find quantization levels for reflection coefficients */
   1480   for (k=0; k<AR_ORDER; k++)
   1481   {
   1482     RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]);
   1483   }
   1484 
   1485   return 0;
   1486 }
   1487 
   1488 
   1489 
   1490 /* quantize & code RC */
   1491 int WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15, Bitstr_enc *streamdata)
   1492 {
   1493   int k;
   1494   WebRtc_Word16 index[AR_ORDER];
   1495   int status;
   1496 
   1497   /* quantize reflection coefficients (add noise feedback?) */
   1498   for (k=0; k<AR_ORDER; k++)
   1499   {
   1500     index[k] = WebRtcIsacfix_kRcInitInd[k];
   1501 
   1502     if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]])
   1503     {
   1504       while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1])
   1505         index[k]++;
   1506     }
   1507     else
   1508     {
   1509       while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ;
   1510     }
   1511 
   1512     RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]);
   1513   }
   1514 
   1515 
   1516   /* entropy coding of quantization indices */
   1517   status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER);
   1518 
   1519   /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
   1520   return status;
   1521 }
   1522 
   1523 
   1524 /* decode & dequantize squared Gain */
   1525 int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, WebRtc_Word32 *gainQ10)
   1526 {
   1527   int err;
   1528   WebRtc_Word16 index;
   1529 
   1530   /* entropy decoding of quantization index */
   1531   err = WebRtcIsacfix_DecHistOneStepMulti(
   1532       &index,
   1533       streamdata,
   1534       WebRtcIsacfix_kGainPtr,
   1535       WebRtcIsacfix_kGainInitInd,
   1536       1);
   1537   /* error check */
   1538   if (err<0) {
   1539     return err;
   1540   }
   1541 
   1542   /* find quantization level */
   1543   *gainQ10 = WebRtcIsacfix_kGain2Lev[index];
   1544 
   1545   return 0;
   1546 }
   1547 
   1548 
   1549 
   1550 /* quantize & code squared Gain */
   1551 int WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr_enc *streamdata)
   1552 {
   1553   WebRtc_Word16 index;
   1554   int status = 0;
   1555 
   1556   /* find quantization index */
   1557   index = WebRtcIsacfix_kGainInitInd[0];
   1558   if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index])
   1559   {
   1560     while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1])
   1561       index++;
   1562   }
   1563   else
   1564   {
   1565     while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ;
   1566   }
   1567 
   1568   /* dequantize */
   1569   *gainQ10 = WebRtcIsacfix_kGain2Lev[index];
   1570 
   1571   /* entropy coding of quantization index */
   1572   status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1);
   1573 
   1574   /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
   1575   return status;
   1576 }
   1577 
   1578 
   1579 /* code and decode Pitch Gains and Lags functions */
   1580 
   1581 /* decode & dequantize Pitch Gains */
   1582 int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, WebRtc_Word16 *PitchGains_Q12)
   1583 {
   1584   int err;
   1585   WebRtc_Word16 index_comb;
   1586   const WebRtc_UWord16 *pitch_gain_cdf_ptr[1];
   1587 
   1588   /* entropy decoding of quantization indices */
   1589   *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
   1590   err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1);
   1591   /* error check, Q_mean_Gain.. tables are of size 144 */
   1592   if ((err<0) || (index_comb<0) || (index_comb>144))
   1593     return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN;
   1594 
   1595   /* unquantize back to pitch gains by table look-up */
   1596   PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb];
   1597   PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb];
   1598   PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb];
   1599   PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb];
   1600 
   1601   return 0;
   1602 }
   1603 
   1604 
   1605 /* quantize & code Pitch Gains */
   1606 int WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData)
   1607 {
   1608   int k,j;
   1609   WebRtc_Word16 SQ15[PITCH_SUBFRAMES];
   1610   WebRtc_Word16 index[3];
   1611   WebRtc_Word16 index_comb;
   1612   const WebRtc_UWord16 *pitch_gain_cdf_ptr[1];
   1613   WebRtc_Word32 CQ17;
   1614   int status = 0;
   1615 
   1616 
   1617   /* get the approximate arcsine (almost linear)*/
   1618   for (k=0; k<PITCH_SUBFRAMES; k++)
   1619     SQ15[k] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[k],33,2); //Q15
   1620 
   1621 
   1622   /* find quantization index; only for the first three transform coefficients */
   1623   for (k=0; k<3; k++)
   1624   {
   1625     /*  transform */
   1626     CQ17=0;
   1627     for (j=0; j<PITCH_SUBFRAMES; j++) {
   1628       CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17
   1629     }
   1630 
   1631     index[k] = (WebRtc_Word16)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8)
   1632 
   1633     /* check that the index is not outside the boundaries of the table */
   1634     if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k];
   1635     else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k];
   1636     index[k] -= WebRtcIsacfix_kLowerlimiGain[k];
   1637   }
   1638 
   1639   /* calculate unique overall index */
   1640   index_comb = (WebRtc_Word16)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) +
   1641                                WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]);
   1642 
   1643   /* unquantize back to pitch gains by table look-up */
   1644   // (Y)
   1645   PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb];
   1646   PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb];
   1647   PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb];
   1648   PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb];
   1649 
   1650 
   1651   /* entropy coding of quantization pitch gains */
   1652   *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
   1653   status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1);
   1654   if (status < 0) {
   1655     return status;
   1656   }
   1657 
   1658   /* Save data for creation of multiple bitstreams */
   1659   if (encData != NULL) {
   1660     encData->pitchGain_index[encData->startIdx] = index_comb;
   1661   }
   1662 
   1663   return 0;
   1664 }
   1665 
   1666 
   1667 
   1668 /* Pitch LAG */
   1669 
   1670 
   1671 /* decode & dequantize Pitch Lags */
   1672 int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
   1673                                  WebRtc_Word16 *PitchGain_Q12,
   1674                                  WebRtc_Word16 *PitchLags_Q7)
   1675 {
   1676   int k, err;
   1677   WebRtc_Word16 index[PITCH_SUBFRAMES];
   1678   const WebRtc_Word16 *mean_val2Q10, *mean_val4Q10;
   1679 
   1680   const WebRtc_Word16 *lower_limit;
   1681   const WebRtc_UWord16 *init_index;
   1682   const WebRtc_UWord16 *cdf_size;
   1683   const WebRtc_UWord16 **cdf;
   1684 
   1685   WebRtc_Word32 meangainQ12;
   1686   WebRtc_Word32 CQ11, CQ10,tmp32a,tmp32b;
   1687   WebRtc_Word16 shft,tmp16a,tmp16c;
   1688 
   1689   meangainQ12=0;
   1690   for (k = 0; k < 4; k++)
   1691     meangainQ12 += PitchGain_Q12[k];
   1692 
   1693   meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2);  // Get average
   1694 
   1695   /* voicing classificiation */
   1696   if (meangainQ12 <= 819) {                 // mean_gain < 0.2
   1697     shft = -1;        // StepSize=2.0;
   1698     cdf = WebRtcIsacfix_kPitchLagPtrLo;
   1699     cdf_size = WebRtcIsacfix_kPitchLagSizeLo;
   1700     mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo;
   1701     mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo;
   1702     lower_limit = WebRtcIsacfix_kLowerLimitLo;
   1703     init_index = WebRtcIsacfix_kInitIndLo;
   1704   } else if (meangainQ12 <= 1638) {            // mean_gain < 0.4
   1705     shft = 0;        // StepSize=1.0;
   1706     cdf = WebRtcIsacfix_kPitchLagPtrMid;
   1707     cdf_size = WebRtcIsacfix_kPitchLagSizeMid;
   1708     mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid;
   1709     mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid;
   1710     lower_limit = WebRtcIsacfix_kLowerLimitMid;
   1711     init_index = WebRtcIsacfix_kInitIndMid;
   1712   } else {
   1713     shft = 1;        // StepSize=0.5;
   1714     cdf = WebRtcIsacfix_kPitchLagPtrHi;
   1715     cdf_size = WebRtcIsacfix_kPitchLagSizeHi;
   1716     mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi;
   1717     mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi;
   1718     lower_limit = WebRtcIsacfix_kLowerLimitHi;
   1719     init_index = WebRtcIsacfix_kInitIndHi;
   1720   }
   1721 
   1722   /* entropy decoding of quantization indices */
   1723   err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1);
   1724   if ((err<0) || (index[0]<0))  // error check
   1725     return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
   1726 
   1727   err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3);
   1728   if (err<0)  // error check
   1729     return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
   1730 
   1731 
   1732   /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */
   1733   CQ11 = ((WebRtc_Word32)index[0] + lower_limit[0]);  // Q0
   1734   CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
   1735   for (k=0; k<PITCH_SUBFRAMES; k++) {
   1736     tmp32a =  WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11);
   1737     tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);
   1738     PitchLags_Q7[k] = tmp16a;
   1739   }
   1740 
   1741   CQ10 = mean_val2Q10[index[1]];
   1742   for (k=0; k<PITCH_SUBFRAMES; k++) {
   1743     tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10);
   1744     tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
   1745     PitchLags_Q7[k] += tmp16c;
   1746   }
   1747 
   1748   CQ10 = mean_val4Q10[index[3]];
   1749   for (k=0; k<PITCH_SUBFRAMES; k++) {
   1750     tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10);
   1751     tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
   1752     PitchLags_Q7[k] += tmp16c;
   1753   }
   1754 
   1755   return 0;
   1756 }
   1757 
   1758 
   1759 
   1760 /* quantize & code Pitch Lags */
   1761 int WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagsQ7,WebRtc_Word16 *PitchGain_Q12,
   1762                                  Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData)
   1763 {
   1764   int k, j;
   1765   WebRtc_Word16 index[PITCH_SUBFRAMES];
   1766   WebRtc_Word32 meangainQ12, CQ17;
   1767   WebRtc_Word32 CQ11, CQ10,tmp32a;
   1768 
   1769   const WebRtc_Word16 *mean_val2Q10,*mean_val4Q10;
   1770   const WebRtc_Word16 *lower_limit, *upper_limit;
   1771   const WebRtc_UWord16 **cdf;
   1772   WebRtc_Word16 shft, tmp16a, tmp16b, tmp16c;
   1773   WebRtc_Word32 tmp32b;
   1774   int status = 0;
   1775 
   1776   /* compute mean pitch gain */
   1777   meangainQ12=0;
   1778   for (k = 0; k < 4; k++)
   1779     meangainQ12 += PitchGain_Q12[k];
   1780 
   1781   meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2);
   1782 
   1783   /* Save data for creation of multiple bitstreams */
   1784   if (encData != NULL) {
   1785     encData->meanGain[encData->startIdx] = meangainQ12;
   1786   }
   1787 
   1788   /* voicing classificiation */
   1789   if (meangainQ12 <= 819) {                 // mean_gain < 0.2
   1790     shft = -1;        // StepSize=2.0;
   1791     cdf = WebRtcIsacfix_kPitchLagPtrLo;
   1792     mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo;
   1793     mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo;
   1794     lower_limit = WebRtcIsacfix_kLowerLimitLo;
   1795     upper_limit = WebRtcIsacfix_kUpperLimitLo;
   1796   } else if (meangainQ12 <= 1638) {            // mean_gain < 0.4
   1797     shft = 0;        // StepSize=1.0;
   1798     cdf = WebRtcIsacfix_kPitchLagPtrMid;
   1799     mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid;
   1800     mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid;
   1801     lower_limit = WebRtcIsacfix_kLowerLimitMid;
   1802     upper_limit = WebRtcIsacfix_kUpperLimitMid;
   1803   } else {
   1804     shft = 1;        // StepSize=0.5;
   1805     cdf = WebRtcIsacfix_kPitchLagPtrHi;
   1806     mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi;
   1807     mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi;
   1808     lower_limit = WebRtcIsacfix_kLowerLimitHi;
   1809     upper_limit = WebRtcIsacfix_kUpperLimitHi;
   1810   }
   1811 
   1812   /* find quantization index */
   1813   for (k=0; k<4; k++)
   1814   {
   1815     /*  transform */
   1816     CQ17=0;
   1817     for (j=0; j<PITCH_SUBFRAMES; j++)
   1818       CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17
   1819 
   1820     CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize
   1821 
   1822     /* quantize */
   1823     tmp16b = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 );
   1824     index[k] =  tmp16b;
   1825 
   1826     /* check that the index is not outside the boundaries of the table */
   1827     if (index[k] < lower_limit[k]) index[k] = lower_limit[k];
   1828     else if (index[k] > upper_limit[k]) index[k] = upper_limit[k];
   1829     index[k] -= lower_limit[k];
   1830 
   1831     /* Save data for creation of multiple bitstreams */
   1832     if(encData != NULL) {
   1833       encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k];
   1834     }
   1835   }
   1836 
   1837   /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */
   1838   CQ11 = (index[0] + lower_limit[0]);  // Q0
   1839   CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
   1840 
   1841   for (k=0; k<PITCH_SUBFRAMES; k++) {
   1842     tmp32a =  WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12
   1843     tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7
   1844     PitchLagsQ7[k] = tmp16a;
   1845   }
   1846 
   1847   CQ10 = mean_val2Q10[index[1]];
   1848   for (k=0; k<PITCH_SUBFRAMES; k++) {
   1849     tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10);
   1850     tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
   1851     PitchLagsQ7[k] += tmp16c;
   1852   }
   1853 
   1854   CQ10 = mean_val4Q10[index[3]];
   1855   for (k=0; k<PITCH_SUBFRAMES; k++) {
   1856     tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10);
   1857     tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
   1858     PitchLagsQ7[k] += tmp16c;
   1859   }
   1860 
   1861   /* entropy coding of quantization pitch lags */
   1862   status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES);
   1863 
   1864   /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
   1865   return status;
   1866 }
   1867 
   1868 
   1869 
   1870 /* Routines for inband signaling of bandwitdh estimation */
   1871 /* Histograms based on uniform distribution of indices */
   1872 /* Move global variables later! */
   1873 
   1874 
   1875 /* cdf array for frame length indicator */
   1876 const WebRtc_UWord16 kFrameLenCdf[4] = {
   1877   0, 21845, 43690, 65535};
   1878 
   1879 /* pointer to cdf array for frame length indicator */
   1880 const WebRtc_UWord16 *kFrameLenCdfPtr[1] = {kFrameLenCdf};
   1881 
   1882 /* initial cdf index for decoder of frame length indicator */
   1883 const WebRtc_UWord16 kFrameLenInitIndex[1] = {1};
   1884 
   1885 
   1886 int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata,
   1887                                  WebRtc_Word16 *framesamples)
   1888 {
   1889 
   1890   int err;
   1891   WebRtc_Word16 frame_mode;
   1892 
   1893   err = 0;
   1894   /* entropy decoding of frame length [1:30ms,2:60ms] */
   1895   err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1);
   1896   if (err<0)  // error check
   1897     return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH;
   1898 
   1899   switch(frame_mode) {
   1900     case 1:
   1901       *framesamples = 480; /* 30ms */
   1902       break;
   1903     case 2:
   1904       *framesamples = 960; /* 60ms */
   1905       break;
   1906     default:
   1907       err = -ISAC_DISALLOWED_FRAME_MODE_DECODER;
   1908   }
   1909 
   1910   return err;
   1911 }
   1912 
   1913 
   1914 int WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framesamples, Bitstr_enc *streamdata) {
   1915 
   1916   int status;
   1917   WebRtc_Word16 frame_mode;
   1918 
   1919   status = 0;
   1920   frame_mode = 0;
   1921   /* entropy coding of frame length [1:480 samples,2:960 samples] */
   1922   switch(framesamples) {
   1923     case 480:
   1924       frame_mode = 1;
   1925       break;
   1926     case 960:
   1927       frame_mode = 2;
   1928       break;
   1929     default:
   1930       status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER;
   1931   }
   1932 
   1933   if (status < 0)
   1934     return status;
   1935 
   1936   status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1);
   1937 
   1938   return status;
   1939 }
   1940 
   1941 /* cdf array for estimated bandwidth */
   1942 const WebRtc_UWord16 kBwCdf[25] = {
   1943   0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037,
   1944   32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074,
   1945   62804, 65535};
   1946 
   1947 /* pointer to cdf array for estimated bandwidth */
   1948 const WebRtc_UWord16 *kBwCdfPtr[1] = {kBwCdf};
   1949 
   1950 /* initial cdf index for decoder of estimated bandwidth*/
   1951 const WebRtc_UWord16 kBwInitIndex[1] = {7};
   1952 
   1953 
   1954 int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, WebRtc_Word16 *BWno) {
   1955 
   1956   int err;
   1957   WebRtc_Word16 BWno32;
   1958 
   1959   /* entropy decoding of sender's BW estimation [0..23] */
   1960   err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1);
   1961   if (err<0)  // error check
   1962     return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH;
   1963   *BWno = (WebRtc_Word16)BWno32;
   1964   return err;
   1965 
   1966 }
   1967 
   1968 
   1969 int WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno, Bitstr_enc *streamdata)
   1970 {
   1971   int status = 0;
   1972   /* entropy encoding of receiver's BW estimation [0..23] */
   1973   status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1);
   1974 
   1975   return status;
   1976 }
   1977 
   1978 /* estimate codel length of LPC Coef */
   1979 void WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *gain_lo_hiQ17,
   1980                                     WebRtc_Word16 *index_gQQ) {
   1981   int j, k, n;
   1982   WebRtc_Word16 posQQ, pos2QQ;
   1983   WebRtc_Word16  pos, pos2, posg, offsg, offs2, gainpos;
   1984   WebRtc_Word32 tmpcoeffs_gQ6[KLT_ORDER_GAIN];
   1985   WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
   1986   WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
   1987   WebRtc_Word32 sumQQ;
   1988 
   1989 
   1990   /* log gains, mean removal and scaling */
   1991   posg = 0;pos=0; gainpos=0;
   1992 
   1993   for (k=0; k<SUBFRAMES; k++) {
   1994     /* log gains */
   1995 
   1996     /* The input argument X to logN(X) is 2^17 times higher than the
   1997        input floating point argument Y to log(Y), since the X value
   1998        is a Q17 value. This can be compensated for after the call, by
   1999        subraction a value Z for each Q-step. One Q-step means that
   2000        X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
   2001        177.445678 should be subtracted (since logN() returns a Q8 value).
   2002        For a X value in Q17, the value 177.445678*17 = 3017 should be
   2003        subtracted */
   2004     tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
   2005     tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
   2006     posg++; gainpos++;
   2007 
   2008     tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
   2009     tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
   2010     posg++; gainpos++;
   2011 
   2012   }
   2013 
   2014 
   2015   /* KLT  */
   2016 
   2017   /* left transform */
   2018   offsg = 0;
   2019   for (j=0; j<SUBFRAMES; j++) {
   2020     posg = offsg;
   2021     for (k=0; k<2; k++) {
   2022       sumQQ = 0;
   2023       pos = offsg;
   2024       pos2 = k;
   2025       for (n=0; n<2; n++) {
   2026         sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15
   2027         pos++;
   2028         pos2 += 2;
   2029       }
   2030       tmpcoeffs2_gQ21[posg] = sumQQ;
   2031       posg++;
   2032     }
   2033 
   2034     offsg += 2;
   2035   }
   2036 
   2037   /* right transform */
   2038   offsg = 0;
   2039   offs2 = 0;
   2040   for (j=0; j<SUBFRAMES; j++) {
   2041     posg = offsg;
   2042     for (k=0; k<2; k++) {
   2043       sumQQ = 0;
   2044       pos = k;
   2045       pos2 = offs2;
   2046       for (n=0; n<SUBFRAMES; n++) {
   2047         sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
   2048         pos += 2;
   2049         pos2++;
   2050       }
   2051       tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
   2052       posg++;
   2053     }
   2054     offsg += 2;
   2055     offs2 += SUBFRAMES;
   2056   }
   2057 
   2058   /* quantize coefficients */
   2059   for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
   2060   {
   2061     posQQ = WebRtcIsacfix_kSelIndGain[k];
   2062     pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
   2063 
   2064     index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
   2065     if (index_gQQ[k] < 0) {
   2066       index_gQQ[k] = 0;
   2067     }
   2068     else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
   2069       index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
   2070     }
   2071   }
   2072 }
   2073