Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2012 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 header file defines all of the functions used to arithmetically
     15  * encode the iSAC bistream
     16  *
     17  */
     18 
     19 
     20 #include "entropy_coding.h"
     21 #include "settings.h"
     22 #include "arith_routines.h"
     23 #include "signal_processing_library.h"
     24 #include "spectrum_ar_model_tables.h"
     25 #include "lpc_tables.h"
     26 #include "pitch_gain_tables.h"
     27 #include "pitch_lag_tables.h"
     28 #include "encode_lpc_swb.h"
     29 #include "lpc_shape_swb12_tables.h"
     30 #include "lpc_shape_swb16_tables.h"
     31 #include "lpc_gain_swb_tables.h"
     32 #include "os_specific_inline.h"
     33 
     34 #include <math.h>
     35 #include <string.h>
     36 
     37 static const WebRtc_UWord16 kLpcVecPerSegmentUb12 = 5;
     38 static const WebRtc_UWord16 kLpcVecPerSegmentUb16 = 4;
     39 
     40 /* CDF array for encoder bandwidth (12 vs 16 kHz) indicator. */
     41 static const WebRtc_UWord16 kOneBitEqualProbCdf[3] = {
     42     0, 32768, 65535 };
     43 
     44 /* Pointer to cdf array for encoder bandwidth (12 vs 16 kHz) indicator. */
     45 static const WebRtc_UWord16* kOneBitEqualProbCdf_ptr[1] = {
     46     kOneBitEqualProbCdf };
     47 
     48 /*
     49  * Initial cdf index for decoder of encoded bandwidth
     50  * (12 vs 16 kHz) indicator.
     51  */
     52 static const WebRtc_UWord16 kOneBitEqualProbInitIndex[1] = { 1 };
     53 
     54 
     55 static const int kIsSWB12 = 1;
     56 
     57 /* compute correlation from power spectrum */
     58 static void FindCorrelation(WebRtc_Word32* PSpecQ12, WebRtc_Word32* CorrQ7) {
     59   WebRtc_Word32 summ[FRAMESAMPLES / 8];
     60   WebRtc_Word32 diff[FRAMESAMPLES / 8];
     61   const WebRtc_Word16* CS_ptrQ9;
     62   WebRtc_Word32 sum;
     63   int k, n;
     64 
     65   for (k = 0; k < FRAMESAMPLES / 8; k++) {
     66     summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5;
     67     diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5;
     68   }
     69 
     70   sum = 2;
     71   for (n = 0; n < FRAMESAMPLES / 8; n++) {
     72     sum += summ[n];
     73   }
     74   CorrQ7[0] = sum;
     75 
     76   for (k = 0; k < AR_ORDER; k += 2) {
     77     sum = 0;
     78     CS_ptrQ9 = WebRtcIsac_kCos[k];
     79     for (n = 0; n < FRAMESAMPLES / 8; n++)
     80       sum += (CS_ptrQ9[n] * diff[n] + 256) >> 9;
     81     CorrQ7[k + 1] = sum;
     82   }
     83 
     84   for (k = 1; k < AR_ORDER; k += 2) {
     85     sum = 0;
     86     CS_ptrQ9 = WebRtcIsac_kCos[k];
     87     for (n = 0; n < FRAMESAMPLES / 8; n++)
     88       sum += (CS_ptrQ9[n] * summ[n] + 256) >> 9;
     89     CorrQ7[k + 1] = sum;
     90   }
     91 }
     92 
     93 /* compute inverse AR power spectrum */
     94 /* Changed to the function used in iSAC FIX for compatibility reasons */
     95 static void FindInvArSpec(const WebRtc_Word16* ARCoefQ12,
     96                           const WebRtc_Word32 gainQ10,
     97                           WebRtc_Word32* CurveQ16) {
     98   WebRtc_Word32 CorrQ11[AR_ORDER + 1];
     99   WebRtc_Word32 sum, tmpGain;
    100   WebRtc_Word32 diffQ16[FRAMESAMPLES / 8];
    101   const WebRtc_Word16* CS_ptrQ9;
    102   int k, n;
    103   WebRtc_Word16 round, shftVal = 0, sh;
    104 
    105   sum = 0;
    106   for (n = 0; n < AR_ORDER + 1; n++) {
    107     sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]);   /* Q24 */
    108   }
    109   sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6),
    110                                              65) + 32768, 16); /* Q8 */
    111   CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
    112 
    113   /* To avoid overflow, we shift down gainQ10 if it is large.
    114    * We will not lose any precision */
    115   if (gainQ10 > 400000) {
    116     tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
    117     round = 32;
    118     shftVal = 6;
    119   } else {
    120     tmpGain = gainQ10;
    121     round = 256;
    122     shftVal = 9;
    123   }
    124 
    125   for (k = 1; k < AR_ORDER + 1; k++) {
    126     sum = 16384;
    127     for (n = k; n < AR_ORDER + 1; n++)
    128       sum += WEBRTC_SPL_MUL(ARCoefQ12[n - k], ARCoefQ12[n]); /* Q24 */
    129     sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
    130     CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round,
    131                                        shftVal);
    132   }
    133   sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
    134   for (n = 0; n < FRAMESAMPLES / 8; n++) {
    135     CurveQ16[n] = sum;
    136   }
    137   for (k = 1; k < AR_ORDER; k += 2) {
    138     for (n = 0; n < FRAMESAMPLES / 8; n++) {
    139       CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(
    140           WebRtcIsac_kCos[k][n], CorrQ11[k + 1]) + 2, 2);
    141     }
    142   }
    143 
    144   CS_ptrQ9 = WebRtcIsac_kCos[0];
    145 
    146   /* If CorrQ11[1] too large we avoid getting overflow in the
    147    * calculation by shifting */
    148   sh = WebRtcSpl_NormW32(CorrQ11[1]);
    149   if (CorrQ11[1] == 0) { /* Use next correlation */
    150     sh = WebRtcSpl_NormW32(CorrQ11[2]);
    151   }
    152   if (sh < 9) {
    153     shftVal = 9 - sh;
    154   } else {
    155     shftVal = 0;
    156   }
    157   for (n = 0; n < FRAMESAMPLES / 8; n++) {
    158     diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(
    159         CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
    160   }
    161   for (k = 2; k < AR_ORDER; k += 2) {
    162     CS_ptrQ9 = WebRtcIsac_kCos[k];
    163     for (n = 0; n < FRAMESAMPLES / 8; n++) {
    164       diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(
    165           CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k + 1], shftVal)) + 2, 2);
    166     }
    167   }
    168 
    169   for (k = 0; k < FRAMESAMPLES / 8; k++) {
    170     CurveQ16[FRAMESAMPLES_QUARTER - 1 - k] = CurveQ16[k] -
    171         WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
    172     CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
    173   }
    174 }
    175 
    176 /* Generate array of dither samples in Q7. */
    177 static void GenerateDitherQ7Lb(WebRtc_Word16* bufQ7, WebRtc_UWord32 seed,
    178                                int length, WebRtc_Word16 AvgPitchGain_Q12) {
    179   int   k, shft;
    180   WebRtc_Word16 dither1_Q7, dither2_Q7, dither_gain_Q14;
    181 
    182   /* This threshold should be equal to that in decode_spec(). */
    183   if (AvgPitchGain_Q12 < 614) {
    184     for (k = 0; k < length - 2; k += 3) {
    185       /* New random unsigned int. */
    186       seed = (seed * 196314165) + 907633515;
    187 
    188       /* Fixed-point dither sample between -64 and 64 (Q7). */
    189       /* dither = seed * 128 / 4294967295 */
    190       dither1_Q7 = (WebRtc_Word16)(((int)seed + 16777216) >> 25);
    191 
    192       /* New random unsigned int. */
    193       seed = (seed * 196314165) + 907633515;
    194 
    195       /* Fixed-point dither sample between -64 and 64. */
    196       dither2_Q7 = (WebRtc_Word16)(((int)seed + 16777216) >> 25);
    197 
    198       shft = (seed >> 25) & 15;
    199       if (shft < 5) {
    200         bufQ7[k]   = dither1_Q7;
    201         bufQ7[k + 1] = dither2_Q7;
    202         bufQ7[k + 2] = 0;
    203       } else if (shft < 10) {
    204         bufQ7[k]   = dither1_Q7;
    205         bufQ7[k + 1] = 0;
    206         bufQ7[k + 2] = dither2_Q7;
    207       } else {
    208         bufQ7[k]   = 0;
    209         bufQ7[k + 1] = dither1_Q7;
    210         bufQ7[k + 2] = dither2_Q7;
    211       }
    212     }
    213   } else {
    214     dither_gain_Q14 = (WebRtc_Word16)(22528 - 10 * AvgPitchGain_Q12);
    215 
    216     /* Dither on half of the coefficients. */
    217     for (k = 0; k < length - 1; k += 2) {
    218       /* New random unsigned int */
    219       seed = (seed * 196314165) + 907633515;
    220 
    221       /* Fixed-point dither sample between -64 and 64. */
    222       dither1_Q7 = (WebRtc_Word16)(((int)seed + 16777216) >> 25);
    223 
    224       /* Dither sample is placed in either even or odd index. */
    225       shft = (seed >> 25) & 1;     /* Either 0 or 1 */
    226 
    227       bufQ7[k + shft] = (((dither_gain_Q14 * dither1_Q7) + 8192) >> 14);
    228       bufQ7[k + 1 - shft] = 0;
    229     }
    230   }
    231 }
    232 
    233 
    234 
    235 /******************************************************************************
    236  * GenerateDitherQ7LbUB()
    237  *
    238  * generate array of dither samples in Q7 There are less zeros in dither
    239  * vector compared to GenerateDitherQ7Lb.
    240  *
    241  * A uniform random number generator with the range of [-64 64] is employed
    242  * but the generated dithers are scaled by 0.35, a heuristic scaling.
    243  *
    244  * Input:
    245  *      -seed               : the initial seed for the random number generator.
    246  *      -length             : the number of dither values to be generated.
    247  *
    248  * Output:
    249  *      -bufQ7              : pointer to a buffer where dithers are written to.
    250  */
    251 static void GenerateDitherQ7LbUB(
    252     WebRtc_Word16* bufQ7,
    253     WebRtc_UWord32 seed,
    254     int length) {
    255   int k;
    256   for (k = 0; k < length; k++) {
    257     /* new random unsigned int */
    258     seed = (seed * 196314165) + 907633515;
    259 
    260     /* Fixed-point dither sample between -64 and 64 (Q7). */
    261     /* bufQ7 = seed * 128 / 4294967295 */
    262     bufQ7[k] = (WebRtc_Word16)(((int)seed + 16777216) >> 25);
    263 
    264     /* Scale by 0.35. */
    265     bufQ7[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(bufQ7[k], 2048, 13);
    266   }
    267 }
    268 
    269 /*
    270  * Function to decode the complex spectrum from the bit stream
    271  * returns the total number of bytes in the stream.
    272  */
    273 int WebRtcIsac_DecodeSpec(Bitstr* streamdata, WebRtc_Word16 AvgPitchGain_Q12,
    274                           enum ISACBand band, double* fr, double* fi) {
    275   WebRtc_Word16  DitherQ7[FRAMESAMPLES];
    276   WebRtc_Word16  data[FRAMESAMPLES];
    277   WebRtc_Word32  invARSpec2_Q16[FRAMESAMPLES_QUARTER];
    278   WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER];
    279   WebRtc_Word16  ARCoefQ12[AR_ORDER + 1];
    280   WebRtc_Word16  RCQ15[AR_ORDER];
    281   WebRtc_Word16  gainQ10;
    282   WebRtc_Word32  gain2_Q10, res;
    283   WebRtc_Word32  in_sqrt;
    284   WebRtc_Word32  newRes;
    285   int k, len, i;
    286   int is_12khz = !kIsSWB12;
    287   int num_dft_coeff = FRAMESAMPLES;
    288   /* Create dither signal. */
    289   if (band == kIsacLowerBand) {
    290     GenerateDitherQ7Lb(DitherQ7, streamdata->W_upper, FRAMESAMPLES,
    291                        AvgPitchGain_Q12);
    292   } else {
    293     GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES);
    294     if (band == kIsacUpperBand12) {
    295       is_12khz = kIsSWB12;
    296       num_dft_coeff = FRAMESAMPLES_HALF;
    297     }
    298   }
    299 
    300   /* Decode model parameters. */
    301   if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0)
    302     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
    303 
    304   WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
    305 
    306   if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0)
    307     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
    308 
    309   /* Compute inverse AR power spectrum. */
    310   FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
    311 
    312   /* Convert to magnitude spectrum,
    313    * by doing square-roots (modified from SPLIB). */
    314   res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1);
    315   for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
    316     in_sqrt = invARSpec2_Q16[k];
    317     i = 10;
    318 
    319     /* Negative values make no sense for a real sqrt-function. */
    320     if (in_sqrt < 0)
    321       in_sqrt = -in_sqrt;
    322 
    323     newRes = (in_sqrt / res + res) >> 1;
    324     do {
    325       res = newRes;
    326       newRes = (in_sqrt / res + res) >> 1;
    327     } while (newRes != res && i-- > 0);
    328 
    329     invARSpecQ8[k] = (WebRtc_Word16)newRes;
    330   }
    331 
    332   len = WebRtcIsac_DecLogisticMulti2(data, streamdata, invARSpecQ8, DitherQ7,
    333                                      num_dft_coeff, is_12khz);
    334   /* Arithmetic decoding of spectrum. */
    335   if (len < 1) {
    336     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
    337   }
    338 
    339   switch (band) {
    340     case kIsacLowerBand: {
    341       /* Scale down spectral samples with low SNR. */
    342       WebRtc_Word32 p1;
    343       WebRtc_Word32 p2;
    344       if (AvgPitchGain_Q12 <= 614) {
    345         p1 = 30 << 10;
    346         p2 = 32768 + (33 << 16);
    347       } else {
    348         p1 = 36 << 10;
    349         p2 = 32768 + (40 << 16);
    350       }
    351       for (k = 0; k < FRAMESAMPLES; k += 4) {
    352         gainQ10 = WebRtcSpl_DivW32W16ResW16(p1, (WebRtc_Word16)(
    353             (invARSpec2_Q16[k >> 2] + p2) >> 16));
    354         *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0;
    355         *fi++ = (double)((data[k + 1] * gainQ10 + 512) >> 10) / 128.0;
    356         *fr++ = (double)((data[k + 2] * gainQ10 + 512) >> 10) / 128.0;
    357         *fi++ = (double)((data[k + 3] * gainQ10 + 512) >> 10) / 128.0;
    358       }
    359       break;
    360     }
    361     case kIsacUpperBand12: {
    362       for (k = 0, i = 0; k < FRAMESAMPLES_HALF; k += 4) {
    363         fr[i] = (double)data[ k ] / 128.0;
    364         fi[i] = (double)data[k + 1] / 128.0;
    365         i++;
    366         fr[i] = (double)data[k + 2] / 128.0;
    367         fi[i] = (double)data[k + 3] / 128.0;
    368         i++;
    369       }
    370       /* The second half of real and imaginary coefficients is zero. This is
    371        * due to using the old FFT module which requires two signals as input
    372        * while in 0-12 kHz mode we only have 8-12 kHz band, and the second
    373        * signal is set to zero. */
    374       memset(&fr[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER *
    375              sizeof(double));
    376       memset(&fi[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER *
    377              sizeof(double));
    378       break;
    379     }
    380     case kIsacUpperBand16: {
    381       for (i = 0, k = 0; k < FRAMESAMPLES; k += 4, i++) {
    382         fr[i] = (double)data[ k ] / 128.0;
    383         fi[i] = (double)data[k + 1] / 128.0;
    384         fr[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 2] / 128.0;
    385         fi[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 3] / 128.0;
    386       }
    387       break;
    388     }
    389   }
    390   return len;
    391 }
    392 
    393 
    394 int WebRtcIsac_EncodeSpec(const WebRtc_Word16* fr, const WebRtc_Word16* fi,
    395                           WebRtc_Word16 AvgPitchGain_Q12, enum ISACBand band,
    396                           Bitstr* streamdata) {
    397   WebRtc_Word16 ditherQ7[FRAMESAMPLES];
    398   WebRtc_Word16 dataQ7[FRAMESAMPLES];
    399   WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER];
    400   WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER];
    401   WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER];
    402   WebRtc_Word32 CorrQ7[AR_ORDER + 1];
    403   WebRtc_Word32 CorrQ7_norm[AR_ORDER + 1];
    404   WebRtc_Word16 RCQ15[AR_ORDER];
    405   WebRtc_Word16 ARCoefQ12[AR_ORDER + 1];
    406   WebRtc_Word32 gain2_Q10;
    407   WebRtc_Word16 val;
    408   WebRtc_Word32 nrg, res;
    409   WebRtc_UWord32 sum;
    410   WebRtc_Word32 in_sqrt;
    411   WebRtc_Word32 newRes;
    412   WebRtc_Word16 err;
    413   WebRtc_UWord32 nrg_u32;
    414   int shift_var;
    415   int k, n, j, i;
    416   int is_12khz = !kIsSWB12;
    417   int num_dft_coeff = FRAMESAMPLES;
    418 
    419   /* Create dither signal. */
    420   if (band == kIsacLowerBand) {
    421     GenerateDitherQ7Lb(ditherQ7, streamdata->W_upper, FRAMESAMPLES,
    422                        AvgPitchGain_Q12);
    423   } else {
    424     GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES);
    425     if (band == kIsacUpperBand12) {
    426       is_12khz = kIsSWB12;
    427       num_dft_coeff = FRAMESAMPLES_HALF;
    428     }
    429   }
    430 
    431   /* add dither and quantize, and compute power spectrum */
    432   switch (band) {
    433     case kIsacLowerBand: {
    434       for (k = 0; k < FRAMESAMPLES; k += 4) {
    435         val = ((*fr++ + ditherQ7[k]   + 64) & 0xFF80) - ditherQ7[k];
    436         dataQ7[k] = val;
    437         sum = val * val;
    438 
    439         val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1];
    440         dataQ7[k + 1] = val;
    441         sum += val * val;
    442 
    443         val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2];
    444         dataQ7[k + 2] = val;
    445         sum += val * val;
    446 
    447         val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3];
    448         dataQ7[k + 3] = val;
    449         sum += val * val;
    450 
    451         PSpec[k >> 2] = sum >> 2;
    452       }
    453       break;
    454     }
    455     case kIsacUpperBand12: {
    456       for (k = 0, j = 0; k < FRAMESAMPLES_HALF; k += 4) {
    457         val = ((*fr++ + ditherQ7[k]   + 64) & 0xFF80) - ditherQ7[k];
    458         dataQ7[k] = val;
    459         sum = val * val;
    460 
    461         val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1];
    462         dataQ7[k + 1] = val;
    463         sum += val * val;
    464 
    465         PSpec[j++] = sum >> 1;
    466 
    467         val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2];
    468         dataQ7[k + 2] = val;
    469         sum = val * val;
    470 
    471         val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3];
    472         dataQ7[k + 3] = val;
    473         sum += val * val;
    474 
    475         PSpec[j++] = sum >> 1;
    476       }
    477       break;
    478     }
    479     case kIsacUpperBand16: {
    480       for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) {
    481         val = ((fr[j] + ditherQ7[k]   + 64) & 0xFF80) - ditherQ7[k];
    482         dataQ7[k] = val;
    483         sum = val * val;
    484 
    485         val = ((fi[j] + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1];
    486         dataQ7[k + 1] = val;
    487         sum += val * val;
    488 
    489         val = ((fr[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 2] + 64) &
    490             0xFF80) - ditherQ7[k + 2];
    491         dataQ7[k + 2] = val;
    492         sum += val * val;
    493 
    494         val = ((fi[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 3] + 64) &
    495             0xFF80) - ditherQ7[k + 3];
    496         dataQ7[k + 3] = val;
    497         sum += val * val;
    498 
    499         PSpec[k >> 2] = sum >> 2;
    500       }
    501       break;
    502     }
    503   }
    504 
    505   /* compute correlation from power spectrum */
    506   FindCorrelation(PSpec, CorrQ7);
    507 
    508   /* Find AR coefficients */
    509   /* Aumber of bit shifts to 14-bit normalize CorrQ7[0]
    510    * (leaving room for sign) */
    511   shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
    512 
    513   if (shift_var > 0) {
    514     for (k = 0; k < AR_ORDER + 1; k++) {
    515       CorrQ7_norm[k] = CorrQ7[k] << shift_var;
    516     }
    517   } else {
    518     for (k = 0; k < AR_ORDER + 1; k++) {
    519       CorrQ7_norm[k] = CorrQ7[k] >> (-shift_var);
    520     }
    521   }
    522 
    523   /* Find RC coefficients. */
    524   WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15);
    525 
    526   /* Quantize & code RC Coefficient. */
    527   WebRtcIsac_EncodeRc(RCQ15, streamdata);
    528 
    529   /* RC -> AR coefficients */
    530   WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
    531 
    532   /* Compute ARCoef' * Corr * ARCoef in Q19. */
    533   nrg = 0;
    534   for (j = 0; j <= AR_ORDER; j++) {
    535     for (n = 0; n <= j; n++) {
    536       nrg += (ARCoefQ12[j] * ((CorrQ7_norm[j - n] * ARCoefQ12[n] + 256) >> 9) +
    537           4) >> 3;
    538     }
    539     for (n = j + 1; n <= AR_ORDER; n++) {
    540       nrg += (ARCoefQ12[j] * ((CorrQ7_norm[n - j] * ARCoefQ12[n] + 256) >> 9) +
    541           4) >> 3;
    542     }
    543   }
    544 
    545   nrg_u32 = (WebRtc_UWord32)nrg;
    546   if (shift_var > 0) {
    547     nrg_u32 = nrg_u32 >> shift_var;
    548   } else {
    549     nrg_u32 = nrg_u32 << (-shift_var);
    550   }
    551   if (nrg_u32 > 0x7FFFFFFF) {
    552     nrg = 0x7FFFFFFF;
    553   }  else {
    554     nrg = (WebRtc_Word32)nrg_u32;
    555   }
    556   /* Also shifts 31 bits to the left! */
    557   gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg);
    558 
    559   /* Quantize & code gain2_Q10. */
    560   if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) {
    561     return -1;
    562   }
    563 
    564   /* Compute inverse AR power spectrum. */
    565   FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
    566   /* Convert to magnitude spectrum, by doing square-roots
    567    * (modified from SPLIB). */
    568   res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1);
    569   for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
    570     in_sqrt = invARSpec2_Q16[k];
    571     i = 10;
    572     /* Negative values make no sense for a real sqrt-function. */
    573     if (in_sqrt < 0) {
    574       in_sqrt = -in_sqrt;
    575     }
    576     newRes = (in_sqrt / res + res) >> 1;
    577     do {
    578       res = newRes;
    579       newRes = (in_sqrt / res + res) >> 1;
    580     } while (newRes != res && i-- > 0);
    581 
    582     invARSpecQ8[k] = (WebRtc_Word16)newRes;
    583   }
    584   /* arithmetic coding of spectrum */
    585   err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8,
    586                                      num_dft_coeff, is_12khz);
    587   if (err < 0) {
    588     return (err);
    589   }
    590   return 0;
    591 }
    592 
    593 
    594 /* step-up */
    595 void WebRtcIsac_Rc2Poly(double* RC, int N, double* a) {
    596   int m, k;
    597   double tmp[MAX_AR_MODEL_ORDER];
    598 
    599   a[0] = 1.0;
    600   tmp[0] = 1.0;
    601   for (m = 1; m <= N; m++) {
    602     /* copy */
    603     memcpy(&tmp[1], &a[1], (m - 1) * sizeof(double));
    604     a[m] = RC[m - 1];
    605     for (k = 1; k < m; k++) {
    606       a[k] += RC[m - 1] * tmp[m - k];
    607     }
    608   }
    609   return;
    610 }
    611 
    612 /* step-down */
    613 void WebRtcIsac_Poly2Rc(double* a, int N, double* RC) {
    614   int m, k;
    615   double tmp[MAX_AR_MODEL_ORDER];
    616   double tmp_inv;
    617 
    618   RC[N - 1] = a[N];
    619   for (m = N - 1; m > 0; m--) {
    620     tmp_inv = 1.0 / (1.0 - RC[m] * RC[m]);
    621     for (k = 1; k <= m; k++) {
    622       tmp[k] = (a[k] - RC[m] * a[m - k + 1]) * tmp_inv;
    623     }
    624 
    625     memcpy(&a[1], &tmp[1], (m - 1) * sizeof(double));
    626     RC[m - 1] = tmp[m];
    627   }
    628   return;
    629 }
    630 
    631 
    632 #define MAX_ORDER 100
    633 
    634 /* Matlab's LAR definition */
    635 void WebRtcIsac_Rc2Lar(const double* refc, double* lar, int order) {
    636   int k;
    637   for (k = 0; k < order; k++) {
    638     lar[k] = log((1 + refc[k]) / (1 - refc[k]));
    639   }
    640 }
    641 
    642 
    643 void WebRtcIsac_Lar2Rc(const double* lar, double* refc,  int order) {
    644   int k;
    645   double tmp;
    646 
    647   for (k = 0; k < order; k++) {
    648     tmp = exp(lar[k]);
    649     refc[k] = (tmp - 1) / (tmp + 1);
    650   }
    651 }
    652 
    653 void WebRtcIsac_Poly2Lar(double* lowband, int orderLo, double* hiband,
    654                          int orderHi, int Nsub, double* lars) {
    655   int k;
    656   double rc[MAX_ORDER], *inpl, *inph, *outp;
    657 
    658   inpl = lowband;
    659   inph = hiband;
    660   outp = lars;
    661   for (k = 0; k < Nsub; k++) {
    662     /* gains */
    663     outp[0] = inpl[0];
    664     outp[1] = inph[0];
    665     outp += 2;
    666 
    667     /* Low band */
    668     inpl[0] = 1.0;
    669     WebRtcIsac_Poly2Rc(inpl, orderLo, rc);
    670     WebRtcIsac_Rc2Lar(rc, outp, orderLo);
    671     outp += orderLo;
    672 
    673     /* High band */
    674     inph[0] = 1.0;
    675     WebRtcIsac_Poly2Rc(inph, orderHi, rc);
    676     WebRtcIsac_Rc2Lar(rc, outp, orderHi);
    677     outp += orderHi;
    678 
    679     inpl += orderLo + 1;
    680     inph += orderHi + 1;
    681   }
    682 }
    683 
    684 
    685 WebRtc_Word16 WebRtcIsac_Poly2LarUB(double* lpcVecs, WebRtc_Word16 bandwidth) {
    686   double      poly[MAX_ORDER];
    687   double      rc[MAX_ORDER];
    688   double*     ptrIO;
    689   WebRtc_Word16 vecCntr;
    690   WebRtc_Word16 vecSize;
    691   WebRtc_Word16 numVec;
    692 
    693   vecSize = UB_LPC_ORDER;
    694   switch (bandwidth) {
    695     case isac12kHz: {
    696       numVec  = UB_LPC_VEC_PER_FRAME;
    697       break;
    698     }
    699     case isac16kHz: {
    700       numVec  = UB16_LPC_VEC_PER_FRAME;
    701       break;
    702     }
    703     default:
    704       return -1;
    705   }
    706 
    707   ptrIO = lpcVecs;
    708   poly[0] = 1.0;
    709   for (vecCntr = 0; vecCntr < numVec; vecCntr++) {
    710     memcpy(&poly[1], ptrIO, sizeof(double) * vecSize);
    711     WebRtcIsac_Poly2Rc(poly, vecSize, rc);
    712     WebRtcIsac_Rc2Lar(rc, ptrIO, vecSize);
    713     ptrIO += vecSize;
    714   }
    715   return 0;
    716 }
    717 
    718 
    719 void WebRtcIsac_Lar2Poly(double* lars, double* lowband, int orderLo,
    720                          double* hiband, int orderHi, int Nsub) {
    721   int k, orderTot;
    722   double rc[MAX_ORDER], *outpl, *outph, *inp;
    723 
    724   orderTot = (orderLo + orderHi + 2);
    725   outpl = lowband;
    726   outph = hiband;
    727   /* First two elements of 'inp' store gains*/
    728   inp = lars;
    729   for (k = 0; k < Nsub; k++) {
    730     /* Low band */
    731     WebRtcIsac_Lar2Rc(&inp[2], rc, orderLo);
    732     WebRtcIsac_Rc2Poly(rc, orderLo, outpl);
    733 
    734     /* High band */
    735     WebRtcIsac_Lar2Rc(&inp[orderLo + 2], rc, orderHi);
    736     WebRtcIsac_Rc2Poly(rc, orderHi, outph);
    737 
    738     /* gains */
    739     outpl[0] = inp[0];
    740     outph[0] = inp[1];
    741 
    742     outpl += orderLo + 1;
    743     outph += orderHi + 1;
    744     inp += orderTot;
    745   }
    746 }
    747 
    748 /*
    749  *  assumes 2 LAR vectors interpolates to 'numPolyVec' A-polynomials
    750  *  Note: 'numPolyVecs' includes the first and the last point of the interval
    751  */
    752 void WebRtcIsac_Lar2PolyInterpolUB(double* larVecs, double* percepFilterParams,
    753                                    int numPolyVecs) {
    754   int polyCntr, coeffCntr;
    755   double larInterpol[UB_LPC_ORDER];
    756   double rc[UB_LPC_ORDER];
    757   double delta[UB_LPC_ORDER];
    758 
    759   /* calculate the step-size for linear interpolation coefficients */
    760   for (coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) {
    761     delta[coeffCntr] = (larVecs[UB_LPC_ORDER + coeffCntr] -
    762         larVecs[coeffCntr]) / (numPolyVecs - 1);
    763   }
    764 
    765   for (polyCntr = 0; polyCntr < numPolyVecs; polyCntr++) {
    766     for (coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) {
    767       larInterpol[coeffCntr] = larVecs[coeffCntr] +
    768           delta[coeffCntr] * polyCntr;
    769     }
    770     WebRtcIsac_Lar2Rc(larInterpol, rc, UB_LPC_ORDER);
    771 
    772     /* convert to A-polynomial, the following function returns A[0] = 1;
    773      * which is written where gains had to be written. Then we write the
    774      * gain (outside this function). This way we say a memcpy. */
    775     WebRtcIsac_Rc2Poly(rc, UB_LPC_ORDER, percepFilterParams);
    776     percepFilterParams += (UB_LPC_ORDER + 1);
    777   }
    778 }
    779 
    780 int WebRtcIsac_DecodeLpc(Bitstr* streamdata, double* LPCCoef_lo,
    781                          double* LPCCoef_hi) {
    782   double lars[KLT_ORDER_GAIN + KLT_ORDER_SHAPE];
    783   int err;
    784 
    785   err = WebRtcIsac_DecodeLpcCoef(streamdata, lars);
    786   if (err < 0) {
    787     return -ISAC_RANGE_ERROR_DECODE_LPC;
    788   }
    789   WebRtcIsac_Lar2Poly(lars, LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI,
    790                       SUBFRAMES);
    791   return 0;
    792 }
    793 
    794 WebRtc_Word16 WebRtcIsac_DecodeInterpolLpcUb(Bitstr* streamdata,
    795                                              double* percepFilterParams,
    796                                              WebRtc_Word16 bandwidth) {
    797   double lpcCoeff[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
    798   int err;
    799   int interpolCntr;
    800   int subframeCntr;
    801   WebRtc_Word16 numSegments;
    802   WebRtc_Word16 numVecPerSegment;
    803   WebRtc_Word16 numGains;
    804 
    805   double percepFilterGains[SUBFRAMES << 1];
    806   double* ptrOutParam = percepFilterParams;
    807 
    808   err = WebRtcIsac_DecodeLpcCoefUB(streamdata, lpcCoeff, percepFilterGains,
    809                                    bandwidth);
    810   if (err < 0) {
    811     return -ISAC_RANGE_ERROR_DECODE_LPC;
    812   }
    813 
    814   switch (bandwidth) {
    815     case isac12kHz: {
    816       numGains = SUBFRAMES;
    817       numSegments = UB_LPC_VEC_PER_FRAME - 1;
    818       numVecPerSegment = kLpcVecPerSegmentUb12;
    819       break;
    820     }
    821     case isac16kHz: {
    822       numGains = SUBFRAMES << 1;
    823       numSegments = UB16_LPC_VEC_PER_FRAME - 1;
    824       numVecPerSegment = kLpcVecPerSegmentUb16;
    825       break;
    826     }
    827     default:
    828       return -1;
    829   }
    830 
    831   for (interpolCntr = 0; interpolCntr < numSegments; interpolCntr++) {
    832     WebRtcIsac_Lar2PolyInterpolUB(&lpcCoeff[interpolCntr * UB_LPC_ORDER],
    833                                   ptrOutParam, numVecPerSegment + 1);
    834     ptrOutParam += (numVecPerSegment * (UB_LPC_ORDER + 1));
    835   }
    836 
    837   ptrOutParam = percepFilterParams;
    838 
    839   if (bandwidth == isac16kHz) {
    840     ptrOutParam += (1 + UB_LPC_ORDER);
    841   }
    842 
    843   for (subframeCntr = 0; subframeCntr < numGains; subframeCntr++) {
    844     *ptrOutParam = percepFilterGains[subframeCntr];
    845     ptrOutParam += (1 + UB_LPC_ORDER);
    846   }
    847   return 0;
    848 }
    849 
    850 
    851 /* decode & dequantize LPC Coef */
    852 int WebRtcIsac_DecodeLpcCoef(Bitstr* streamdata, double* LPCCoef) {
    853   int j, k, n, pos, pos2, posg, poss, offsg, offss, offs2;
    854   int index_g[KLT_ORDER_GAIN], index_s[KLT_ORDER_SHAPE];
    855   double tmpcoeffs_g[KLT_ORDER_GAIN], tmpcoeffs_s[KLT_ORDER_SHAPE];
    856   double tmpcoeffs2_g[KLT_ORDER_GAIN], tmpcoeffs2_s[KLT_ORDER_SHAPE];
    857   double sum;
    858   int err;
    859   int model = 1;
    860 
    861   /* entropy decoding of model number */
    862   /* We are keeping this for backward compatibility of bit-streams. */
    863   err = WebRtcIsac_DecHistOneStepMulti(&model, streamdata,
    864                                        WebRtcIsac_kQKltModelCdfPtr,
    865                                        WebRtcIsac_kQKltModelInitIndex, 1);
    866   if (err < 0) {
    867     return err;
    868   }
    869   /* Only accepted value of model is 0. It is kept in bit-stream for backward
    870    * compatibility. */
    871   if (model != 0) {
    872     return -ISAC_DISALLOWED_LPC_MODEL;
    873   }
    874 
    875   /* entropy decoding of quantization indices */
    876   err = WebRtcIsac_DecHistOneStepMulti(
    877       index_s, streamdata, WebRtcIsac_kQKltCdfPtrShape,
    878       WebRtcIsac_kQKltInitIndexShape, KLT_ORDER_SHAPE);
    879   if (err < 0) {
    880     return err;
    881   }
    882   err = WebRtcIsac_DecHistOneStepMulti(
    883       index_g, streamdata, WebRtcIsac_kQKltCdfPtrGain,
    884       WebRtcIsac_kQKltInitIndexGain, KLT_ORDER_GAIN);
    885   if (err < 0) {
    886     return err;
    887   }
    888 
    889   /* find quantization levels for coefficients */
    890   for (k = 0; k < KLT_ORDER_SHAPE; k++) {
    891     tmpcoeffs_s[k] =
    892         WebRtcIsac_kQKltLevelsShape[WebRtcIsac_kQKltOffsetShape[k] +
    893                                     index_s[k]];
    894   }
    895   for (k = 0; k < KLT_ORDER_GAIN; k++) {
    896     tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[WebRtcIsac_kQKltOffsetGain[k] +
    897                                                 index_g[k]];
    898   }
    899 
    900   /* Inverse KLT  */
    901 
    902   /* Left transform, transpose matrix!  */
    903   offsg = 0;
    904   offss = 0;
    905   posg = 0;
    906   poss = 0;
    907   for (j = 0; j < SUBFRAMES; j++) {
    908     offs2 = 0;
    909     for (k = 0; k < LPC_GAIN_ORDER; k++) {
    910       sum = 0;
    911       pos = offsg;
    912       pos2 = offs2;
    913       for (n = 0; n < LPC_GAIN_ORDER; n++) {
    914         sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2++];
    915       }
    916       tmpcoeffs2_g[posg++] = sum;
    917       offs2 += LPC_GAIN_ORDER;
    918     }
    919     offs2 = 0;
    920     for (k = 0; k < LPC_SHAPE_ORDER; k++) {
    921       sum = 0;
    922       pos = offss;
    923       pos2 = offs2;
    924       for (n = 0; n < LPC_SHAPE_ORDER; n++) {
    925         sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2++];
    926       }
    927       tmpcoeffs2_s[poss++] = sum;
    928       offs2 += LPC_SHAPE_ORDER;
    929     }
    930     offsg += LPC_GAIN_ORDER;
    931     offss += LPC_SHAPE_ORDER;
    932   }
    933 
    934   /* Right transform, transpose matrix */
    935   offsg = 0;
    936   offss = 0;
    937   posg = 0;
    938   poss = 0;
    939   for (j = 0; j < SUBFRAMES; j++) {
    940     posg = offsg;
    941     for (k = 0; k < LPC_GAIN_ORDER; k++) {
    942       sum = 0;
    943       pos = k;
    944       pos2 = j;
    945       for (n = 0; n < SUBFRAMES; n++) {
    946         sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2];
    947         pos += LPC_GAIN_ORDER;
    948         pos2 += SUBFRAMES;
    949 
    950       }
    951       tmpcoeffs_g[posg++] = sum;
    952     }
    953     poss = offss;
    954     for (k = 0; k < LPC_SHAPE_ORDER; k++) {
    955       sum = 0;
    956       pos = k;
    957       pos2 = j;
    958       for (n = 0; n < SUBFRAMES; n++) {
    959         sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2];
    960         pos += LPC_SHAPE_ORDER;
    961         pos2 += SUBFRAMES;
    962       }
    963       tmpcoeffs_s[poss++] = sum;
    964     }
    965     offsg += LPC_GAIN_ORDER;
    966     offss += LPC_SHAPE_ORDER;
    967   }
    968 
    969   /* scaling, mean addition, and gain restoration */
    970   posg = 0;
    971   poss = 0;
    972   pos = 0;
    973   for (k = 0; k < SUBFRAMES; k++) {
    974     /* log gains */
    975     LPCCoef[pos] = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
    976     LPCCoef[pos] += WebRtcIsac_kLpcMeansGain[posg];
    977     LPCCoef[pos] = exp(LPCCoef[pos]);
    978     pos++;
    979     posg++;
    980     LPCCoef[pos] = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
    981     LPCCoef[pos] += WebRtcIsac_kLpcMeansGain[posg];
    982     LPCCoef[pos] = exp(LPCCoef[pos]);
    983     pos++;
    984     posg++;
    985 
    986     /* Low-band LAR coefficients. */
    987     for (n = 0; n < LPC_LOBAND_ORDER; n++, pos++, poss++) {
    988       LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_LOBAND_SCALE;
    989       LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
    990     }
    991 
    992     /* High-band LAR coefficients. */
    993     for (n = 0; n < LPC_HIBAND_ORDER; n++, pos++, poss++) {
    994       LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_HIBAND_SCALE;
    995       LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
    996     }
    997   }
    998   return 0;
    999 }
   1000 
   1001 /* Encode LPC in LAR domain. */
   1002 void WebRtcIsac_EncodeLar(double* LPCCoef, Bitstr* streamdata,
   1003                           ISAC_SaveEncData_t* encData) {
   1004   int j, k, n, pos, pos2, poss, offss, offs2;
   1005   int index_s[KLT_ORDER_SHAPE];
   1006   int index_ovr_s[KLT_ORDER_SHAPE];
   1007   double tmpcoeffs_s[KLT_ORDER_SHAPE];
   1008   double tmpcoeffs2_s[KLT_ORDER_SHAPE];
   1009   double sum;
   1010   const int kModel = 0;
   1011 
   1012   /* Mean removal and scaling. */
   1013   poss = 0;
   1014   pos = 0;
   1015   for (k = 0; k < SUBFRAMES; k++) {
   1016     /* First two element are gains, move over them. */
   1017     pos += 2;
   1018 
   1019     /* Low-band LAR coefficients. */
   1020     for (n = 0; n < LPC_LOBAND_ORDER; n++, poss++, pos++) {
   1021       tmpcoeffs_s[poss] = LPCCoef[pos] - WebRtcIsac_kLpcMeansShape[poss];
   1022       tmpcoeffs_s[poss] *= LPC_LOBAND_SCALE;
   1023     }
   1024 
   1025     /* High-band LAR coefficients. */
   1026     for (n = 0; n < LPC_HIBAND_ORDER; n++, poss++, pos++) {
   1027       tmpcoeffs_s[poss] = LPCCoef[pos] - WebRtcIsac_kLpcMeansShape[poss];
   1028       tmpcoeffs_s[poss] *= LPC_HIBAND_SCALE;
   1029     }
   1030   }
   1031 
   1032   /* KLT  */
   1033 
   1034   /* Left transform. */
   1035   offss = 0;
   1036   for (j = 0; j < SUBFRAMES; j++) {
   1037     poss = offss;
   1038     for (k = 0; k < LPC_SHAPE_ORDER; k++) {
   1039       sum = 0;
   1040       pos = offss;
   1041       pos2 = k;
   1042       for (n = 0; n < LPC_SHAPE_ORDER; n++) {
   1043         sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2];
   1044         pos2 += LPC_SHAPE_ORDER;
   1045       }
   1046       tmpcoeffs2_s[poss++] = sum;
   1047     }
   1048     offss += LPC_SHAPE_ORDER;
   1049   }
   1050 
   1051   /* Right transform. */
   1052   offss = 0;
   1053   offs2 = 0;
   1054   for (j = 0; j < SUBFRAMES; j++) {
   1055     poss = offss;
   1056     for (k = 0; k < LPC_SHAPE_ORDER; k++) {
   1057       sum = 0;
   1058       pos = k;
   1059       pos2 = offs2;
   1060       for (n = 0; n < SUBFRAMES; n++) {
   1061         sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2++];
   1062         pos += LPC_SHAPE_ORDER;
   1063       }
   1064       tmpcoeffs_s[poss++] = sum;
   1065     }
   1066     offs2 += SUBFRAMES;
   1067     offss += LPC_SHAPE_ORDER;
   1068   }
   1069 
   1070   /* Quantize coefficients. */
   1071   for (k = 0; k < KLT_ORDER_SHAPE; k++) {
   1072     index_s[k] = (WebRtcIsac_lrint(tmpcoeffs_s[k] / KLT_STEPSIZE)) +
   1073         WebRtcIsac_kQKltQuantMinShape[k];
   1074     if (index_s[k] < 0) {
   1075       index_s[k] = 0;
   1076     } else if (index_s[k] > WebRtcIsac_kQKltMaxIndShape[k]) {
   1077       index_s[k] = WebRtcIsac_kQKltMaxIndShape[k];
   1078     }
   1079     index_ovr_s[k] = WebRtcIsac_kQKltOffsetShape[k] + index_s[k];
   1080   }
   1081 
   1082 
   1083   /* Only one model remains in this version of the code, kModel = 0. We
   1084    * are keeping for bit-streams to be backward compatible. */
   1085   /* entropy coding of model number */
   1086   WebRtcIsac_EncHistMulti(streamdata, &kModel, WebRtcIsac_kQKltModelCdfPtr, 1);
   1087 
   1088   /* Save data for creation of multiple bit streams */
   1089   /* Entropy coding of quantization indices - shape only. */
   1090   WebRtcIsac_EncHistMulti(streamdata, index_s, WebRtcIsac_kQKltCdfPtrShape,
   1091                           KLT_ORDER_SHAPE);
   1092 
   1093   /* Save data for creation of multiple bit streams. */
   1094   for (k = 0; k < KLT_ORDER_SHAPE; k++) {
   1095     encData->LPCindex_s[KLT_ORDER_SHAPE * encData->startIdx + k] = index_s[k];
   1096   }
   1097 
   1098   /* Find quantization levels for shape coefficients. */
   1099   for (k = 0; k < KLT_ORDER_SHAPE; k++) {
   1100     tmpcoeffs_s[k] = WebRtcIsac_kQKltLevelsShape[index_ovr_s[k]];
   1101   }
   1102   /* Inverse KLT.  */
   1103   /* Left transform, transpose matrix.! */
   1104   offss = 0;
   1105   poss = 0;
   1106   for (j = 0; j < SUBFRAMES; j++) {
   1107     offs2 = 0;
   1108     for (k = 0; k < LPC_SHAPE_ORDER; k++) {
   1109       sum = 0;
   1110       pos = offss;
   1111       pos2 = offs2;
   1112       for (n = 0; n < LPC_SHAPE_ORDER; n++) {
   1113         sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2++];
   1114       }
   1115       tmpcoeffs2_s[poss++] = sum;
   1116       offs2 += LPC_SHAPE_ORDER;
   1117     }
   1118     offss += LPC_SHAPE_ORDER;
   1119   }
   1120 
   1121   /* Right transform, Transpose matrix */
   1122   offss = 0;
   1123   poss = 0;
   1124   for (j = 0; j < SUBFRAMES; j++) {
   1125     poss = offss;
   1126     for (k = 0; k < LPC_SHAPE_ORDER; k++) {
   1127       sum = 0;
   1128       pos = k;
   1129       pos2 = j;
   1130       for (n = 0; n < SUBFRAMES; n++) {
   1131         sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2];
   1132         pos += LPC_SHAPE_ORDER;
   1133         pos2 += SUBFRAMES;
   1134       }
   1135       tmpcoeffs_s[poss++] = sum;
   1136     }
   1137     offss += LPC_SHAPE_ORDER;
   1138   }
   1139 
   1140   /* Scaling, mean addition, and gain restoration. */
   1141   poss = 0;
   1142   pos = 0;
   1143   for (k = 0; k < SUBFRAMES; k++) {
   1144     /* Ignore gains. */
   1145     pos += 2;
   1146 
   1147     /* Low band LAR coefficients. */
   1148     for (n = 0; n < LPC_LOBAND_ORDER; n++, pos++, poss++) {
   1149       LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_LOBAND_SCALE;
   1150       LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
   1151     }
   1152 
   1153     /* High band LAR coefficients. */
   1154     for (n = 0; n < LPC_HIBAND_ORDER; n++, pos++, poss++) {
   1155       LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_HIBAND_SCALE;
   1156       LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
   1157     }
   1158   }
   1159 }
   1160 
   1161 
   1162 void WebRtcIsac_EncodeLpcLb(double* LPCCoef_lo, double* LPCCoef_hi,
   1163                             Bitstr* streamdata, ISAC_SaveEncData_t* encData) {
   1164   double lars[KLT_ORDER_GAIN + KLT_ORDER_SHAPE];
   1165   int k;
   1166 
   1167   WebRtcIsac_Poly2Lar(LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI, SUBFRAMES,
   1168                       lars);
   1169   WebRtcIsac_EncodeLar(lars, streamdata, encData);
   1170   WebRtcIsac_Lar2Poly(lars, LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI,
   1171                       SUBFRAMES);
   1172   /* Save data for creation of multiple bit streams (and transcoding). */
   1173   for (k = 0; k < (ORDERLO + 1)*SUBFRAMES; k++) {
   1174     encData->LPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * encData->startIdx + k] =
   1175         LPCCoef_lo[k];
   1176   }
   1177   for (k = 0; k < (ORDERHI + 1)*SUBFRAMES; k++) {
   1178     encData->LPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * encData->startIdx + k] =
   1179         LPCCoef_hi[k];
   1180   }
   1181 }
   1182 
   1183 
   1184 WebRtc_Word16 WebRtcIsac_EncodeLpcUB(double* lpcVecs, Bitstr* streamdata,
   1185                                      double* interpolLPCCoeff,
   1186                                      WebRtc_Word16 bandwidth,
   1187                                      ISACUBSaveEncDataStruct* encData) {
   1188   double    U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
   1189   int     idx[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
   1190   int interpolCntr;
   1191 
   1192   WebRtcIsac_Poly2LarUB(lpcVecs, bandwidth);
   1193   WebRtcIsac_RemoveLarMean(lpcVecs, bandwidth);
   1194   WebRtcIsac_DecorrelateIntraVec(lpcVecs, U, bandwidth);
   1195   WebRtcIsac_DecorrelateInterVec(U, lpcVecs, bandwidth);
   1196   WebRtcIsac_QuantizeUncorrLar(lpcVecs, idx, bandwidth);
   1197 
   1198   WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth);
   1199   WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth);
   1200   WebRtcIsac_AddLarMean(lpcVecs, bandwidth);
   1201 
   1202   switch (bandwidth) {
   1203     case isac12kHz: {
   1204       /* Store the indices to be used for multiple encoding. */
   1205       memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER *
   1206              UB_LPC_VEC_PER_FRAME * sizeof(int));
   1207       WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb12,
   1208                               UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME);
   1209       for (interpolCntr = 0; interpolCntr < UB_INTERPOL_SEGMENTS;
   1210           interpolCntr++) {
   1211         WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff,
   1212                                       kLpcVecPerSegmentUb12 + 1);
   1213         lpcVecs += UB_LPC_ORDER;
   1214         interpolLPCCoeff += (kLpcVecPerSegmentUb12 * (UB_LPC_ORDER + 1));
   1215       }
   1216       break;
   1217     }
   1218     case isac16kHz: {
   1219       /* Store the indices to be used for multiple encoding. */
   1220       memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER *
   1221              UB16_LPC_VEC_PER_FRAME * sizeof(int));
   1222       WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb16,
   1223                               UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME);
   1224       for (interpolCntr = 0; interpolCntr < UB16_INTERPOL_SEGMENTS;
   1225           interpolCntr++) {
   1226         WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff,
   1227                                       kLpcVecPerSegmentUb16 + 1);
   1228         lpcVecs += UB_LPC_ORDER;
   1229         interpolLPCCoeff += (kLpcVecPerSegmentUb16 * (UB_LPC_ORDER + 1));
   1230       }
   1231       break;
   1232     }
   1233     default:
   1234       return -1;
   1235   }
   1236   return 0;
   1237 }
   1238 
   1239 void WebRtcIsac_EncodeLpcGainLb(double* LPCCoef_lo, double* LPCCoef_hi,
   1240                                 Bitstr* streamdata,
   1241                                 ISAC_SaveEncData_t* encData) {
   1242   int j, k, n, pos, pos2, posg, offsg, offs2;
   1243   int index_g[KLT_ORDER_GAIN];
   1244   int index_ovr_g[KLT_ORDER_GAIN];
   1245   double tmpcoeffs_g[KLT_ORDER_GAIN];
   1246   double tmpcoeffs2_g[KLT_ORDER_GAIN];
   1247   double sum;
   1248   /* log gains, mean removal and scaling */
   1249   posg = 0;
   1250   for (k = 0; k < SUBFRAMES; k++) {
   1251     tmpcoeffs_g[posg] = log(LPCCoef_lo[(LPC_LOBAND_ORDER + 1) * k]);
   1252     tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
   1253     tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
   1254     posg++;
   1255     tmpcoeffs_g[posg] = log(LPCCoef_hi[(LPC_HIBAND_ORDER + 1) * k]);
   1256     tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
   1257     tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
   1258     posg++;
   1259   }
   1260 
   1261   /* KLT  */
   1262 
   1263   /* Left transform. */
   1264   offsg = 0;
   1265   for (j = 0; j < SUBFRAMES; j++) {
   1266     posg = offsg;
   1267     for (k = 0; k < LPC_GAIN_ORDER; k++) {
   1268       sum = 0;
   1269       pos = offsg;
   1270       pos2 = k;
   1271       for (n = 0; n < LPC_GAIN_ORDER; n++) {
   1272         sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2];
   1273         pos2 += LPC_GAIN_ORDER;
   1274       }
   1275       tmpcoeffs2_g[posg++] = sum;
   1276     }
   1277     offsg += LPC_GAIN_ORDER;
   1278   }
   1279 
   1280   /* Right transform. */
   1281   offsg = 0;
   1282   offs2 = 0;
   1283   for (j = 0; j < SUBFRAMES; j++) {
   1284     posg = offsg;
   1285     for (k = 0; k < LPC_GAIN_ORDER; k++) {
   1286       sum = 0;
   1287       pos = k;
   1288       pos2 = offs2;
   1289       for (n = 0; n < SUBFRAMES; n++) {
   1290         sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2++];
   1291         pos += LPC_GAIN_ORDER;
   1292       }
   1293       tmpcoeffs_g[posg++] = sum;
   1294     }
   1295     offs2 += SUBFRAMES;
   1296     offsg += LPC_GAIN_ORDER;
   1297   }
   1298 
   1299   /* Quantize coefficients. */
   1300   for (k = 0; k < KLT_ORDER_GAIN; k++) {
   1301     /* Get index. */
   1302     pos2 = WebRtcIsac_lrint(tmpcoeffs_g[k] / KLT_STEPSIZE);
   1303     index_g[k] = (pos2) + WebRtcIsac_kQKltQuantMinGain[k];
   1304     if (index_g[k] < 0) {
   1305       index_g[k] = 0;
   1306     } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) {
   1307       index_g[k] = WebRtcIsac_kQKltMaxIndGain[k];
   1308     }
   1309     index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k];
   1310 
   1311     /* Find quantization levels for coefficients. */
   1312     tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]];
   1313 
   1314     /* Save data for creation of multiple bit streams. */
   1315     encData->LPCindex_g[KLT_ORDER_GAIN * encData->startIdx + k] = index_g[k];
   1316   }
   1317 
   1318   /* Entropy coding of quantization indices - gain. */
   1319   WebRtcIsac_EncHistMulti(streamdata, index_g, WebRtcIsac_kQKltCdfPtrGain,
   1320                           KLT_ORDER_GAIN);
   1321 
   1322   /* Find quantization levels for coefficients. */
   1323   /* Left transform. */
   1324   offsg = 0;
   1325   posg = 0;
   1326   for (j = 0; j < SUBFRAMES; j++) {
   1327     offs2 = 0;
   1328     for (k = 0; k < LPC_GAIN_ORDER; k++) {
   1329       sum = 0;
   1330       pos = offsg;
   1331       pos2 = offs2;
   1332       for (n = 0; n < LPC_GAIN_ORDER; n++)
   1333         sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2++];
   1334       tmpcoeffs2_g[posg++] = sum;
   1335       offs2 += LPC_GAIN_ORDER;
   1336     }
   1337     offsg += LPC_GAIN_ORDER;
   1338   }
   1339 
   1340   /* Right transform, transpose matrix. */
   1341   offsg = 0;
   1342   posg = 0;
   1343   for (j = 0; j < SUBFRAMES; j++) {
   1344     posg = offsg;
   1345     for (k = 0; k < LPC_GAIN_ORDER; k++) {
   1346       sum = 0;
   1347       pos = k;
   1348       pos2 = j;
   1349       for (n = 0; n < SUBFRAMES; n++) {
   1350         sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2];
   1351         pos += LPC_GAIN_ORDER;
   1352         pos2 += SUBFRAMES;
   1353       }
   1354       tmpcoeffs_g[posg++] = sum;
   1355     }
   1356     offsg += LPC_GAIN_ORDER;
   1357   }
   1358 
   1359 
   1360   /* Scaling, mean addition, and gain restoration. */
   1361   posg = 0;
   1362   for (k = 0; k < SUBFRAMES; k++) {
   1363     sum = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
   1364     sum += WebRtcIsac_kLpcMeansGain[posg];
   1365     LPCCoef_lo[k * (LPC_LOBAND_ORDER + 1)] = exp(sum);
   1366     pos++;
   1367     posg++;
   1368     sum = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
   1369     sum += WebRtcIsac_kLpcMeansGain[posg];
   1370     LPCCoef_hi[k * (LPC_HIBAND_ORDER + 1)] = exp(sum);
   1371     pos++;
   1372     posg++;
   1373   }
   1374 
   1375 }
   1376 
   1377 void WebRtcIsac_EncodeLpcGainUb(double* lpGains, Bitstr* streamdata,
   1378                                 int* lpcGainIndex) {
   1379   double U[UB_LPC_GAIN_DIM];
   1380   int idx[UB_LPC_GAIN_DIM];
   1381   WebRtcIsac_ToLogDomainRemoveMean(lpGains);
   1382   WebRtcIsac_DecorrelateLPGain(lpGains, U);
   1383   WebRtcIsac_QuantizeLpcGain(U, idx);
   1384   /* Store the index for re-encoding for FEC. */
   1385   memcpy(lpcGainIndex, idx, UB_LPC_GAIN_DIM * sizeof(int));
   1386   WebRtcIsac_CorrelateLpcGain(U, lpGains);
   1387   WebRtcIsac_AddMeanToLinearDomain(lpGains);
   1388   WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcGainCdfMat,
   1389                           UB_LPC_GAIN_DIM);
   1390 }
   1391 
   1392 
   1393 void WebRtcIsac_StoreLpcGainUb(double* lpGains, Bitstr* streamdata) {
   1394   double U[UB_LPC_GAIN_DIM];
   1395   int idx[UB_LPC_GAIN_DIM];
   1396   WebRtcIsac_ToLogDomainRemoveMean(lpGains);
   1397   WebRtcIsac_DecorrelateLPGain(lpGains, U);
   1398   WebRtcIsac_QuantizeLpcGain(U, idx);
   1399   WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcGainCdfMat,
   1400                           UB_LPC_GAIN_DIM);
   1401 }
   1402 
   1403 
   1404 
   1405 WebRtc_Word16 WebRtcIsac_DecodeLpcGainUb(double* lpGains, Bitstr* streamdata) {
   1406   double U[UB_LPC_GAIN_DIM];
   1407   int idx[UB_LPC_GAIN_DIM];
   1408   int err;
   1409   err = WebRtcIsac_DecHistOneStepMulti(idx, streamdata,
   1410                                        WebRtcIsac_kLpcGainCdfMat,
   1411                                        WebRtcIsac_kLpcGainEntropySearch,
   1412                                        UB_LPC_GAIN_DIM);
   1413   if (err < 0) {
   1414     return -1;
   1415   }
   1416   WebRtcIsac_DequantizeLpcGain(idx, U);
   1417   WebRtcIsac_CorrelateLpcGain(U, lpGains);
   1418   WebRtcIsac_AddMeanToLinearDomain(lpGains);
   1419   return 0;
   1420 }
   1421 
   1422 
   1423 
   1424 /* decode & dequantize RC */
   1425 int WebRtcIsac_DecodeRc(Bitstr* streamdata, WebRtc_Word16* RCQ15) {
   1426   int k, err;
   1427   int index[AR_ORDER];
   1428 
   1429   /* entropy decoding of quantization indices */
   1430   err = WebRtcIsac_DecHistOneStepMulti(index, streamdata,
   1431                                        WebRtcIsac_kQArRcCdfPtr,
   1432                                        WebRtcIsac_kQArRcInitIndex, AR_ORDER);
   1433   if (err < 0)
   1434     return err;
   1435 
   1436   /* find quantization levels for reflection coefficients */
   1437   for (k = 0; k < AR_ORDER; k++) {
   1438     RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]);
   1439   }
   1440   return 0;
   1441 }
   1442 
   1443 
   1444 /* quantize & code RC */
   1445 void WebRtcIsac_EncodeRc(WebRtc_Word16* RCQ15, Bitstr* streamdata) {
   1446   int k;
   1447   int index[AR_ORDER];
   1448 
   1449   /* quantize reflection coefficients (add noise feedback?) */
   1450   for (k = 0; k < AR_ORDER; k++) {
   1451     index[k] = WebRtcIsac_kQArRcInitIndex[k];
   1452 
   1453     if (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k]]) {
   1454       while (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k] + 1]) {
   1455         index[k]++;
   1456       }
   1457     } else {
   1458       while (RCQ15[k] < WebRtcIsac_kQArBoundaryLevels[--index[k]]) ;
   1459     }
   1460     RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]);
   1461   }
   1462 
   1463   /* entropy coding of quantization indices */
   1464   WebRtcIsac_EncHistMulti(streamdata, index, WebRtcIsac_kQArRcCdfPtr, AR_ORDER);
   1465 }
   1466 
   1467 
   1468 /* decode & dequantize squared Gain */
   1469 int WebRtcIsac_DecodeGain2(Bitstr* streamdata, WebRtc_Word32* gainQ10) {
   1470   int index, err;
   1471 
   1472   /* entropy decoding of quantization index */
   1473   err = WebRtcIsac_DecHistOneStepMulti(&index, streamdata,
   1474                                        WebRtcIsac_kQGainCdf_ptr,
   1475                                        WebRtcIsac_kQGainInitIndex, 1);
   1476   if (err < 0) {
   1477     return err;
   1478   }
   1479   /* find quantization level */
   1480   *gainQ10 = WebRtcIsac_kQGain2Levels[index];
   1481   return 0;
   1482 }
   1483 
   1484 
   1485 /* quantize & code squared Gain */
   1486 int WebRtcIsac_EncodeGain2(WebRtc_Word32* gainQ10, Bitstr* streamdata) {
   1487   int index;
   1488 
   1489   /* find quantization index */
   1490   index = WebRtcIsac_kQGainInitIndex[0];
   1491   if (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index]) {
   1492     while (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index + 1]) {
   1493       index++;
   1494     }
   1495   } else {
   1496     while (*gainQ10 < WebRtcIsac_kQGain2BoundaryLevels[--index]) ;
   1497   }
   1498   /* De-quantize */
   1499   *gainQ10 = WebRtcIsac_kQGain2Levels[index];
   1500 
   1501   /* entropy coding of quantization index */
   1502   WebRtcIsac_EncHistMulti(streamdata, &index, WebRtcIsac_kQGainCdf_ptr, 1);
   1503   return 0;
   1504 }
   1505 
   1506 
   1507 /* code and decode Pitch Gains and Lags functions */
   1508 
   1509 /* decode & dequantize Pitch Gains */
   1510 int WebRtcIsac_DecodePitchGain(Bitstr* streamdata,
   1511                                WebRtc_Word16* PitchGains_Q12) {
   1512   int index_comb, err;
   1513   const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1];
   1514 
   1515   /* Entropy decoding of quantization indices */
   1516   *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
   1517   err = WebRtcIsac_DecHistBisectMulti(&index_comb, streamdata,
   1518                                       WebRtcIsac_kQPitchGainCdf_ptr,
   1519                                       WebRtcIsac_kQCdfTableSizeGain, 1);
   1520   /* Error check, Q_mean_Gain.. tables are of size 144 */
   1521   if ((err < 0) || (index_comb < 0) || (index_comb > 144)) {
   1522     return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN;
   1523   }
   1524   /* De-quantize back to pitch gains by table look-up. */
   1525   PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb];
   1526   PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb];
   1527   PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb];
   1528   PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb];
   1529   return 0;
   1530 }
   1531 
   1532 
   1533 /* Quantize & code Pitch Gains. */
   1534 void WebRtcIsac_EncodePitchGain(WebRtc_Word16* PitchGains_Q12,
   1535                                 Bitstr* streamdata,
   1536                                 ISAC_SaveEncData_t* encData) {
   1537   int k, j;
   1538   double C;
   1539   double S[PITCH_SUBFRAMES];
   1540   int index[3];
   1541   int index_comb;
   1542   const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1];
   1543   double PitchGains[PITCH_SUBFRAMES] = {0, 0, 0, 0};
   1544 
   1545   /* Take the asin. */
   1546   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1547     PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
   1548     S[k] = asin(PitchGains[k]);
   1549   }
   1550 
   1551   /* Find quantization index; only for the first three
   1552    * transform coefficients. */
   1553   for (k = 0; k < 3; k++) {
   1554     /*  transform */
   1555     C = 0.0;
   1556     for (j = 0; j < PITCH_SUBFRAMES; j++) {
   1557       C += WebRtcIsac_kTransform[k][j] * S[j];
   1558     }
   1559     /* Quantize */
   1560     index[k] = WebRtcIsac_lrint(C / PITCH_GAIN_STEPSIZE);
   1561 
   1562     /* Check that the index is not outside the boundaries of the table. */
   1563     if (index[k] < WebRtcIsac_kIndexLowerLimitGain[k]) {
   1564       index[k] = WebRtcIsac_kIndexLowerLimitGain[k];
   1565     } else if (index[k] > WebRtcIsac_kIndexUpperLimitGain[k]) {
   1566       index[k] = WebRtcIsac_kIndexUpperLimitGain[k];
   1567     }
   1568     index[k] -= WebRtcIsac_kIndexLowerLimitGain[k];
   1569   }
   1570 
   1571   /* Calculate unique overall index. */
   1572   index_comb = WebRtcIsac_kIndexMultsGain[0] * index[0] +
   1573       WebRtcIsac_kIndexMultsGain[1] * index[1] + index[2];
   1574 
   1575   /* unquantize back to pitch gains by table look-up */
   1576   PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb];
   1577   PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb];
   1578   PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb];
   1579   PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb];
   1580 
   1581   /* entropy coding of quantization pitch gains */
   1582   *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
   1583   WebRtcIsac_EncHistMulti(streamdata, &index_comb,
   1584                           WebRtcIsac_kQPitchGainCdf_ptr, 1);
   1585   encData->pitchGain_index[encData->startIdx] = index_comb;
   1586 }
   1587 
   1588 
   1589 
   1590 /* Pitch LAG */
   1591 /* Decode & de-quantize Pitch Lags. */
   1592 int WebRtcIsac_DecodePitchLag(Bitstr* streamdata, WebRtc_Word16* PitchGain_Q12,
   1593                               double* PitchLags) {
   1594   int k, err;
   1595   double StepSize;
   1596   double C;
   1597   int index[PITCH_SUBFRAMES];
   1598   double mean_gain;
   1599   const double* mean_val2, *mean_val3, *mean_val4;
   1600   const WebRtc_Word16* lower_limit;
   1601   const WebRtc_UWord16* init_index;
   1602   const WebRtc_UWord16* cdf_size;
   1603   const WebRtc_UWord16** cdf;
   1604   double PitchGain[4] = {0, 0, 0, 0};
   1605 
   1606   /* compute mean pitch gain */
   1607   mean_gain = 0.0;
   1608   for (k = 0; k < 4; k++) {
   1609     PitchGain[k] = ((float)PitchGain_Q12[k]) / 4096;
   1610     mean_gain += PitchGain[k];
   1611   }
   1612   mean_gain /= 4.0;
   1613 
   1614   /* voicing classification. */
   1615   if (mean_gain < 0.2) {
   1616     StepSize = WebRtcIsac_kQPitchLagStepsizeLo;
   1617     cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
   1618     cdf_size = WebRtcIsac_kQPitchLagCdfSizeLo;
   1619     mean_val2 = WebRtcIsac_kQMeanLag2Lo;
   1620     mean_val3 = WebRtcIsac_kQMeanLag3Lo;
   1621     mean_val4 = WebRtcIsac_kQMeanLag4Lo;
   1622     lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo;
   1623     init_index = WebRtcIsac_kQInitIndexLagLo;
   1624   } else if (mean_gain < 0.4) {
   1625     StepSize = WebRtcIsac_kQPitchLagStepsizeMid;
   1626     cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
   1627     cdf_size = WebRtcIsac_kQPitchLagCdfSizeMid;
   1628     mean_val2 = WebRtcIsac_kQMeanLag2Mid;
   1629     mean_val3 = WebRtcIsac_kQMeanLag3Mid;
   1630     mean_val4 = WebRtcIsac_kQMeanLag4Mid;
   1631     lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid;
   1632     init_index = WebRtcIsac_kQInitIndexLagMid;
   1633   } else {
   1634     StepSize = WebRtcIsac_kQPitchLagStepsizeHi;
   1635     cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
   1636     cdf_size = WebRtcIsac_kQPitchLagCdfSizeHi;
   1637     mean_val2 = WebRtcIsac_kQMeanLag2Hi;
   1638     mean_val3 = WebRtcIsac_kQMeanLag3Hi;
   1639     mean_val4 = WebRtcIsac_kQMeanLag4Hi;
   1640     lower_limit = WebRtcIsac_kQindexLowerLimitLagHi;
   1641     init_index = WebRtcIsac_kQInitIndexLagHi;
   1642   }
   1643 
   1644   /* Entropy decoding of quantization indices. */
   1645   err = WebRtcIsac_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1);
   1646   if ((err < 0) || (index[0] < 0)) {
   1647     return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
   1648   }
   1649   err = WebRtcIsac_DecHistOneStepMulti(index + 1, streamdata, cdf + 1,
   1650                                        init_index, 3);
   1651   if (err < 0) {
   1652     return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
   1653   }
   1654 
   1655   /* Unquantize back to transform coefficients and do the inverse transform:
   1656    * S = T'*C. */
   1657   C = (index[0] + lower_limit[0]) * StepSize;
   1658   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1659     PitchLags[k] = WebRtcIsac_kTransformTranspose[k][0] * C;
   1660   }
   1661   C = mean_val2[index[1]];
   1662   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1663     PitchLags[k] += WebRtcIsac_kTransformTranspose[k][1] * C;
   1664   }
   1665   C = mean_val3[index[2]];
   1666   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1667     PitchLags[k] += WebRtcIsac_kTransformTranspose[k][2] * C;
   1668   }
   1669   C = mean_val4[index[3]];
   1670   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1671     PitchLags[k] += WebRtcIsac_kTransformTranspose[k][3] * C;
   1672   }
   1673   return 0;
   1674 }
   1675 
   1676 
   1677 
   1678 /* Quantize & code pitch lags. */
   1679 void WebRtcIsac_EncodePitchLag(double* PitchLags, WebRtc_Word16* PitchGain_Q12,
   1680                                Bitstr* streamdata,
   1681                                ISAC_SaveEncData_t* encData) {
   1682   int k, j;
   1683   double StepSize;
   1684   double C;
   1685   int index[PITCH_SUBFRAMES];
   1686   double mean_gain;
   1687   const double* mean_val2, *mean_val3, *mean_val4;
   1688   const WebRtc_Word16* lower_limit, *upper_limit;
   1689   const WebRtc_UWord16** cdf;
   1690   double PitchGain[4] = {0, 0, 0, 0};
   1691 
   1692   /* compute mean pitch gain */
   1693   mean_gain = 0.0;
   1694   for (k = 0; k < 4; k++) {
   1695     PitchGain[k] = ((float)PitchGain_Q12[k]) / 4096;
   1696     mean_gain += PitchGain[k];
   1697   }
   1698   mean_gain /= 4.0;
   1699 
   1700   /* Save data for creation of multiple bit streams */
   1701   encData->meanGain[encData->startIdx] = mean_gain;
   1702 
   1703   /* Voicing classification. */
   1704   if (mean_gain < 0.2) {
   1705     StepSize = WebRtcIsac_kQPitchLagStepsizeLo;
   1706     cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
   1707     mean_val2 = WebRtcIsac_kQMeanLag2Lo;
   1708     mean_val3 = WebRtcIsac_kQMeanLag3Lo;
   1709     mean_val4 = WebRtcIsac_kQMeanLag4Lo;
   1710     lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo;
   1711     upper_limit = WebRtcIsac_kQIndexUpperLimitLagLo;
   1712   } else if (mean_gain < 0.4) {
   1713     StepSize = WebRtcIsac_kQPitchLagStepsizeMid;
   1714     cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
   1715     mean_val2 = WebRtcIsac_kQMeanLag2Mid;
   1716     mean_val3 = WebRtcIsac_kQMeanLag3Mid;
   1717     mean_val4 = WebRtcIsac_kQMeanLag4Mid;
   1718     lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid;
   1719     upper_limit = WebRtcIsac_kQIndexUpperLimitLagMid;
   1720   } else {
   1721     StepSize = WebRtcIsac_kQPitchLagStepsizeHi;
   1722     cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
   1723     mean_val2 = WebRtcIsac_kQMeanLag2Hi;
   1724     mean_val3 = WebRtcIsac_kQMeanLag3Hi;
   1725     mean_val4 = WebRtcIsac_kQMeanLag4Hi;
   1726     lower_limit = WebRtcIsac_kQindexLowerLimitLagHi;
   1727     upper_limit = WebRtcIsac_kQindexUpperLimitLagHi;
   1728   }
   1729 
   1730   /* find quantization index */
   1731   for (k = 0; k < 4; k++) {
   1732     /*  transform */
   1733     C = 0.0;
   1734     for (j = 0; j < PITCH_SUBFRAMES; j++) {
   1735       C += WebRtcIsac_kTransform[k][j] * PitchLags[j];
   1736     }
   1737     /* quantize */
   1738     index[k] = WebRtcIsac_lrint(C / StepSize);
   1739 
   1740     /* check that the index is not outside the boundaries of the table */
   1741     if (index[k] < lower_limit[k]) {
   1742       index[k] = lower_limit[k];
   1743     } else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; {
   1744       index[k] -= lower_limit[k];
   1745     }
   1746     /* Save data for creation of multiple bit streams */
   1747     encData->pitchIndex[PITCH_SUBFRAMES * encData->startIdx + k] = index[k];
   1748   }
   1749 
   1750   /* Un-quantize back to transform coefficients and do the inverse transform:
   1751    * S = T'*C */
   1752   C = (index[0] + lower_limit[0]) * StepSize;
   1753   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1754     PitchLags[k] = WebRtcIsac_kTransformTranspose[k][0] * C;
   1755   }
   1756   C = mean_val2[index[1]];
   1757   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1758     PitchLags[k] += WebRtcIsac_kTransformTranspose[k][1] * C;
   1759   }
   1760   C = mean_val3[index[2]];
   1761   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1762     PitchLags[k] += WebRtcIsac_kTransformTranspose[k][2] * C;
   1763   }
   1764   C = mean_val4[index[3]];
   1765   for (k = 0; k < PITCH_SUBFRAMES; k++) {
   1766     PitchLags[k] += WebRtcIsac_kTransformTranspose[k][3] * C;
   1767   }
   1768   /* entropy coding of quantization pitch lags */
   1769   WebRtcIsac_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES);
   1770 }
   1771 
   1772 
   1773 
   1774 /* Routines for in-band signaling of bandwidth estimation */
   1775 /* Histograms based on uniform distribution of indices */
   1776 /* Move global variables later! */
   1777 
   1778 
   1779 /* cdf array for frame length indicator */
   1780 const WebRtc_UWord16 WebRtcIsac_kFrameLengthCdf[4] = {
   1781     0, 21845, 43690, 65535 };
   1782 
   1783 /* pointer to cdf array for frame length indicator */
   1784 const WebRtc_UWord16* WebRtcIsac_kFrameLengthCdf_ptr[1] = {
   1785     WebRtcIsac_kFrameLengthCdf };
   1786 
   1787 /* initial cdf index for decoder of frame length indicator */
   1788 const WebRtc_UWord16 WebRtcIsac_kFrameLengthInitIndex[1] = { 1 };
   1789 
   1790 
   1791 int WebRtcIsac_DecodeFrameLen(Bitstr* streamdata, WebRtc_Word16* framesamples) {
   1792   int frame_mode, err;
   1793   err = 0;
   1794   /* entropy decoding of frame length [1:30ms,2:60ms] */
   1795   err = WebRtcIsac_DecHistOneStepMulti(&frame_mode, streamdata,
   1796                                        WebRtcIsac_kFrameLengthCdf_ptr,
   1797                                        WebRtcIsac_kFrameLengthInitIndex, 1);
   1798   if (err < 0)
   1799     return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH;
   1800 
   1801   switch (frame_mode) {
   1802     case 1:
   1803       *framesamples = 480; /* 30ms */
   1804       break;
   1805     case 2:
   1806       *framesamples = 960; /* 60ms */
   1807       break;
   1808     default:
   1809       err = -ISAC_DISALLOWED_FRAME_MODE_DECODER;
   1810   }
   1811   return err;
   1812 }
   1813 
   1814 int WebRtcIsac_EncodeFrameLen(WebRtc_Word16 framesamples, Bitstr* streamdata) {
   1815   int frame_mode, status;
   1816 
   1817   status = 0;
   1818   frame_mode = 0;
   1819   /* entropy coding of frame length [1:480 samples,2:960 samples] */
   1820   switch (framesamples) {
   1821     case 480:
   1822       frame_mode = 1;
   1823       break;
   1824     case 960:
   1825       frame_mode = 2;
   1826       break;
   1827     default:
   1828       status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER;
   1829   }
   1830 
   1831   if (status < 0)
   1832     return status;
   1833 
   1834   WebRtcIsac_EncHistMulti(streamdata, &frame_mode,
   1835                           WebRtcIsac_kFrameLengthCdf_ptr, 1);
   1836   return status;
   1837 }
   1838 
   1839 /* cdf array for estimated bandwidth */
   1840 static const WebRtc_UWord16 kBwCdf[25] = {
   1841     0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037,
   1842     32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074,
   1843     62804, 65535 };
   1844 
   1845 /* pointer to cdf array for estimated bandwidth */
   1846 static const WebRtc_UWord16* kBwCdfPtr[1] = { kBwCdf };
   1847 
   1848 /* initial cdf index for decoder of estimated bandwidth*/
   1849 static const WebRtc_UWord16 kBwInitIndex[1] = { 7 };
   1850 
   1851 
   1852 int WebRtcIsac_DecodeSendBW(Bitstr* streamdata, WebRtc_Word16* BWno) {
   1853   int BWno32, err;
   1854 
   1855   /* entropy decoding of sender's BW estimation [0..23] */
   1856   err = WebRtcIsac_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr,
   1857                                        kBwInitIndex, 1);
   1858   if (err < 0) {
   1859     return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH;
   1860   }
   1861   *BWno = (WebRtc_Word16)BWno32;
   1862   return err;
   1863 }
   1864 
   1865 void WebRtcIsac_EncodeReceiveBw(int* BWno, Bitstr* streamdata) {
   1866   /* entropy encoding of receiver's BW estimation [0..23] */
   1867   WebRtcIsac_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1);
   1868 }
   1869 
   1870 
   1871 /* estimate code length of LPC Coef */
   1872 void WebRtcIsac_TranscodeLPCCoef(double* LPCCoef_lo, double* LPCCoef_hi,
   1873                                  int* index_g) {
   1874   int j, k, n, pos, pos2, posg, offsg, offs2;
   1875   int index_ovr_g[KLT_ORDER_GAIN];
   1876   double tmpcoeffs_g[KLT_ORDER_GAIN];
   1877   double tmpcoeffs2_g[KLT_ORDER_GAIN];
   1878   double sum;
   1879 
   1880   /* log gains, mean removal and scaling */
   1881   posg = 0;
   1882   for (k = 0; k < SUBFRAMES; k++) {
   1883     tmpcoeffs_g[posg] = log(LPCCoef_lo[(LPC_LOBAND_ORDER + 1) * k]);
   1884     tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
   1885     tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
   1886     posg++;
   1887     tmpcoeffs_g[posg] = log(LPCCoef_hi[(LPC_HIBAND_ORDER + 1) * k]);
   1888     tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
   1889     tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
   1890     posg++;
   1891   }
   1892 
   1893   /* KLT  */
   1894 
   1895   /* Left transform. */
   1896   offsg = 0;
   1897   for (j = 0; j < SUBFRAMES; j++) {
   1898     posg = offsg;
   1899     for (k = 0; k < LPC_GAIN_ORDER; k++) {
   1900       sum = 0;
   1901       pos = offsg;
   1902       pos2 = k;
   1903       for (n = 0; n < LPC_GAIN_ORDER; n++) {
   1904         sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2];
   1905         pos2 += LPC_GAIN_ORDER;
   1906       }
   1907       tmpcoeffs2_g[posg++] = sum;
   1908     }
   1909     offsg += LPC_GAIN_ORDER;
   1910   }
   1911 
   1912   /* Right transform. */
   1913   offsg = 0;
   1914   offs2 = 0;
   1915   for (j = 0; j < SUBFRAMES; j++) {
   1916     posg = offsg;
   1917     for (k = 0; k < LPC_GAIN_ORDER; k++) {
   1918       sum = 0;
   1919       pos = k;
   1920       pos2 = offs2;
   1921       for (n = 0; n < SUBFRAMES; n++) {
   1922         sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2++];
   1923         pos += LPC_GAIN_ORDER;
   1924       }
   1925       tmpcoeffs_g[posg++] = sum;
   1926     }
   1927     offs2 += SUBFRAMES;
   1928     offsg += LPC_GAIN_ORDER;
   1929   }
   1930 
   1931 
   1932   /* quantize coefficients */
   1933   for (k = 0; k < KLT_ORDER_GAIN; k++) {
   1934     /* Get index. */
   1935     pos2 = WebRtcIsac_lrint(tmpcoeffs_g[k] / KLT_STEPSIZE);
   1936     index_g[k] = (pos2) + WebRtcIsac_kQKltQuantMinGain[k];
   1937     if (index_g[k] < 0) {
   1938       index_g[k] = 0;
   1939     } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) {
   1940       index_g[k] = WebRtcIsac_kQKltMaxIndGain[k];
   1941     }
   1942     index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k];
   1943 
   1944     /* find quantization levels for coefficients */
   1945     tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]];
   1946   }
   1947 }
   1948 
   1949 
   1950 /* Decode & de-quantize LPC Coefficients. */
   1951 int WebRtcIsac_DecodeLpcCoefUB(Bitstr* streamdata, double* lpcVecs,
   1952                                double* percepFilterGains,
   1953                                WebRtc_Word16 bandwidth) {
   1954   int  index_s[KLT_ORDER_SHAPE];
   1955 
   1956   double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
   1957   int err;
   1958 
   1959   /* Entropy decoding of quantization indices. */
   1960   switch (bandwidth) {
   1961     case isac12kHz: {
   1962       err = WebRtcIsac_DecHistOneStepMulti(
   1963           index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb12,
   1964           WebRtcIsac_kLpcShapeEntropySearchUb12, UB_LPC_ORDER *
   1965           UB_LPC_VEC_PER_FRAME);
   1966       break;
   1967     }
   1968     case isac16kHz: {
   1969       err = WebRtcIsac_DecHistOneStepMulti(
   1970           index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb16,
   1971           WebRtcIsac_kLpcShapeEntropySearchUb16, UB_LPC_ORDER *
   1972           UB16_LPC_VEC_PER_FRAME);
   1973       break;
   1974     }
   1975     default:
   1976       return -1;
   1977   }
   1978 
   1979   if (err < 0) {
   1980     return err;
   1981   }
   1982 
   1983   WebRtcIsac_DequantizeLpcParam(index_s, lpcVecs, bandwidth);
   1984   WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth);
   1985   WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth);
   1986   WebRtcIsac_AddLarMean(lpcVecs, bandwidth);
   1987   WebRtcIsac_DecodeLpcGainUb(percepFilterGains, streamdata);
   1988 
   1989   if (bandwidth == isac16kHz) {
   1990     /* Decode another set of Gains. */
   1991     WebRtcIsac_DecodeLpcGainUb(&percepFilterGains[SUBFRAMES], streamdata);
   1992   }
   1993   return 0;
   1994 }
   1995 
   1996 WebRtc_Word16 WebRtcIsac_EncodeBandwidth(enum ISACBandwidth bandwidth,
   1997                                          Bitstr* streamData) {
   1998   int bandwidthMode;
   1999   switch (bandwidth) {
   2000     case isac12kHz: {
   2001       bandwidthMode = 0;
   2002       break;
   2003     }
   2004     case isac16kHz: {
   2005       bandwidthMode = 1;
   2006       break;
   2007     }
   2008     default:
   2009       return -ISAC_DISALLOWED_ENCODER_BANDWIDTH;
   2010   }
   2011   WebRtcIsac_EncHistMulti(streamData, &bandwidthMode, kOneBitEqualProbCdf_ptr,
   2012                           1);
   2013   return 0;
   2014 }
   2015 
   2016 WebRtc_Word16 WebRtcIsac_DecodeBandwidth(Bitstr* streamData,
   2017                                          enum ISACBandwidth* bandwidth) {
   2018   int bandwidthMode;
   2019   if (WebRtcIsac_DecHistOneStepMulti(&bandwidthMode, streamData,
   2020                                      kOneBitEqualProbCdf_ptr,
   2021                                      kOneBitEqualProbInitIndex, 1) < 0) {
   2022     return -ISAC_RANGE_ERROR_DECODE_BANDWITH;
   2023   }
   2024   switch (bandwidthMode) {
   2025     case 0: {
   2026       *bandwidth = isac12kHz;
   2027       break;
   2028     }
   2029     case 1: {
   2030       *bandwidth = isac16kHz;
   2031       break;
   2032     }
   2033     default:
   2034       return -ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER;
   2035   }
   2036   return 0;
   2037 }
   2038 
   2039 WebRtc_Word16 WebRtcIsac_EncodeJitterInfo(WebRtc_Word32 jitterIndex,
   2040                                           Bitstr* streamData) {
   2041   /* This is to avoid LINUX warning until we change 'int' to 'Word32'. */
   2042   int intVar;
   2043 
   2044   if ((jitterIndex < 0) || (jitterIndex > 1)) {
   2045     return -1;
   2046   }
   2047   intVar = (int)(jitterIndex);
   2048   /* Use the same CDF table as for bandwidth
   2049    * both take two values with equal probability.*/
   2050   WebRtcIsac_EncHistMulti(streamData, &intVar, kOneBitEqualProbCdf_ptr, 1);
   2051   return 0;
   2052 }
   2053 
   2054 WebRtc_Word16 WebRtcIsac_DecodeJitterInfo(Bitstr* streamData,
   2055                                           WebRtc_Word32* jitterInfo) {
   2056   int intVar;
   2057   /* Use the same CDF table as for bandwidth
   2058    * both take two values with equal probability. */
   2059   if (WebRtcIsac_DecHistOneStepMulti(&intVar, streamData,
   2060                                      kOneBitEqualProbCdf_ptr,
   2061                                      kOneBitEqualProbInitIndex, 1) < 0) {
   2062     return -ISAC_RANGE_ERROR_DECODE_BANDWITH;
   2063   }
   2064   *jitterInfo = (WebRtc_Word16)(intVar);
   2065   return 0;
   2066 }
   2067