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