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
37static const WebRtc_UWord16 kLpcVecPerSegmentUb12 = 5;
38static const WebRtc_UWord16 kLpcVecPerSegmentUb16 = 4;
39
40/* CDF array for encoder bandwidth (12 vs 16 kHz) indicator. */
41static const WebRtc_UWord16 kOneBitEqualProbCdf[3] = {
42    0, 32768, 65535 };
43
44/* Pointer to cdf array for encoder bandwidth (12 vs 16 kHz) indicator. */
45static 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 */
52static const WebRtc_UWord16 kOneBitEqualProbInitIndex[1] = { 1 };
53
54
55static const int kIsSWB12 = 1;
56
57/* compute correlation from power spectrum */
58static 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 */
95static 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. */
177static 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 */
251static 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 */
273int 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
394int 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 */
595void 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 */
613void 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 */
635void 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
643void 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
653void 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
685WebRtc_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
719void 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 */
752void 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
780int 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
794WebRtc_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 */
852int 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. */
1002void 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
1162void 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
1184WebRtc_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
1239void 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
1377void 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
1393void 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
1405WebRtc_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 */
1425int 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 */
1445void 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 */
1469int 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 */
1486int 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 */
1510int 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. */
1534void 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. */
1592int 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. */
1679void 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 */
1780const WebRtc_UWord16 WebRtcIsac_kFrameLengthCdf[4] = {
1781    0, 21845, 43690, 65535 };
1782
1783/* pointer to cdf array for frame length indicator */
1784const WebRtc_UWord16* WebRtcIsac_kFrameLengthCdf_ptr[1] = {
1785    WebRtcIsac_kFrameLengthCdf };
1786
1787/* initial cdf index for decoder of frame length indicator */
1788const WebRtc_UWord16 WebRtcIsac_kFrameLengthInitIndex[1] = { 1 };
1789
1790
1791int 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
1814int 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 */
1840static 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 */
1846static const WebRtc_UWord16* kBwCdfPtr[1] = { kBwCdf };
1847
1848/* initial cdf index for decoder of estimated bandwidth*/
1849static const WebRtc_UWord16 kBwInitIndex[1] = { 7 };
1850
1851
1852int 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
1865void 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 */
1872void 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. */
1951int 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
1996WebRtc_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
2016WebRtc_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
2039WebRtc_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
2054WebRtc_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