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