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