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