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