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