2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
14 * This file contains all functions used to arithmetically
15 * encode the iSAC bistream.
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"
28 #include "signal_processing_library.h"
31 * Eenumerations for arguments to functions WebRtcIsacfix_MatrixProduct1()
32 * and WebRtcIsacfix_MatrixProduct2().
35 enum matrix_index_factor {
38 kTIndexFactor3 = SUBFRAMES,
39 kTIndexFactor4 = LPC_SHAPE_ORDER
42 enum matrix_index_step {
44 kTIndexStep2 = SUBFRAMES,
45 kTIndexStep3 = LPC_SHAPE_ORDER
48 enum matrixprod_loop_count {
49 kTLoopCount1 = SUBFRAMES,
51 kTLoopCount3 = LPC_SHAPE_ORDER
54 enum matrix1_shift_value {
60 enum matrixprod_init_case {
66 This function implements the fix-point correspondant function to lrint.
68 FLP: (int32_t)floor(flt+.499999999999)
69 FIP: (fixVal+roundVal)>>qDomain
71 where roundVal = 2^(qDomain-1) = 1<<(qDomain-1)
74 static __inline int32_t CalcLrIntQ(int32_t fixVal, int16_t qDomain) {
78 roundVal = WEBRTC_SPL_LSHIFT_W32((int32_t)1, qDomain-1);
79 intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain);
85 __inline uint32_t stepwise(int32_t dinQ10) {
87 int32_t ind, diQ10, dtQ10;
90 if (diQ10 < DPMIN_Q10)
92 if (diQ10 >= DPMAX_Q10)
93 diQ10 = DPMAX_Q10 - 1;
95 dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */
96 /* ind = (dtQ10 * 5) >> 10; */ /* 2^10 / 5 = 0.2 in Q10 */
99 /* return rpointsFIX_Q10[ind];
104 /* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */
105 /* The input argument X to logN(X) is 2^17 times higher than the
106 input floating point argument Y to log(Y), since the X value
107 is a Q17 value. This can be compensated for after the call, by
108 subraction a value Z for each Q-step. One Q-step means that
109 X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
110 177.445678 should be subtracted (since logN() returns a Q8 value).
111 For a X value in Q17, the value 177.445678*17 = 3017 should be
113 static int16_t CalcLogN(int32_t arg) {
114 int16_t zeros, log2, frac, logN;
116 zeros=WebRtcSpl_NormU32(arg);
117 frac=(int16_t)WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_LSHIFT_W32(arg, zeros)&0x7FFFFFFF, 23);
118 log2=(int16_t)(WEBRTC_SPL_LSHIFT_W32(31-zeros, 8)+frac); // log2(x) in Q8
119 logN=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(log2,22713,15); //Q8*Q15 log(2) = 0.693147 = 22713 in Q15
120 logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x.
127 expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695
130 Output: Q17 (int32_t)
132 a = log2(e) = log2(exp(1)) ~= 1.442695 ==> a = 23637 in Q14 (1.442688)
133 To this value, 700 is added or subtracted in order to get an average error
134 nearer zero, instead of always same-sign.
137 static int32_t CalcExpN(int16_t x) {
138 int16_t ax, axINT, axFRAC;
143 // ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637-700, 14); //Q8
144 ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8
145 axINT = WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0
147 exp16 = WEBRTC_SPL_LSHIFT_W32(1, axINT); //Q0
148 axFRAC = axFRAC+256; //Q8
149 exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q0*Q8 = Q8
150 exp = WEBRTC_SPL_LSHIFT_W32(exp, 9); //Q17
152 // ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637+700, 14); //Q8
153 ax=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8
155 axINT = 1 + WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0
156 axFRAC = 0x00FF - (ax&0x00FF);
157 exp16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15
158 axFRAC = axFRAC+256; //Q8
159 exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23
160 exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17
167 /* compute correlation from power spectrum */
168 static void CalcCorrelation(int32_t *PSpecQ12, int32_t *CorrQ7)
170 int32_t summ[FRAMESAMPLES/8];
171 int32_t diff[FRAMESAMPLES/8];
175 for (k = 0; k < FRAMESAMPLES/8; k++) {
176 summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
177 diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
181 for (n = 0; n < FRAMESAMPLES/8; n++)
185 for (k = 0; k < AR_ORDER; k += 2) {
187 for (n = 0; n < FRAMESAMPLES/8; n++)
188 sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9);
192 for (k=1; k<AR_ORDER; k+=2) {
194 for (n = 0; n < FRAMESAMPLES/8; n++)
195 sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9);
201 /* compute inverse AR power spectrum */
202 static void CalcInvArSpec(const int16_t *ARCoefQ12,
203 const int32_t gainQ10,
206 int32_t CorrQ11[AR_ORDER+1];
207 int32_t sum, tmpGain;
208 int32_t diffQ16[FRAMESAMPLES/8];
209 const int16_t *CS_ptrQ9;
211 int16_t round, shftVal = 0, sh;
214 for (n = 0; n < AR_ORDER+1; n++)
215 sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */
216 sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */
217 CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
219 /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
221 tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
230 for (k = 1; k < AR_ORDER+1; k++) {
232 for (n = k; n < AR_ORDER+1; n++)
233 sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */
234 sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
235 CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
237 sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
238 for (n = 0; n < FRAMESAMPLES/8; n++)
241 for (k = 1; k < AR_ORDER; k += 2) {
242 for (n = 0; n < FRAMESAMPLES/8; n++)
243 CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2);
246 CS_ptrQ9 = WebRtcIsacfix_kCos[0];
248 /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */
249 sh=WebRtcSpl_NormW32(CorrQ11[1]);
250 if (CorrQ11[1]==0) /* Use next correlation */
251 sh=WebRtcSpl_NormW32(CorrQ11[2]);
258 for (n = 0; n < FRAMESAMPLES/8; n++)
259 diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
260 for (k = 2; k < AR_ORDER; k += 2) {
261 CS_ptrQ9 = WebRtcIsacfix_kCos[k];
262 for (n = 0; n < FRAMESAMPLES/8; n++)
263 diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
266 for (k=0; k<FRAMESAMPLES/8; k++) {
267 CurveQ16[FRAMESAMPLES/4-1 - k] = CurveQ16[k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
268 CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
272 static void CalcRootInvArSpec(const int16_t *ARCoefQ12,
273 const int32_t gainQ10,
276 int32_t CorrQ11[AR_ORDER+1];
277 int32_t sum, tmpGain;
278 int32_t summQ16[FRAMESAMPLES/8];
279 int32_t diffQ16[FRAMESAMPLES/8];
281 const int16_t *CS_ptrQ9;
283 int16_t round, shftVal = 0, sh;
284 int32_t res, in_sqrt, newRes;
287 for (n = 0; n < AR_ORDER+1; n++)
288 sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */
289 sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */
290 CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
292 /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
294 tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
303 for (k = 1; k < AR_ORDER+1; k++) {
305 for (n = k; n < AR_ORDER+1; n++)
306 sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */
307 sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
308 CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
310 sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
311 for (n = 0; n < FRAMESAMPLES/8; n++)
314 for (k = 1; k < (AR_ORDER); k += 2) {
315 for (n = 0; n < FRAMESAMPLES/8; n++)
316 summQ16[n] += ((CorrQ11[k + 1] * WebRtcIsacfix_kCos[k][n]) + 2) >> 2;
319 CS_ptrQ9 = WebRtcIsacfix_kCos[0];
321 /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */
322 sh=WebRtcSpl_NormW32(CorrQ11[1]);
323 if (CorrQ11[1]==0) /* Use next correlation */
324 sh=WebRtcSpl_NormW32(CorrQ11[2]);
331 for (n = 0; n < FRAMESAMPLES/8; n++)
332 diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
333 for (k = 2; k < AR_ORDER; k += 2) {
334 CS_ptrQ9 = WebRtcIsacfix_kCos[k];
335 for (n = 0; n < FRAMESAMPLES/8; n++)
336 diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
339 in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal);
341 /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */
342 res = WEBRTC_SPL_LSHIFT_W32(1, WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(in_sqrt), 1));
344 for (k = 0; k < FRAMESAMPLES/8; k++)
346 in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
349 /* make in_sqrt positive to prohibit sqrt of negative values */
353 newRes = (in_sqrt / res + res) >> 1;
357 newRes = (in_sqrt / res + res) >> 1;
358 } while (newRes != res && i-- > 0);
360 CurveQ8[k] = (int16_t)newRes;
362 for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) {
364 in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal);
367 /* make in_sqrt positive to prohibit sqrt of negative values */
371 newRes = (in_sqrt / res + res) >> 1;
375 newRes = (in_sqrt / res + res) >> 1;
376 } while (newRes != res && i-- > 0);
378 CurveQ8[k] = (int16_t)newRes;
385 /* generate array of dither samples in Q7 */
386 static void GenerateDitherQ7(int16_t *bufQ7,
389 int16_t AvgPitchGain_Q12)
392 int16_t dither1_Q7, dither2_Q7, dither_gain_Q14, shft;
394 if (AvgPitchGain_Q12 < 614) /* this threshold should be equal to that in decode_spec() */
396 for (k = 0; k < length-2; k += 3)
398 /* new random unsigned int32_t */
399 seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
401 /* fixed-point dither sample between -64 and 64 (Q7) */
402 dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25); // * 128/4294967295
404 /* new random unsigned int32_t */
405 seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
407 /* fixed-point dither sample between -64 and 64 */
408 dither2_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25);
410 shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15);
413 bufQ7[k] = dither1_Q7;
414 bufQ7[k+1] = dither2_Q7;
419 bufQ7[k] = dither1_Q7;
421 bufQ7[k+2] = dither2_Q7;
426 bufQ7[k+1] = dither1_Q7;
427 bufQ7[k+2] = dither2_Q7;
433 dither_gain_Q14 = (int16_t)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12));
435 /* dither on half of the coefficients */
436 for (k = 0; k < length-1; k += 2)
438 /* new random unsigned int32_t */
439 seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
441 /* fixed-point dither sample between -64 and 64 */
442 dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25);
444 /* dither sample is placed in either even or odd index */
445 shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1); /* either 0 or 1 */
447 bufQ7[k + shft] = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14);
448 bufQ7[k + 1 - shft] = 0;
457 * function to decode the complex spectrum from the bitstream
458 * returns the total number of bytes in the stream
460 int16_t WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata,
463 int16_t AvgPitchGain_Q12)
465 int16_t data[FRAMESAMPLES];
466 int32_t invARSpec2_Q16[FRAMESAMPLES/4];
467 int16_t ARCoefQ12[AR_ORDER+1];
468 int16_t RCQ15[AR_ORDER];
474 /* create dither signal */
475 GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */
477 /* decode model parameters */
478 if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0)
479 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
482 WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
484 if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0)
485 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
487 /* compute inverse AR power spectrum */
488 CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
490 /* arithmetic decoding of spectrum */
491 /* 'data' input and output. Input = Dither */
492 len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (int16_t)FRAMESAMPLES);
495 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
497 /* subtract dither and scale down spectral samples with low SNR */
498 if (AvgPitchGain_Q12 <= 614)
500 for (k = 0; k < FRAMESAMPLES; k += 4)
502 gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((int32_t)30, 10),
503 (int16_t)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (uint32_t)2195456, 16));
504 *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
505 *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
506 *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
507 *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
512 for (k = 0; k < FRAMESAMPLES; k += 4)
514 gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((int32_t)36, 10),
515 (int16_t)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (uint32_t)2654208, 16));
516 *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
517 *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
518 *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
519 *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
527 int WebRtcIsacfix_EncodeSpec(const int16_t *fr,
529 Bitstr_enc *streamdata,
530 int16_t AvgPitchGain_Q12)
532 int16_t dataQ7[FRAMESAMPLES];
533 int32_t PSpec[FRAMESAMPLES/4];
534 uint16_t invARSpecQ8[FRAMESAMPLES/4];
535 int32_t CorrQ7[AR_ORDER+1];
536 int32_t CorrQ7_norm[AR_ORDER+1];
537 int16_t RCQ15[AR_ORDER];
538 int16_t ARCoefQ12[AR_ORDER+1];
548 /* create dither_float signal */
549 GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12);
551 /* add dither and quantize, and compute power spectrum */
552 /* Vector dataQ7 contains Dither in Q7 */
553 for (k = 0; k < FRAMESAMPLES; k += 4)
555 val = ((*fr++ + dataQ7[k] + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */
556 dataQ7[k] = val; /* New value in Data */
557 sum = WEBRTC_SPL_UMUL(val, val);
559 val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */
560 dataQ7[k+1] = val; /* New value in Data */
561 sum += WEBRTC_SPL_UMUL(val, val);
563 val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */
564 dataQ7[k+2] = val; /* New value in Data */
565 sum += WEBRTC_SPL_UMUL(val, val);
567 val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */
568 dataQ7[k+3] = val; /* New value in Data */
569 sum += WEBRTC_SPL_UMUL(val, val);
571 PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2);
574 /* compute correlation from power spectrum */
575 CalcCorrelation(PSpec, CorrQ7);
578 /* find AR coefficients */
579 /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */
580 lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
583 for (k=0; k<AR_ORDER+1; k++)
584 CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft);
586 for (k=0; k<AR_ORDER+1; k++)
587 CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft);
590 /* find RC coefficients */
591 WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15);
593 /* quantize & code RC Coef */
594 status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata);
599 /* RC -> AR coefficients */
600 WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
602 /* compute ARCoef' * Corr * ARCoef in Q19 */
604 for (j = 0; j <= AR_ORDER; j++) {
605 for (n = 0; n <= j; n++)
606 nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3);
607 for (n = j+1; n <= AR_ORDER; n++)
608 nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3);
612 nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft);
614 nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft);
617 gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */
619 gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2);
621 /* quantize & code gain2_Q10 */
622 if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata))
625 /* compute inverse AR magnitude spectrum */
626 CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8);
629 /* arithmetic coding of spectrum */
630 status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (int16_t)FRAMESAMPLES);
638 /* Matlab's LAR definition */
639 static void Rc2LarFix(const int16_t *rcQ15, int32_t *larQ17, int16_t order) {
643 This is a piece-wise implemenetation of a rc2lar-function (all values in the comment
644 are Q15 values and are based on [0 24956/32768 30000/32768 32500/32768], i.e.
645 [0.76159667968750 0.91552734375000 0.99182128906250]
647 x0 x1 a k x0(again) b
648 ==================================================================================
649 0.00 0.76: 0 2.625997508581 0 0
650 0.76 0.91: 2.000012018559 7.284502668663 0.761596679688 -3.547841027073
651 0.91 0.99: 3.121320351712 31.115835041229 0.915527343750 -25.366077452148
652 0.99 1.00: 5.495270168700 686.663805654056 0.991821289063 -675.552510708011
654 The implementation is y(x)= a + (x-x0)*k, but this can be simplified to
656 y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k
658 akx=[0 2.625997508581 0
659 2.000012018559 7.284502668663 0.761596679688
660 3.121320351712 31.115835041229 0.915527343750
661 5.495270168700 686.663805654056 0.991821289063];
663 b = akx(:,1) - akx(:,3).*akx(:,2)
676 for (k = 0; k < order; k++) {
678 rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15
680 /* Calculate larAbsQ17 in Q17 from rc in Q15 */
682 if (rc<24956) { //0.7615966 in Q15
683 // (Q15*Q13)>>11 = Q17
684 larAbsQ17 = WEBRTC_SPL_MUL_16_16_RSFT(rc, 21512, 11);
685 } else if (rc<30000) { //0.91552734375 in Q15
686 // Q17 + (Q15*Q12)>>10 = Q17
687 larAbsQ17 = -465024 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 29837, 10);
688 } else if (rc<32500) { //0.99182128906250 in Q15
689 // Q17 + (Q15*Q10)>>8 = Q17
690 larAbsQ17 = -3324784 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 31863, 8);
692 // Q17 + (Q15*Q5)>>3 = Q17
693 larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3);
697 larQ17[k] = larAbsQ17;
699 larQ17[k] = -larAbsQ17;
705 static void Lar2RcFix(const int32_t *larQ17, int16_t *rcQ15, int16_t order) {
708 This is a piece-wise implemenetation of a lar2rc-function
709 See comment in Rc2LarFix() about details.
716 for (k = 0; k < order; k++) {
718 larAbsQ11 = (int16_t) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11
720 if (larAbsQ11<4097) { //2.000012018559 in Q11
722 rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12);
723 } else if (larAbsQ11<6393) { //3.121320351712 in Q11
724 // (Q11*Q17 + Q13)>>13 = Q15
725 rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13);
726 } else if (larAbsQ11<11255) { //5.495270168700 in Q11
727 // (Q11*Q19 + Q30)>>15 = Q15
728 rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15);
730 // (Q11*Q24>>16 + Q19)>>4 = Q15
731 rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4);
738 rcQ15[k] = (int16_t) rc; // Q15
742 static void Poly2LarFix(int16_t *lowbandQ15,
752 int32_t larQ17[MAX_ORDER]; // Size 7+6 is enough
754 orderTot = (orderLo + orderHi);
756 for (k = 0; k < Nsub; k++) {
758 Rc2LarFix(lowbandQ15, larQ17, orderLo);
760 for (n = 0; n < orderLo; n++)
761 outpQ17[n] = larQ17[n]; //Q17
763 Rc2LarFix(hibandQ15, larQ17, orderHi);
765 for (n = 0; n < orderHi; n++)
766 outpQ17[n + orderLo] = larQ17[n]; //Q17;
769 lowbandQ15 += orderLo;
770 hibandQ15 += orderHi;
775 static void Lar2polyFix(int32_t *larsQ17,
784 int16_t *outplQ15, *outphQ15;
788 orderTot = (orderLo + orderHi);
789 outplQ15 = lowbandQ15;
790 outphQ15 = hibandQ15;
792 for (k = 0; k < Nsub; k++) {
794 /* gains not handled here as in the FLP version */
797 Lar2RcFix(&inpQ17[0], rcQ15, orderLo);
798 for (n = 0; n < orderLo; n++)
799 outplQ15[n] = rcQ15[n]; // Refl. coeffs
802 Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi);
803 for (n = 0; n < orderHi; n++)
804 outphQ15[n] = rcQ15[n]; // Refl. coeffs
813 Function WebRtcIsacfix_MatrixProduct1C() does one form of matrix multiplication.
814 It first shifts input data of one matrix, determines the right indexes for the
815 two matrixes, multiply them, and write the results into an output buffer.
817 Note that two factors (or, multipliers) determine the initialization values of
818 the variable |matrix1_index| in the code. The relationship is
819 |matrix1_index| = |matrix1_index_factor1| * |matrix1_index_factor2|, where
820 |matrix1_index_factor1| is given by the argument while |matrix1_index_factor2|
821 is determined by the value of argument |matrix1_index_init_case|;
822 |matrix1_index_factor2| is the value of the outmost loop counter j (when
823 |matrix1_index_init_case| is 0), or the value of the middle loop counter k (when
824 |matrix1_index_init_case| is non-zero).
826 |matrix0_index| is determined the same way.
829 matrix0[]: matrix0 data in Q15 domain.
830 matrix1[]: matrix1 data.
831 matrix_product[]: output data (matrix product).
832 matrix1_index_factor1: The first of two factors determining the
833 initialization value of matrix1_index.
834 matrix0_index_factor1: The first of two factors determining the
835 initialization value of matrix0_index.
836 matrix1_index_init_case: Case number for selecting the second of two
837 factors determining the initialization value
838 of matrix1_index and matrix0_index.
839 matrix1_index_step: Incremental step for matrix1_index.
840 matrix0_index_step: Incremental step for matrix0_index.
841 inner_loop_count: Maximum count of the inner loop.
842 mid_loop_count: Maximum count of the intermediate loop.
843 shift: Left shift value for matrix1.
845 void WebRtcIsacfix_MatrixProduct1C(const int16_t matrix0[],
846 const int32_t matrix1[],
847 int32_t matrix_product[],
848 const int matrix1_index_factor1,
849 const int matrix0_index_factor1,
850 const int matrix1_index_init_case,
851 const int matrix1_index_step,
852 const int matrix0_index_step,
853 const int inner_loop_count,
854 const int mid_loop_count,
856 int j = 0, k = 0, n = 0;
857 int matrix0_index = 0, matrix1_index = 0, matrix_prod_index = 0;
858 int* matrix0_index_factor2 = &k;
859 int* matrix1_index_factor2 = &j;
860 if (matrix1_index_init_case != 0) {
861 matrix0_index_factor2 = &j;
862 matrix1_index_factor2 = &k;
865 for (j = 0; j < SUBFRAMES; j++) {
866 matrix_prod_index = mid_loop_count * j;
867 for (k = 0; k < mid_loop_count; k++) {
869 matrix0_index = matrix0_index_factor1 * (*matrix0_index_factor2);
870 matrix1_index = matrix1_index_factor1 * (*matrix1_index_factor2);
871 for (n = 0; n < inner_loop_count; n++) {
872 sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index],
873 matrix1[matrix1_index] << shift));
874 matrix0_index += matrix0_index_step;
875 matrix1_index += matrix1_index_step;
877 matrix_product[matrix_prod_index] = sum32;
884 Function WebRtcIsacfix_MatrixProduct2C() returns the product of two matrixes,
885 one of which has two columns. It first has to determine the correct index of
886 the first matrix before doing the actual element multiplication.
889 matrix0[]: A matrix in Q15 domain.
890 matrix1[]: A matrix in Q21 domain.
891 matrix_product[]: Output data in Q17 domain.
892 matrix0_index_factor: A factor determining the initialization value
894 matrix0_index_step: Incremental step for matrix0_index.
896 void WebRtcIsacfix_MatrixProduct2C(const int16_t matrix0[],
897 const int32_t matrix1[],
898 int32_t matrix_product[],
899 const int matrix0_index_factor,
900 const int matrix0_index_step) {
902 int matrix1_index = 0, matrix0_index = 0, matrix_prod_index = 0;
903 for (j = 0; j < SUBFRAMES; j++) {
904 int32_t sum32 = 0, sum32_2 = 0;
906 matrix0_index = matrix0_index_factor * j;
907 for (n = SUBFRAMES; n > 0; n--) {
908 sum32 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index],
909 matrix1[matrix1_index]));
910 sum32_2 += (WEBRTC_SPL_MUL_16_32_RSFT16(matrix0[matrix0_index],
911 matrix1[matrix1_index + 1]));
913 matrix0_index += matrix0_index_step;
915 matrix_product[matrix_prod_index] = sum32 >> 3;
916 matrix_product[matrix_prod_index + 1] = sum32_2 >> 3;
917 matrix_prod_index += 2;
921 int WebRtcIsacfix_DecodeLpc(int32_t *gain_lo_hiQ17,
922 int16_t *LPCCoef_loQ15,
923 int16_t *LPCCoef_hiQ15,
924 Bitstr_dec *streamdata,
927 int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES
930 err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel);
931 if (err<0) // error check
932 return -ISAC_RANGE_ERROR_DECODE_LPC;
934 Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES);
939 /* decode & dequantize LPC Coef */
940 int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata,
942 int32_t *gain_lo_hiQ17,
947 int16_t pos, pos2, posg, poss;
950 int16_t index_QQ[KLT_ORDER_SHAPE];
951 int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN];
952 int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
953 int16_t tmpcoeffs_sQ10[KLT_ORDER_SHAPE];
954 int32_t tmpcoeffs_sQ17[KLT_ORDER_SHAPE];
955 int32_t tmpcoeffs2_sQ18[KLT_ORDER_SHAPE];
962 /* entropy decoding of model number */
963 err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1);
964 if (err<0) // error check
967 /* entropy decoding of quantization indices */
968 err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE);
969 if (err<0) // error check
971 /* find quantization levels for coefficients */
972 for (k=0; k<KLT_ORDER_SHAPE; k++) {
973 tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]];
976 err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN);
977 if (err<0) // error check
979 /* find quantization levels for coefficients */
980 for (k=0; k<KLT_ORDER_GAIN; k++) {
981 tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]];
987 /* left transform */ // Transpose matrix!
988 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1GainQ15[model], tmpcoeffs_gQ17,
989 tmpcoeffs2_gQ21, kTIndexFactor2, kTIndexFactor2,
990 kTInitCase0, kTIndexStep1, kTIndexStep1,
991 kTLoopCount2, kTLoopCount2, kTMatrix1_shift5);
994 for (j=0; j<SUBFRAMES; j++) {
995 for (k=0; k<LPC_SHAPE_ORDER; k++) {
997 pos = LPC_SHAPE_ORDER * j;
998 pos2 = LPC_SHAPE_ORDER * k;
999 for (n=0; n<LPC_SHAPE_ORDER; n++) {
1000 sumQQ += WEBRTC_SPL_MUL_16_16_RSFT(tmpcoeffs_sQ10[pos], WebRtcIsacfix_kT1ShapeQ15[model][pos2], 7); // (Q10*Q15)>>7 = Q18
1004 tmpcoeffs2_sQ18[poss] = sumQQ; //Q18
1009 /* right transform */ // Transpose matrix
1010 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21,
1011 tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2);
1012 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[model],
1013 tmpcoeffs2_sQ18, tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1,
1014 kTInitCase1, kTIndexStep3, kTIndexStep2, kTLoopCount1, kTLoopCount3,
1017 /* scaling, mean addition, and gain restoration */
1019 posg = 0;poss = 0;pos=0;
1020 for (k=0; k<SUBFRAMES; k++) {
1023 sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
1024 sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
1025 sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
1026 gain_lo_hiQ17[gainpos] = sumQQ; //Q17
1030 sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
1031 sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
1032 sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
1033 gain_lo_hiQ17[gainpos] = sumQQ; //Q17
1037 /* lo band LAR coeffs */
1038 for (n=0; n<ORDERLO; n++, pos++, poss++) {
1039 tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16
1040 tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17
1041 LPCCoefQ17[pos] = tmp32;
1044 /* hi band LAR coeffs */
1045 for (n=0; n<ORDERHI; n++, pos++, poss++) {
1046 tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13
1047 tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17
1048 LPCCoefQ17[pos] = tmp32;
1058 /* estimate codel length of LPC Coef */
1059 static int EstCodeLpcCoef(int32_t *LPCCoefQ17,
1060 int32_t *gain_lo_hiQ17,
1063 Bitstr_enc *streamdata,
1064 ISAC_SaveEncData_t* encData,
1065 transcode_obj *transcodingParam) {
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];
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];
1083 /* write LAR coefficients to statistics file */
1084 /* Save data for creation of multiple bitstreams (and transcoding) */
1085 if (encData != NULL) {
1086 for (k=0; k<KLT_ORDER_GAIN; k++) {
1087 encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k];
1091 /* log gains, mean removal and scaling */
1092 posg = 0;poss = 0;pos=0; gainpos=0;
1094 for (k=0; k<SUBFRAMES; k++) {
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
1105 tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
1106 tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
1109 tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
1110 tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
1113 /* lo band LAR coeffs */
1114 for (n=0; n<ORDERLO; n++, poss++, pos++) {
1115 tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17
1116 tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32
1117 tmpcoeffs_sQ17[poss] = tmp32; //Q17
1120 /* hi band LAR coeffs */
1121 for (n=0; n<ORDERHI; n++, poss++, pos++) {
1122 tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17
1123 tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32
1124 tmpcoeffs_sQ17[poss] = tmp32; //Q17
1132 /* left transform */
1135 for (j=0; j<SUBFRAMES; j++) {
1137 sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg],
1138 WebRtcIsacfix_kT1GainQ15[0][0]);
1139 sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1],
1140 WebRtcIsacfix_kT1GainQ15[0][2]);
1141 tmpcoeffs2_gQ21[posg] = sumQQ;
1145 sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg],
1146 WebRtcIsacfix_kT1GainQ15[0][1]);
1147 sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1],
1148 WebRtcIsacfix_kT1GainQ15[0][3]);
1149 tmpcoeffs2_gQ21[posg] = sumQQ;
1155 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17,
1156 tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor1, kTInitCase0,
1157 kTIndexStep1, kTIndexStep3, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1);
1159 /* right transform */
1160 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21,
1161 tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1);
1163 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17,
1164 tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor3, kTInitCase1, kTIndexStep3,
1165 kTIndexStep1, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1);
1167 /* quantize coefficients */
1170 for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
1172 posQQ = WebRtcIsacfix_kSelIndGain[k];
1173 pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
1175 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
1176 if (index_gQQ[k] < 0) {
1179 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
1180 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
1182 index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k];
1183 posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k];
1185 /* Save data for creation of multiple bitstreams */
1186 if (encData != NULL) {
1187 encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k];
1190 /* determine number of bits */
1191 sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11
1195 for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok?
1197 index_sQQ[k] = (int16_t)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok?
1199 if (index_sQQ[k] < 0)
1201 else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k])
1202 index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k];
1203 index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k];
1205 posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k];
1206 sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11
1215 /* entropy coding of model number */
1216 status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1);
1221 /* entropy coding of quantization indices - shape only */
1222 status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
1227 /* Save data for creation of multiple bitstreams */
1228 if (encData != NULL) {
1229 for (k=0; k<KLT_ORDER_SHAPE; k++)
1231 encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k];
1234 /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */
1235 transcodingParam->full = streamdata->full;
1236 transcodingParam->stream_index = streamdata->stream_index;
1237 transcodingParam->streamval = streamdata->streamval;
1238 transcodingParam->W_upper = streamdata->W_upper;
1239 transcodingParam->beforeLastWord = streamdata->stream[streamdata->stream_index-1];
1240 transcodingParam->lastWord = streamdata->stream[streamdata->stream_index];
1242 /* entropy coding of index */
1243 status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
1248 /* find quantization levels for shape coefficients */
1249 for (k=0; k<KLT_ORDER_SHAPE; k++) {
1250 tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]);
1255 /* left transform */ // Transpose matrix!
1256 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17,
1257 tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor4, kTInitCase0,
1258 kTIndexStep1, kTIndexStep1, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1);
1260 /* right transform */ // Transpose matrix
1261 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17,
1262 tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor1, kTInitCase1, kTIndexStep3,
1263 kTIndexStep2, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1);
1265 /* scaling, mean addition, and gain restoration */
1267 for (k=0; k<SUBFRAMES; k++) {
1269 /* lo band LAR coeffs */
1270 for (n=0; n<ORDERLO; n++, pos++, poss++) {
1271 tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16
1272 tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17
1273 LPCCoefQ17[pos] = tmp32;
1276 /* hi band LAR coeffs */
1277 for (n=0; n<ORDERHI; n++, pos++, poss++) {
1278 tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13
1279 tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17
1280 LPCCoefQ17[pos] = tmp32;
1285 //to update tmpcoeffs_gQ17 to the proper state
1286 for (k=0; k<KLT_ORDER_GAIN; k++) {
1287 tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]];
1292 /* find quantization levels for coefficients */
1294 /* left transform */
1297 for (j=0; j<SUBFRAMES; j++) {
1298 // (Q15 * Q17) >> (16 - 1) = Q17; Q17 << 4 = Q21.
1299 sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][0],
1300 tmpcoeffs_gQ17[offsg]) << 1);
1301 sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][1],
1302 tmpcoeffs_gQ17[offsg + 1]) << 1);
1303 tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4);
1306 sumQQ = (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][2],
1307 tmpcoeffs_gQ17[offsg]) << 1);
1308 sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][3],
1309 tmpcoeffs_gQ17[offsg + 1]) << 1);
1310 tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4);
1315 /* right transform */ // Transpose matrix
1316 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21,
1317 tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2);
1319 /* scaling, mean addition, and gain restoration */
1322 for (k=0; k<2*SUBFRAMES; k++) {
1324 sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
1325 sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg];
1326 sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
1327 gain_lo_hiQ17[gainpos] = sumQQ; //Q17
1336 int WebRtcIsacfix_EstCodeLpcGain(int32_t *gain_lo_hiQ17,
1337 Bitstr_enc *streamdata,
1338 ISAC_SaveEncData_t* encData) {
1340 int16_t posQQ, pos2QQ, gainpos;
1342 int16_t index_gQQ[KLT_ORDER_GAIN];
1344 int16_t tmpcoeffs_gQ6[KLT_ORDER_GAIN];
1345 int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN];
1346 int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
1350 /* write LAR coefficients to statistics file */
1351 /* Save data for creation of multiple bitstreams (and transcoding) */
1352 if (encData != NULL) {
1353 for (k=0; k<KLT_ORDER_GAIN; k++) {
1354 encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k];
1358 /* log gains, mean removal and scaling */
1359 posg = 0; gainpos = 0;
1361 for (k=0; k<SUBFRAMES; k++) {
1364 /* The input argument X to logN(X) is 2^17 times higher than the
1365 input floating point argument Y to log(Y), since the X value
1366 is a Q17 value. This can be compensated for after the call, by
1367 subraction a value Z for each Q-step. One Q-step means that
1368 X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
1369 177.445678 should be subtracted (since logN() returns a Q8 value).
1370 For a X value in Q17, the value 177.445678*17 = 3017 should be
1372 tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
1373 tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
1376 tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
1377 tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
1384 /* left transform */
1386 for (j=0; j<SUBFRAMES; j++) {
1388 sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2],
1389 WebRtcIsacfix_kT1GainQ15[0][0]);
1390 sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2 + 1],
1391 WebRtcIsacfix_kT1GainQ15[0][2]);
1392 tmpcoeffs2_gQ21[posg] = sumQQ;
1395 sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2],
1396 WebRtcIsacfix_kT1GainQ15[0][1]);
1397 sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[j * 2 + 1],
1398 WebRtcIsacfix_kT1GainQ15[0][3]);
1399 tmpcoeffs2_gQ21[posg] = sumQQ;
1403 /* right transform */
1404 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21,
1405 tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1);
1407 /* quantize coefficients */
1409 for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
1411 posQQ = WebRtcIsacfix_kSelIndGain[k];
1412 pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
1414 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
1415 if (index_gQQ[k] < 0) {
1418 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
1419 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
1422 /* Save data for creation of multiple bitstreams */
1423 if (encData != NULL) {
1424 encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k];
1428 /* entropy coding of index */
1429 status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
1438 int WebRtcIsacfix_EncodeLpc(int32_t *gain_lo_hiQ17,
1439 int16_t *LPCCoef_loQ15,
1440 int16_t *LPCCoef_hiQ15,
1443 Bitstr_enc *streamdata,
1444 ISAC_SaveEncData_t* encData,
1445 transcode_obj *transcodeParam)
1448 int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES
1449 // = (6+12)*6 == 108
1451 Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17);
1453 status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11,
1454 streamdata, encData, transcodeParam);
1459 Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES);
1465 /* decode & dequantize RC */
1466 int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, int16_t *RCQ15)
1469 int16_t index[AR_ORDER];
1471 /* entropy decoding of quantization indices */
1472 err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER);
1473 if (err<0) // error check
1476 /* find quantization levels for reflection coefficients */
1477 for (k=0; k<AR_ORDER; k++)
1479 RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]);
1487 /* quantize & code RC */
1488 int WebRtcIsacfix_EncodeRcCoef(int16_t *RCQ15, Bitstr_enc *streamdata)
1491 int16_t index[AR_ORDER];
1494 /* quantize reflection coefficients (add noise feedback?) */
1495 for (k=0; k<AR_ORDER; k++)
1497 index[k] = WebRtcIsacfix_kRcInitInd[k];
1499 if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]])
1501 while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1])
1506 while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ;
1509 RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]);
1513 /* entropy coding of quantization indices */
1514 status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER);
1516 /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
1521 /* decode & dequantize squared Gain */
1522 int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, int32_t *gainQ10)
1527 /* entropy decoding of quantization index */
1528 err = WebRtcIsacfix_DecHistOneStepMulti(
1531 WebRtcIsacfix_kGainPtr,
1532 WebRtcIsacfix_kGainInitInd,
1539 /* find quantization level */
1540 *gainQ10 = WebRtcIsacfix_kGain2Lev[index];
1547 /* quantize & code squared Gain */
1548 int WebRtcIsacfix_EncodeGain2(int32_t *gainQ10, Bitstr_enc *streamdata)
1553 /* find quantization index */
1554 index = WebRtcIsacfix_kGainInitInd[0];
1555 if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index])
1557 while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1])
1562 while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ;
1566 *gainQ10 = WebRtcIsacfix_kGain2Lev[index];
1568 /* entropy coding of quantization index */
1569 status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1);
1571 /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
1576 /* code and decode Pitch Gains and Lags functions */
1578 /* decode & dequantize Pitch Gains */
1579 int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, int16_t *PitchGains_Q12)
1583 const uint16_t *pitch_gain_cdf_ptr[1];
1585 /* entropy decoding of quantization indices */
1586 *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
1587 err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1);
1588 /* error check, Q_mean_Gain.. tables are of size 144 */
1589 if ((err < 0) || (index_comb < 0) || (index_comb >= 144))
1590 return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN;
1592 /* unquantize back to pitch gains by table look-up */
1593 PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb];
1594 PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb];
1595 PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb];
1596 PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb];
1602 /* quantize & code Pitch Gains */
1603 int WebRtcIsacfix_EncodePitchGain(int16_t *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData)
1606 int16_t SQ15[PITCH_SUBFRAMES];
1609 const uint16_t *pitch_gain_cdf_ptr[1];
1614 /* get the approximate arcsine (almost linear)*/
1615 for (k=0; k<PITCH_SUBFRAMES; k++)
1616 SQ15[k] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[k],33,2); //Q15
1619 /* find quantization index; only for the first three transform coefficients */
1624 for (j=0; j<PITCH_SUBFRAMES; j++) {
1625 CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17
1628 index[k] = (int16_t)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8)
1630 /* check that the index is not outside the boundaries of the table */
1631 if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k];
1632 else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k];
1633 index[k] -= WebRtcIsacfix_kLowerlimiGain[k];
1636 /* calculate unique overall index */
1637 index_comb = (int16_t)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) +
1638 WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]);
1640 /* unquantize back to pitch gains by table look-up */
1642 PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb];
1643 PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb];
1644 PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb];
1645 PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb];
1648 /* entropy coding of quantization pitch gains */
1649 *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
1650 status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1);
1655 /* Save data for creation of multiple bitstreams */
1656 if (encData != NULL) {
1657 encData->pitchGain_index[encData->startIdx] = index_comb;
1668 /* decode & dequantize Pitch Lags */
1669 int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
1670 int16_t *PitchGain_Q12,
1671 int16_t *PitchLags_Q7)
1674 int16_t index[PITCH_SUBFRAMES];
1675 const int16_t *mean_val2Q10, *mean_val4Q10;
1677 const int16_t *lower_limit;
1678 const uint16_t *init_index;
1679 const uint16_t *cdf_size;
1680 const uint16_t **cdf;
1682 int32_t meangainQ12;
1683 int32_t CQ11, CQ10,tmp32a,tmp32b;
1684 int16_t shft,tmp16a,tmp16c;
1687 for (k = 0; k < 4; k++)
1688 meangainQ12 += PitchGain_Q12[k];
1690 meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); // Get average
1692 /* voicing classificiation */
1693 if (meangainQ12 <= 819) { // mean_gain < 0.2
1694 shft = -1; // StepSize=2.0;
1695 cdf = WebRtcIsacfix_kPitchLagPtrLo;
1696 cdf_size = WebRtcIsacfix_kPitchLagSizeLo;
1697 mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo;
1698 mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo;
1699 lower_limit = WebRtcIsacfix_kLowerLimitLo;
1700 init_index = WebRtcIsacfix_kInitIndLo;
1701 } else if (meangainQ12 <= 1638) { // mean_gain < 0.4
1702 shft = 0; // StepSize=1.0;
1703 cdf = WebRtcIsacfix_kPitchLagPtrMid;
1704 cdf_size = WebRtcIsacfix_kPitchLagSizeMid;
1705 mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid;
1706 mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid;
1707 lower_limit = WebRtcIsacfix_kLowerLimitMid;
1708 init_index = WebRtcIsacfix_kInitIndMid;
1710 shft = 1; // StepSize=0.5;
1711 cdf = WebRtcIsacfix_kPitchLagPtrHi;
1712 cdf_size = WebRtcIsacfix_kPitchLagSizeHi;
1713 mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi;
1714 mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi;
1715 lower_limit = WebRtcIsacfix_kLowerLimitHi;
1716 init_index = WebRtcIsacfix_kInitIndHi;
1719 /* entropy decoding of quantization indices */
1720 err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1);
1721 if ((err<0) || (index[0]<0)) // error check
1722 return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
1724 err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3);
1725 if (err<0) // error check
1726 return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
1729 /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */
1730 CQ11 = ((int32_t)index[0] + lower_limit[0]); // Q0
1731 CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
1732 for (k=0; k<PITCH_SUBFRAMES; k++) {
1733 tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11);
1734 tmp16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);
1735 PitchLags_Q7[k] = tmp16a;
1738 CQ10 = mean_val2Q10[index[1]];
1739 for (k=0; k<PITCH_SUBFRAMES; k++) {
1740 tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[1][k], (int16_t) CQ10,10);
1741 tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
1742 PitchLags_Q7[k] += tmp16c;
1745 CQ10 = mean_val4Q10[index[3]];
1746 for (k=0; k<PITCH_SUBFRAMES; k++) {
1747 tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[3][k], (int16_t) CQ10,10);
1748 tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
1749 PitchLags_Q7[k] += tmp16c;
1757 /* quantize & code Pitch Lags */
1758 int WebRtcIsacfix_EncodePitchLag(int16_t *PitchLagsQ7,int16_t *PitchGain_Q12,
1759 Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData)
1762 int16_t index[PITCH_SUBFRAMES];
1763 int32_t meangainQ12, CQ17;
1764 int32_t CQ11, CQ10,tmp32a;
1766 const int16_t *mean_val2Q10,*mean_val4Q10;
1767 const int16_t *lower_limit, *upper_limit;
1768 const uint16_t **cdf;
1769 int16_t shft, tmp16a, tmp16b, tmp16c;
1773 /* compute mean pitch gain */
1775 for (k = 0; k < 4; k++)
1776 meangainQ12 += PitchGain_Q12[k];
1778 meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2);
1780 /* Save data for creation of multiple bitstreams */
1781 if (encData != NULL) {
1782 encData->meanGain[encData->startIdx] = meangainQ12;
1785 /* voicing classificiation */
1786 if (meangainQ12 <= 819) { // mean_gain < 0.2
1787 shft = -1; // StepSize=2.0;
1788 cdf = WebRtcIsacfix_kPitchLagPtrLo;
1789 mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo;
1790 mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo;
1791 lower_limit = WebRtcIsacfix_kLowerLimitLo;
1792 upper_limit = WebRtcIsacfix_kUpperLimitLo;
1793 } else if (meangainQ12 <= 1638) { // mean_gain < 0.4
1794 shft = 0; // StepSize=1.0;
1795 cdf = WebRtcIsacfix_kPitchLagPtrMid;
1796 mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid;
1797 mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid;
1798 lower_limit = WebRtcIsacfix_kLowerLimitMid;
1799 upper_limit = WebRtcIsacfix_kUpperLimitMid;
1801 shft = 1; // StepSize=0.5;
1802 cdf = WebRtcIsacfix_kPitchLagPtrHi;
1803 mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi;
1804 mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi;
1805 lower_limit = WebRtcIsacfix_kLowerLimitHi;
1806 upper_limit = WebRtcIsacfix_kUpperLimitHi;
1809 /* find quantization index */
1814 for (j=0; j<PITCH_SUBFRAMES; j++)
1815 CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17
1817 CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize
1820 tmp16b = (int16_t) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 );
1823 /* check that the index is not outside the boundaries of the table */
1824 if (index[k] < lower_limit[k]) index[k] = lower_limit[k];
1825 else if (index[k] > upper_limit[k]) index[k] = upper_limit[k];
1826 index[k] -= lower_limit[k];
1828 /* Save data for creation of multiple bitstreams */
1829 if(encData != NULL) {
1830 encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k];
1834 /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */
1835 CQ11 = (index[0] + lower_limit[0]); // Q0
1836 CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
1838 for (k=0; k<PITCH_SUBFRAMES; k++) {
1839 tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12
1840 tmp16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7
1841 PitchLagsQ7[k] = tmp16a;
1844 CQ10 = mean_val2Q10[index[1]];
1845 for (k=0; k<PITCH_SUBFRAMES; k++) {
1846 tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[1][k], (int16_t) CQ10,10);
1847 tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
1848 PitchLagsQ7[k] += tmp16c;
1851 CQ10 = mean_val4Q10[index[3]];
1852 for (k=0; k<PITCH_SUBFRAMES; k++) {
1853 tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[3][k], (int16_t) CQ10,10);
1854 tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
1855 PitchLagsQ7[k] += tmp16c;
1858 /* entropy coding of quantization pitch lags */
1859 status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES);
1861 /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
1867 /* Routines for inband signaling of bandwitdh estimation */
1868 /* Histograms based on uniform distribution of indices */
1869 /* Move global variables later! */
1872 /* cdf array for frame length indicator */
1873 const uint16_t kFrameLenCdf[4] = {
1874 0, 21845, 43690, 65535};
1876 /* pointer to cdf array for frame length indicator */
1877 const uint16_t *kFrameLenCdfPtr[1] = {kFrameLenCdf};
1879 /* initial cdf index for decoder of frame length indicator */
1880 const uint16_t kFrameLenInitIndex[1] = {1};
1883 int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata,
1884 int16_t *framesamples)
1891 /* entropy decoding of frame length [1:30ms,2:60ms] */
1892 err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1);
1893 if (err<0) // error check
1894 return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH;
1896 switch(frame_mode) {
1898 *framesamples = 480; /* 30ms */
1901 *framesamples = 960; /* 60ms */
1904 err = -ISAC_DISALLOWED_FRAME_MODE_DECODER;
1911 int WebRtcIsacfix_EncodeFrameLen(int16_t framesamples, Bitstr_enc *streamdata) {
1918 /* entropy coding of frame length [1:480 samples,2:960 samples] */
1919 switch(framesamples) {
1927 status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER;
1933 status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1);
1938 /* cdf array for estimated bandwidth */
1939 const uint16_t kBwCdf[25] = {
1940 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037,
1941 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074,
1944 /* pointer to cdf array for estimated bandwidth */
1945 const uint16_t *kBwCdfPtr[1] = {kBwCdf};
1947 /* initial cdf index for decoder of estimated bandwidth*/
1948 const uint16_t kBwInitIndex[1] = {7};
1951 int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, int16_t *BWno) {
1956 /* entropy decoding of sender's BW estimation [0..23] */
1957 err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1);
1958 if (err<0) // error check
1959 return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH;
1960 *BWno = (int16_t)BWno32;
1966 int WebRtcIsacfix_EncodeReceiveBandwidth(int16_t *BWno, Bitstr_enc *streamdata)
1969 /* entropy encoding of receiver's BW estimation [0..23] */
1970 status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1);
1975 /* estimate codel length of LPC Coef */
1976 void WebRtcIsacfix_TranscodeLpcCoef(int32_t *gain_lo_hiQ17,
1977 int16_t *index_gQQ) {
1979 int16_t posQQ, pos2QQ;
1980 int16_t posg, offsg, gainpos;
1981 int32_t tmpcoeffs_gQ6[KLT_ORDER_GAIN];
1982 int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN];
1983 int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
1987 /* log gains, mean removal and scaling */
1988 posg = 0; gainpos=0;
1990 for (k=0; k<SUBFRAMES; k++) {
1993 /* The input argument X to logN(X) is 2^17 times higher than the
1994 input floating point argument Y to log(Y), since the X value
1995 is a Q17 value. This can be compensated for after the call, by
1996 subraction a value Z for each Q-step. One Q-step means that
1997 X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
1998 177.445678 should be subtracted (since logN() returns a Q8 value).
1999 For a X value in Q17, the value 177.445678*17 = 3017 should be
2001 tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
2002 tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
2005 tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
2006 tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
2014 /* left transform */
2015 for (j = 0, offsg = 0; j < SUBFRAMES; j++, offsg += 2) {
2017 sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg],
2018 WebRtcIsacfix_kT1GainQ15[0][0]);
2019 sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1],
2020 WebRtcIsacfix_kT1GainQ15[0][2]);
2021 tmpcoeffs2_gQ21[offsg] = sumQQ;
2024 sumQQ = WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg],
2025 WebRtcIsacfix_kT1GainQ15[0][1]);
2026 sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[offsg + 1],
2027 WebRtcIsacfix_kT1GainQ15[0][3]);
2028 tmpcoeffs2_gQ21[offsg + 1] = sumQQ;
2031 /* right transform */
2032 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21,
2033 tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1);
2035 /* quantize coefficients */
2036 for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
2038 posQQ = WebRtcIsacfix_kSelIndGain[k];
2039 pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
2041 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
2042 if (index_gQQ[k] < 0) {
2045 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
2046 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];