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