LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/source - entropy_coding.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1018 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 42 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13