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 static __inline int32_t CalcLrIntQ(int32_t fixVal, int16_t qDomain) { 75 int32_t intgr; 76 int32_t roundVal; 77 78 roundVal = WEBRTC_SPL_LSHIFT_W32((int32_t)1, qDomain-1); 79 intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain); 80 81 return intgr; 82 } 83 84 /* 85 __inline uint32_t stepwise(int32_t dinQ10) { 86 87 int32_t ind, diQ10, dtQ10; 88 89 diQ10 = dinQ10; 90 if (diQ10 < DPMIN_Q10) 91 diQ10 = DPMIN_Q10; 92 if (diQ10 >= DPMAX_Q10) 93 diQ10 = DPMAX_Q10 - 1; 94 95 dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */ 96 /* ind = (dtQ10 * 5) >> 10; */ /* 2^10 / 5 = 0.2 in Q10 */ 97 /* Q10 -> Q0 */ 98 99 /* return rpointsFIX_Q10[ind]; 100 101 } 102 */ 103 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 112 subtracted */ 113 static int16_t CalcLogN(int32_t arg) { 114 int16_t zeros, log2, frac, logN; 115 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. 121 122 return logN; 123 } 124 125 126 /* 127 expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695 128 129 Input: Q8 (int16_t) 130 Output: Q17 (int32_t) 131 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. 135 */ 136 137 static int32_t CalcExpN(int16_t x) { 138 int16_t ax, axINT, axFRAC; 139 int16_t exp16; 140 int32_t exp; 141 142 if (x>=0) { 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 146 axFRAC = ax&0x00FF; 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 151 } else { 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 154 ax = -ax; 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 161 } 162 163 return exp; 164 } 165 166 167 /* compute correlation from power spectrum */ 168 static void CalcCorrelation(int32_t *PSpecQ12, int32_t *CorrQ7) 169 { 170 int32_t summ[FRAMESAMPLES/8]; 171 int32_t diff[FRAMESAMPLES/8]; 172 int32_t sum; 173 int k, n; 174 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); 178 } 179 180 sum = 2; 181 for (n = 0; n < FRAMESAMPLES/8; n++) 182 sum += summ[n]; 183 CorrQ7[0] = sum; 184 185 for (k = 0; k < AR_ORDER; k += 2) { 186 sum = 0; 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); 189 CorrQ7[k+1] = sum; 190 } 191 192 for (k=1; k<AR_ORDER; k+=2) { 193 sum = 0; 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); 196 CorrQ7[k+1] = sum; 197 } 198 } 199 200 201 /* compute inverse AR power spectrum */ 202 static void CalcInvArSpec(const int16_t *ARCoefQ12, 203 const int32_t gainQ10, 204 int32_t *CurveQ16) 205 { 206 int32_t CorrQ11[AR_ORDER+1]; 207 int32_t sum, tmpGain; 208 int32_t diffQ16[FRAMESAMPLES/8]; 209 const int16_t *CS_ptrQ9; 210 int k, n; 211 int16_t round, shftVal = 0, sh; 212 213 sum = 0; 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); 218 219 /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 220 if(gainQ10>400000){ 221 tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 222 round = 32; 223 shftVal = 6; 224 } else { 225 tmpGain = gainQ10; 226 round = 256; 227 shftVal = 9; 228 } 229 230 for (k = 1; k < AR_ORDER+1; k++) { 231 sum = 16384; 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); 236 } 237 sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 238 for (n = 0; n < FRAMESAMPLES/8; n++) 239 CurveQ16[n] = sum; 240 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); 244 } 245 246 CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 247 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]); 252 253 if (sh<9) 254 shftVal = 9 - sh; 255 else 256 shftVal = 0; 257 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); 264 } 265 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); 269 } 270 } 271 272 static void CalcRootInvArSpec(const int16_t *ARCoefQ12, 273 const int32_t gainQ10, 274 uint16_t *CurveQ8) 275 { 276 int32_t CorrQ11[AR_ORDER+1]; 277 int32_t sum, tmpGain; 278 int32_t summQ16[FRAMESAMPLES/8]; 279 int32_t diffQ16[FRAMESAMPLES/8]; 280 281 const int16_t *CS_ptrQ9; 282 int k, n, i; 283 int16_t round, shftVal = 0, sh; 284 int32_t res, in_sqrt, newRes; 285 286 sum = 0; 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); 291 292 /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ 293 if(gainQ10>400000){ 294 tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); 295 round = 32; 296 shftVal = 6; 297 } else { 298 tmpGain = gainQ10; 299 round = 256; 300 shftVal = 9; 301 } 302 303 for (k = 1; k < AR_ORDER+1; k++) { 304 sum = 16384; 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); 309 } 310 sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); 311 for (n = 0; n < FRAMESAMPLES/8; n++) 312 summQ16[n] = sum; 313 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; 317 } 318 319 CS_ptrQ9 = WebRtcIsacfix_kCos[0]; 320 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]); 325 326 if (sh<9) 327 shftVal = 9 - sh; 328 else 329 shftVal = 0; 330 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); 337 } 338 339 in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal); 340 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)); 343 344 for (k = 0; k < FRAMESAMPLES/8; k++) 345 { 346 in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); 347 i = 10; 348 349 /* make in_sqrt positive to prohibit sqrt of negative values */ 350 if(in_sqrt<0) 351 in_sqrt=-in_sqrt; 352 353 newRes = (in_sqrt / res + res) >> 1; 354 do 355 { 356 res = newRes; 357 newRes = (in_sqrt / res + res) >> 1; 358 } while (newRes != res && i-- > 0); 359 360 CurveQ8[k] = (int16_t)newRes; 361 } 362 for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) { 363 364 in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal); 365 i = 10; 366 367 /* make in_sqrt positive to prohibit sqrt of negative values */ 368 if(in_sqrt<0) 369 in_sqrt=-in_sqrt; 370 371 newRes = (in_sqrt / res + res) >> 1; 372 do 373 { 374 res = newRes; 375 newRes = (in_sqrt / res + res) >> 1; 376 } while (newRes != res && i-- > 0); 377 378 CurveQ8[k] = (int16_t)newRes; 379 } 380 381 } 382 383 384 385 /* generate array of dither samples in Q7 */ 386 static void GenerateDitherQ7(int16_t *bufQ7, 387 uint32_t seed, 388 int16_t length, 389 int16_t AvgPitchGain_Q12) 390 { 391 int k; 392 int16_t dither1_Q7, dither2_Q7, dither_gain_Q14, shft; 393 394 if (AvgPitchGain_Q12 < 614) /* this threshold should be equal to that in decode_spec() */ 395 { 396 for (k = 0; k < length-2; k += 3) 397 { 398 /* new random unsigned int32_t */ 399 seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 400 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 403 404 /* new random unsigned int32_t */ 405 seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 406 407 /* fixed-point dither sample between -64 and 64 */ 408 dither2_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25); 409 410 shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15); 411 if (shft < 5) 412 { 413 bufQ7[k] = dither1_Q7; 414 bufQ7[k+1] = dither2_Q7; 415 bufQ7[k+2] = 0; 416 } 417 else if (shft < 10) 418 { 419 bufQ7[k] = dither1_Q7; 420 bufQ7[k+1] = 0; 421 bufQ7[k+2] = dither2_Q7; 422 } 423 else 424 { 425 bufQ7[k] = 0; 426 bufQ7[k+1] = dither1_Q7; 427 bufQ7[k+2] = dither2_Q7; 428 } 429 } 430 } 431 else 432 { 433 dither_gain_Q14 = (int16_t)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12)); 434 435 /* dither on half of the coefficients */ 436 for (k = 0; k < length-1; k += 2) 437 { 438 /* new random unsigned int32_t */ 439 seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; 440 441 /* fixed-point dither sample between -64 and 64 */ 442 dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25); 443 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 */ 446 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; 449 } 450 } 451 } 452 453 454 455 456 /* 457 * function to decode the complex spectrum from the bitstream 458 * returns the total number of bytes in the stream 459 */ 460 int16_t WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata, 461 int16_t *frQ7, 462 int16_t *fiQ7, 463 int16_t AvgPitchGain_Q12) 464 { 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]; 469 int16_t gainQ10; 470 int32_t gain2_Q10; 471 int16_t len; 472 int k; 473 474 /* create dither signal */ 475 GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */ 476 477 /* decode model parameters */ 478 if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0) 479 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 480 481 482 WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 483 484 if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0) 485 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 486 487 /* compute inverse AR power spectrum */ 488 CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); 489 490 /* arithmetic decoding of spectrum */ 491 /* 'data' input and output. Input = Dither */ 492 len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (int16_t)FRAMESAMPLES); 493 494 if (len<1) 495 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; 496 497 /* subtract dither and scale down spectral samples with low SNR */ 498 if (AvgPitchGain_Q12 <= 614) 499 { 500 for (k = 0; k < FRAMESAMPLES; k += 4) 501 { 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); 508 } 509 } 510 else 511 { 512 for (k = 0; k < FRAMESAMPLES; k += 4) 513 { 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); 520 } 521 } 522 523 return len; 524 } 525 526 527 int WebRtcIsacfix_EncodeSpec(const int16_t *fr, 528 const int16_t *fi, 529 Bitstr_enc *streamdata, 530 int16_t AvgPitchGain_Q12) 531 { 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]; 539 int32_t gain2_Q10; 540 int16_t val; 541 int32_t nrg; 542 uint32_t sum; 543 int16_t lft_shft; 544 int16_t status; 545 int k, n, j; 546 547 548 /* create dither_float signal */ 549 GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); 550 551 /* add dither and quantize, and compute power spectrum */ 552 /* Vector dataQ7 contains Dither in Q7 */ 553 for (k = 0; k < FRAMESAMPLES; k += 4) 554 { 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); 558 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); 562 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); 566 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); 570 571 PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2); 572 } 573 574 /* compute correlation from power spectrum */ 575 CalcCorrelation(PSpec, CorrQ7); 576 577 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; 581 582 if (lft_shft > 0) { 583 for (k=0; k<AR_ORDER+1; k++) 584 CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft); 585 } else { 586 for (k=0; k<AR_ORDER+1; k++) 587 CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft); 588 } 589 590 /* find RC coefficients */ 591 WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); 592 593 /* quantize & code RC Coef */ 594 status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata); 595 if (status < 0) { 596 return status; 597 } 598 599 /* RC -> AR coefficients */ 600 WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); 601 602 /* compute ARCoef' * Corr * ARCoef in Q19 */ 603 nrg = 0; 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); 609 } 610 611 if (lft_shft > 0) 612 nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft); 613 else 614 nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft); 615 616 if(nrg>131072) 617 gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */ 618 else 619 gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2); 620 621 /* quantize & code gain2_Q10 */ 622 if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata)) 623 return -1; 624 625 /* compute inverse AR magnitude spectrum */ 626 CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8); 627 628 629 /* arithmetic coding of spectrum */ 630 status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (int16_t)FRAMESAMPLES); 631 if ( status ) 632 return( status ); 633 634 return 0; 635 } 636 637 638 /* Matlab's LAR definition */ 639 static void Rc2LarFix(const int16_t *rcQ15, int32_t *larQ17, int16_t order) { 640 641 /* 642 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] 646 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 653 654 The implementation is y(x)= a + (x-x0)*k, but this can be simplified to 655 656 y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k 657 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]; 662 663 b = akx(:,1) - akx(:,3).*akx(:,2) 664 665 [ 0.0 666 -3.547841027073 667 -25.366077452148 668 -675.552510708011] 669 670 */ 671 672 int k; 673 int16_t rc; 674 int32_t larAbsQ17; 675 676 for (k = 0; k < order; k++) { 677 678 rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15 679 680 /* Calculate larAbsQ17 in Q17 from rc in Q15 */ 681 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); 691 } else { 692 // Q17 + (Q15*Q5)>>3 = Q17 693 larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3); 694 } 695 696 if (rcQ15[k]>0) { 697 larQ17[k] = larAbsQ17; 698 } else { 699 larQ17[k] = -larAbsQ17; 700 } 701 } 702 } 703 704 705 static void Lar2RcFix(const int32_t *larQ17, int16_t *rcQ15, int16_t order) { 706 707 /* 708 This is a piece-wise implemenetation of a lar2rc-function 709 See comment in Rc2LarFix() about details. 710 */ 711 712 int k; 713 int16_t larAbsQ11; 714 int32_t rc; 715 716 for (k = 0; k < order; k++) { 717 718 larAbsQ11 = (int16_t) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11 719 720 if (larAbsQ11<4097) { //2.000012018559 in Q11 721 // Q11*Q16>>12 = Q15 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); 729 } else { 730 // (Q11*Q24>>16 + Q19)>>4 = Q15 731 rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4); 732 } 733 734 if (larQ17[k]<=0) { 735 rc = -rc; 736 } 737 738 rcQ15[k] = (int16_t) rc; // Q15 739 } 740 } 741 742 static void Poly2LarFix(int16_t *lowbandQ15, 743 int16_t orderLo, 744 int16_t *hibandQ15, 745 int16_t orderHi, 746 int16_t Nsub, 747 int32_t *larsQ17) { 748 749 int k, n; 750 int32_t *outpQ17; 751 int16_t orderTot; 752 int32_t larQ17[MAX_ORDER]; // Size 7+6 is enough 753 754 orderTot = (orderLo + orderHi); 755 outpQ17 = larsQ17; 756 for (k = 0; k < Nsub; k++) { 757 758 Rc2LarFix(lowbandQ15, larQ17, orderLo); 759 760 for (n = 0; n < orderLo; n++) 761 outpQ17[n] = larQ17[n]; //Q17 762 763 Rc2LarFix(hibandQ15, larQ17, orderHi); 764 765 for (n = 0; n < orderHi; n++) 766 outpQ17[n + orderLo] = larQ17[n]; //Q17; 767 768 outpQ17 += orderTot; 769 lowbandQ15 += orderLo; 770 hibandQ15 += orderHi; 771 } 772 } 773 774 775 static void Lar2polyFix(int32_t *larsQ17, 776 int16_t *lowbandQ15, 777 int16_t orderLo, 778 int16_t *hibandQ15, 779 int16_t orderHi, 780 int16_t Nsub) { 781 782 int k, n; 783 int16_t orderTot; 784 int16_t *outplQ15, *outphQ15; 785 int32_t *inpQ17; 786 int16_t rcQ15[7+6]; 787 788 orderTot = (orderLo + orderHi); 789 outplQ15 = lowbandQ15; 790 outphQ15 = hibandQ15; 791 inpQ17 = larsQ17; 792 for (k = 0; k < Nsub; k++) { 793 794 /* gains not handled here as in the FLP version */ 795 796 /* Low band */ 797 Lar2RcFix(&inpQ17[0], rcQ15, orderLo); 798 for (n = 0; n < orderLo; n++) 799 outplQ15[n] = rcQ15[n]; // Refl. coeffs 800 801 /* High band */ 802 Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi); 803 for (n = 0; n < orderHi; n++) 804 outphQ15[n] = rcQ15[n]; // Refl. coeffs 805 806 inpQ17 += orderTot; 807 outplQ15 += orderLo; 808 outphQ15 += orderHi; 809 } 810 } 811 812 /* 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. 816 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). 825 826 |matrix0_index| is determined the same way. 827 828 Arguments: 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. 844 */ 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, 855 const int shift) { 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; 863 } 864 865 for (j = 0; j < SUBFRAMES; j++) { 866 matrix_prod_index = mid_loop_count * j; 867 for (k = 0; k < mid_loop_count; k++) { 868 int32_t sum32 = 0; 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; 876 } 877 matrix_product[matrix_prod_index] = sum32; 878 matrix_prod_index++; 879 } 880 } 881 } 882 883 /* 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. 887 888 Arguments: 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 893 of matrix0_index. 894 matrix0_index_step: Incremental step for matrix0_index. 895 */ 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) { 901 int j = 0, n = 0; 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; 905 matrix1_index = 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])); 912 matrix1_index += 2; 913 matrix0_index += matrix0_index_step; 914 } 915 matrix_product[matrix_prod_index] = sum32 >> 3; 916 matrix_product[matrix_prod_index + 1] = sum32_2 >> 3; 917 matrix_prod_index += 2; 918 } 919 } 920 921 int WebRtcIsacfix_DecodeLpc(int32_t *gain_lo_hiQ17, 922 int16_t *LPCCoef_loQ15, 923 int16_t *LPCCoef_hiQ15, 924 Bitstr_dec *streamdata, 925 int16_t *outmodel) { 926 927 int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 928 int err; 929 930 err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel); 931 if (err<0) // error check 932 return -ISAC_RANGE_ERROR_DECODE_LPC; 933 934 Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 935 936 return 0; 937 } 938 939 /* decode & dequantize LPC Coef */ 940 int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata, 941 int32_t *LPCCoefQ17, 942 int32_t *gain_lo_hiQ17, 943 int16_t *outmodel) 944 { 945 int j, k, n; 946 int err; 947 int16_t pos, pos2, posg, poss; 948 int16_t gainpos; 949 int16_t model; 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]; 956 int32_t sumQQ; 957 int16_t sumQQ16; 958 int32_t tmp32; 959 960 961 962 /* entropy decoding of model number */ 963 err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1); 964 if (err<0) // error check 965 return err; 966 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 970 return err; 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]]; 974 } 975 976 err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN); 977 if (err<0) // error check 978 return err; 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]]; 982 } 983 984 985 /* inverse KLT */ 986 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); 992 993 poss = 0; 994 for (j=0; j<SUBFRAMES; j++) { 995 for (k=0; k<LPC_SHAPE_ORDER; k++) { 996 sumQQ = 0; 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 1001 pos++; 1002 pos2++; 1003 } 1004 tmpcoeffs2_sQ18[poss] = sumQQ; //Q18 1005 poss++; 1006 } 1007 } 1008 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, 1015 kTMatrix1_shift0); 1016 1017 /* scaling, mean addition, and gain restoration */ 1018 gainpos = 0; 1019 posg = 0;poss = 0;pos=0; 1020 for (k=0; k<SUBFRAMES; k++) { 1021 1022 /* log gains */ 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 1027 gainpos++; 1028 posg++; 1029 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 1034 gainpos++; 1035 posg++; 1036 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; 1042 } 1043 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; 1049 } 1050 } 1051 1052 1053 *outmodel=model; 1054 1055 return 0; 1056 } 1057 1058 /* estimate codel length of LPC Coef */ 1059 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 ISAC_SaveEncData_t* 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 int status = 0; 1082 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]; 1088 } 1089 } 1090 1091 /* log gains, mean removal and scaling */ 1092 posg = 0;poss = 0;pos=0; gainpos=0; 1093 1094 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 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 1107 posg++; gainpos++; 1108 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 1111 posg++; gainpos++; 1112 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 1118 } 1119 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 1125 } 1126 1127 } 1128 1129 1130 /* KLT */ 1131 1132 /* left transform */ 1133 offsg = 0; 1134 posg = 0; 1135 for (j=0; j<SUBFRAMES; j++) { 1136 // Q21 = Q6 * Q15 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; 1142 posg++; 1143 1144 // Q21 = Q6 * Q15 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; 1150 posg++; 1151 1152 offsg += 2; 1153 } 1154 1155 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT1ShapeQ15[0], tmpcoeffs_sQ17, 1156 tmpcoeffs2_sQ17, kTIndexFactor4, kTIndexFactor1, kTInitCase0, 1157 kTIndexStep1, kTIndexStep3, kTLoopCount3, kTLoopCount3, kTMatrix1_shift1); 1158 1159 /* right transform */ 1160 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 1161 tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 1162 1163 WebRtcIsacfix_MatrixProduct1(WebRtcIsacfix_kT2ShapeQ15[0], tmpcoeffs2_sQ17, 1164 tmpcoeffs_sQ17, kTIndexFactor1, kTIndexFactor3, kTInitCase1, kTIndexStep3, 1165 kTIndexStep1, kTLoopCount1, kTLoopCount3, kTMatrix1_shift1); 1166 1167 /* quantize coefficients */ 1168 1169 BitsQQ = 0; 1170 for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1171 { 1172 posQQ = WebRtcIsacfix_kSelIndGain[k]; 1173 pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1174 1175 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1176 if (index_gQQ[k] < 0) { 1177 index_gQQ[k] = 0; 1178 } 1179 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1180 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1181 } 1182 index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k]; 1183 posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k]; 1184 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]; 1188 } 1189 1190 /* determine number of bits */ 1191 sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11 1192 BitsQQ += sumQQ; 1193 } 1194 1195 for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok? 1196 { 1197 index_sQQ[k] = (int16_t)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok? 1198 1199 if (index_sQQ[k] < 0) 1200 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]; 1204 1205 posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k]; 1206 sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11 1207 BitsQQ += sumQQ; 1208 } 1209 1210 1211 1212 *model = 0; 1213 *sizeQ11=BitsQQ; 1214 1215 /* entropy coding of model number */ 1216 status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1); 1217 if (status < 0) { 1218 return status; 1219 } 1220 1221 /* entropy coding of quantization indices - shape only */ 1222 status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); 1223 if (status < 0) { 1224 return status; 1225 } 1226 1227 /* Save data for creation of multiple bitstreams */ 1228 if (encData != NULL) { 1229 for (k=0; k<KLT_ORDER_SHAPE; k++) 1230 { 1231 encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k]; 1232 } 1233 } 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]; 1241 1242 /* entropy coding of index */ 1243 status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1244 if (status < 0) { 1245 return status; 1246 } 1247 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]]); 1251 1252 } 1253 /* inverse KLT */ 1254 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); 1259 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); 1264 1265 /* scaling, mean addition, and gain restoration */ 1266 poss = 0;pos=0; 1267 for (k=0; k<SUBFRAMES; k++) { 1268 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; 1274 } 1275 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; 1281 } 1282 1283 } 1284 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]]; 1288 } 1289 1290 1291 1292 /* find quantization levels for coefficients */ 1293 1294 /* left transform */ 1295 offsg = 0; 1296 posg = 0; 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); 1304 posg++; 1305 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); 1311 posg++; 1312 offsg += 2; 1313 } 1314 1315 /* right transform */ // Transpose matrix 1316 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 1317 tmpcoeffs_gQ17, kTIndexFactor1, kTIndexStep2); 1318 1319 /* scaling, mean addition, and gain restoration */ 1320 posg = 0; 1321 gainpos = 0; 1322 for (k=0; k<2*SUBFRAMES; k++) { 1323 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 1328 1329 gainpos++; 1330 pos++;posg++; 1331 } 1332 1333 return 0; 1334 } 1335 1336 int WebRtcIsacfix_EstCodeLpcGain(int32_t *gain_lo_hiQ17, 1337 Bitstr_enc *streamdata, 1338 ISAC_SaveEncData_t* encData) { 1339 int j, k; 1340 int16_t posQQ, pos2QQ, gainpos; 1341 int16_t posg; 1342 int16_t index_gQQ[KLT_ORDER_GAIN]; 1343 1344 int16_t tmpcoeffs_gQ6[KLT_ORDER_GAIN]; 1345 int32_t tmpcoeffs_gQ17[KLT_ORDER_GAIN]; 1346 int32_t tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; 1347 int32_t sumQQ; 1348 int status = 0; 1349 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]; 1355 } 1356 } 1357 1358 /* log gains, mean removal and scaling */ 1359 posg = 0; gainpos = 0; 1360 1361 for (k=0; k<SUBFRAMES; k++) { 1362 /* log gains */ 1363 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 1371 subtracted */ 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 1374 posg++; gainpos++; 1375 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 1378 posg++; gainpos++; 1379 } 1380 1381 1382 /* KLT */ 1383 1384 /* left transform */ 1385 posg = 0; 1386 for (j=0; j<SUBFRAMES; j++) { 1387 // Q21 = Q6 * Q15 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; 1393 posg++; 1394 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; 1400 posg++; 1401 } 1402 1403 /* right transform */ 1404 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 1405 tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 1406 1407 /* quantize coefficients */ 1408 1409 for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 1410 { 1411 posQQ = WebRtcIsacfix_kSelIndGain[k]; 1412 pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 1413 1414 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 1415 if (index_gQQ[k] < 0) { 1416 index_gQQ[k] = 0; 1417 } 1418 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 1419 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 1420 } 1421 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]; 1425 } 1426 } 1427 1428 /* entropy coding of index */ 1429 status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 1430 if (status < 0) { 1431 return status; 1432 } 1433 1434 return 0; 1435 } 1436 1437 1438 int WebRtcIsacfix_EncodeLpc(int32_t *gain_lo_hiQ17, 1439 int16_t *LPCCoef_loQ15, 1440 int16_t *LPCCoef_hiQ15, 1441 int16_t *model, 1442 int32_t *sizeQ11, 1443 Bitstr_enc *streamdata, 1444 ISAC_SaveEncData_t* encData, 1445 transcode_obj *transcodeParam) 1446 { 1447 int status = 0; 1448 int32_t larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES 1449 // = (6+12)*6 == 108 1450 1451 Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17); 1452 1453 status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, 1454 streamdata, encData, transcodeParam); 1455 if (status < 0) { 1456 return (status); 1457 } 1458 1459 Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); 1460 1461 return 0; 1462 } 1463 1464 1465 /* decode & dequantize RC */ 1466 int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, int16_t *RCQ15) 1467 { 1468 int k, err; 1469 int16_t index[AR_ORDER]; 1470 1471 /* entropy decoding of quantization indices */ 1472 err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER); 1473 if (err<0) // error check 1474 return err; 1475 1476 /* find quantization levels for reflection coefficients */ 1477 for (k=0; k<AR_ORDER; k++) 1478 { 1479 RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1480 } 1481 1482 return 0; 1483 } 1484 1485 1486 1487 /* quantize & code RC */ 1488 int WebRtcIsacfix_EncodeRcCoef(int16_t *RCQ15, Bitstr_enc *streamdata) 1489 { 1490 int k; 1491 int16_t index[AR_ORDER]; 1492 int status; 1493 1494 /* quantize reflection coefficients (add noise feedback?) */ 1495 for (k=0; k<AR_ORDER; k++) 1496 { 1497 index[k] = WebRtcIsacfix_kRcInitInd[k]; 1498 1499 if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]]) 1500 { 1501 while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1]) 1502 index[k]++; 1503 } 1504 else 1505 { 1506 while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ; 1507 } 1508 1509 RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); 1510 } 1511 1512 1513 /* entropy coding of quantization indices */ 1514 status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER); 1515 1516 /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1517 return status; 1518 } 1519 1520 1521 /* decode & dequantize squared Gain */ 1522 int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, int32_t *gainQ10) 1523 { 1524 int err; 1525 int16_t index; 1526 1527 /* entropy decoding of quantization index */ 1528 err = WebRtcIsacfix_DecHistOneStepMulti( 1529 &index, 1530 streamdata, 1531 WebRtcIsacfix_kGainPtr, 1532 WebRtcIsacfix_kGainInitInd, 1533 1); 1534 /* error check */ 1535 if (err<0) { 1536 return err; 1537 } 1538 1539 /* find quantization level */ 1540 *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1541 1542 return 0; 1543 } 1544 1545 1546 1547 /* quantize & code squared Gain */ 1548 int WebRtcIsacfix_EncodeGain2(int32_t *gainQ10, Bitstr_enc *streamdata) 1549 { 1550 int16_t index; 1551 int status = 0; 1552 1553 /* find quantization index */ 1554 index = WebRtcIsacfix_kGainInitInd[0]; 1555 if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index]) 1556 { 1557 while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1]) 1558 index++; 1559 } 1560 else 1561 { 1562 while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ; 1563 } 1564 1565 /* dequantize */ 1566 *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; 1567 1568 /* entropy coding of quantization index */ 1569 status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1); 1570 1571 /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1572 return status; 1573 } 1574 1575 1576 /* code and decode Pitch Gains and Lags functions */ 1577 1578 /* decode & dequantize Pitch Gains */ 1579 int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, int16_t *PitchGains_Q12) 1580 { 1581 int err; 1582 int16_t index_comb; 1583 const uint16_t *pitch_gain_cdf_ptr[1]; 1584 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; 1591 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]; 1597 1598 return 0; 1599 } 1600 1601 1602 /* quantize & code Pitch Gains */ 1603 int WebRtcIsacfix_EncodePitchGain(int16_t *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) 1604 { 1605 int k,j; 1606 int16_t SQ15[PITCH_SUBFRAMES]; 1607 int16_t index[3]; 1608 int16_t index_comb; 1609 const uint16_t *pitch_gain_cdf_ptr[1]; 1610 int32_t CQ17; 1611 int status = 0; 1612 1613 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 1617 1618 1619 /* find quantization index; only for the first three transform coefficients */ 1620 for (k=0; k<3; k++) 1621 { 1622 /* transform */ 1623 CQ17=0; 1624 for (j=0; j<PITCH_SUBFRAMES; j++) { 1625 CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17 1626 } 1627 1628 index[k] = (int16_t)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8) 1629 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]; 1634 } 1635 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]); 1639 1640 /* unquantize back to pitch gains by table look-up */ 1641 // (Y) 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]; 1646 1647 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); 1651 if (status < 0) { 1652 return status; 1653 } 1654 1655 /* Save data for creation of multiple bitstreams */ 1656 if (encData != NULL) { 1657 encData->pitchGain_index[encData->startIdx] = index_comb; 1658 } 1659 1660 return 0; 1661 } 1662 1663 1664 1665 /* Pitch LAG */ 1666 1667 1668 /* decode & dequantize Pitch Lags */ 1669 int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata, 1670 int16_t *PitchGain_Q12, 1671 int16_t *PitchLags_Q7) 1672 { 1673 int k, err; 1674 int16_t index[PITCH_SUBFRAMES]; 1675 const int16_t *mean_val2Q10, *mean_val4Q10; 1676 1677 const int16_t *lower_limit; 1678 const uint16_t *init_index; 1679 const uint16_t *cdf_size; 1680 const uint16_t **cdf; 1681 1682 int32_t meangainQ12; 1683 int32_t CQ11, CQ10,tmp32a,tmp32b; 1684 int16_t shft,tmp16a,tmp16c; 1685 1686 meangainQ12=0; 1687 for (k = 0; k < 4; k++) 1688 meangainQ12 += PitchGain_Q12[k]; 1689 1690 meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); // Get average 1691 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; 1709 } else { 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; 1717 } 1718 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; 1723 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; 1727 1728 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; 1736 } 1737 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; 1743 } 1744 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; 1750 } 1751 1752 return 0; 1753 } 1754 1755 1756 1757 /* quantize & code Pitch Lags */ 1758 int WebRtcIsacfix_EncodePitchLag(int16_t *PitchLagsQ7,int16_t *PitchGain_Q12, 1759 Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) 1760 { 1761 int k, j; 1762 int16_t index[PITCH_SUBFRAMES]; 1763 int32_t meangainQ12, CQ17; 1764 int32_t CQ11, CQ10,tmp32a; 1765 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; 1770 int32_t tmp32b; 1771 int status = 0; 1772 1773 /* compute mean pitch gain */ 1774 meangainQ12=0; 1775 for (k = 0; k < 4; k++) 1776 meangainQ12 += PitchGain_Q12[k]; 1777 1778 meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); 1779 1780 /* Save data for creation of multiple bitstreams */ 1781 if (encData != NULL) { 1782 encData->meanGain[encData->startIdx] = meangainQ12; 1783 } 1784 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; 1800 } else { 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; 1807 } 1808 1809 /* find quantization index */ 1810 for (k=0; k<4; k++) 1811 { 1812 /* transform */ 1813 CQ17=0; 1814 for (j=0; j<PITCH_SUBFRAMES; j++) 1815 CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17 1816 1817 CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize 1818 1819 /* quantize */ 1820 tmp16b = (int16_t) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 ); 1821 index[k] = tmp16b; 1822 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]; 1827 1828 /* Save data for creation of multiple bitstreams */ 1829 if(encData != NULL) { 1830 encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; 1831 } 1832 } 1833 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 1837 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; 1842 } 1843 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; 1849 } 1850 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; 1856 } 1857 1858 /* entropy coding of quantization pitch lags */ 1859 status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES); 1860 1861 /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ 1862 return status; 1863 } 1864 1865 1866 1867 /* Routines for inband signaling of bandwitdh estimation */ 1868 /* Histograms based on uniform distribution of indices */ 1869 /* Move global variables later! */ 1870 1871 1872 /* cdf array for frame length indicator */ 1873 const uint16_t kFrameLenCdf[4] = { 1874 0, 21845, 43690, 65535}; 1875 1876 /* pointer to cdf array for frame length indicator */ 1877 const uint16_t *kFrameLenCdfPtr[1] = {kFrameLenCdf}; 1878 1879 /* initial cdf index for decoder of frame length indicator */ 1880 const uint16_t kFrameLenInitIndex[1] = {1}; 1881 1882 1883 int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata, 1884 int16_t *framesamples) 1885 { 1886 1887 int err; 1888 int16_t frame_mode; 1889 1890 err = 0; 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; 1895 1896 switch(frame_mode) { 1897 case 1: 1898 *framesamples = 480; /* 30ms */ 1899 break; 1900 case 2: 1901 *framesamples = 960; /* 60ms */ 1902 break; 1903 default: 1904 err = -ISAC_DISALLOWED_FRAME_MODE_DECODER; 1905 } 1906 1907 return err; 1908 } 1909 1910 1911 int WebRtcIsacfix_EncodeFrameLen(int16_t framesamples, Bitstr_enc *streamdata) { 1912 1913 int status; 1914 int16_t frame_mode; 1915 1916 status = 0; 1917 frame_mode = 0; 1918 /* entropy coding of frame length [1:480 samples,2:960 samples] */ 1919 switch(framesamples) { 1920 case 480: 1921 frame_mode = 1; 1922 break; 1923 case 960: 1924 frame_mode = 2; 1925 break; 1926 default: 1927 status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER; 1928 } 1929 1930 if (status < 0) 1931 return status; 1932 1933 status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1); 1934 1935 return status; 1936 } 1937 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, 1942 62804, 65535}; 1943 1944 /* pointer to cdf array for estimated bandwidth */ 1945 const uint16_t *kBwCdfPtr[1] = {kBwCdf}; 1946 1947 /* initial cdf index for decoder of estimated bandwidth*/ 1948 const uint16_t kBwInitIndex[1] = {7}; 1949 1950 1951 int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, int16_t *BWno) { 1952 1953 int err; 1954 int16_t BWno32; 1955 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; 1961 return err; 1962 1963 } 1964 1965 1966 int WebRtcIsacfix_EncodeReceiveBandwidth(int16_t *BWno, Bitstr_enc *streamdata) 1967 { 1968 int status = 0; 1969 /* entropy encoding of receiver's BW estimation [0..23] */ 1970 status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1); 1971 1972 return status; 1973 } 1974 1975 /* estimate codel length of LPC Coef */ 1976 void WebRtcIsacfix_TranscodeLpcCoef(int32_t *gain_lo_hiQ17, 1977 int16_t *index_gQQ) { 1978 int j, k; 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]; 1984 int32_t sumQQ; 1985 1986 1987 /* log gains, mean removal and scaling */ 1988 posg = 0; gainpos=0; 1989 1990 for (k=0; k<SUBFRAMES; k++) { 1991 /* log gains */ 1992 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 2000 subtracted */ 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 2003 posg++; gainpos++; 2004 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 2007 posg++; gainpos++; 2008 2009 } 2010 2011 2012 /* KLT */ 2013 2014 /* left transform */ 2015 for (j = 0, offsg = 0; j < SUBFRAMES; j++, offsg += 2) { 2016 // Q21 = Q6 * Q15 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; 2022 2023 // Q21 = Q6 * Q15 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; 2029 } 2030 2031 /* right transform */ 2032 WebRtcIsacfix_MatrixProduct2(WebRtcIsacfix_kT2GainQ15[0], tmpcoeffs2_gQ21, 2033 tmpcoeffs_gQ17, kTIndexFactor3, kTIndexStep1); 2034 2035 /* quantize coefficients */ 2036 for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? 2037 { 2038 posQQ = WebRtcIsacfix_kSelIndGain[k]; 2039 pos2QQ= (int16_t)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); 2040 2041 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? 2042 if (index_gQQ[k] < 0) { 2043 index_gQQ[k] = 0; 2044 } 2045 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { 2046 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; 2047 } 2048 } 2049 } 2050