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

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

Generated by: LCOV version 1.13