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