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