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