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