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