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