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 * decode_plc.c 13 * 14 * Packet Loss Concealment. 15 * 16 */ 17 18 #include <string.h> 19 20 #include "settings.h" 21 #include "entropy_coding.h" 22 #include "pitch_estimator.h" 23 #include "bandwidth_estimator.h" 24 #include "structs.h" 25 #include "codec.h" 26 27 28 #define NO_OF_PRIMES 8 29 #define NOISE_FILTER_LEN 30 30 31 /* 32 * function to decode the bitstream 33 * returns the total number of bytes in the stream 34 */ 35 36 static int16_t plc_filterma_Fast( 37 int16_t *In, /* (i) Vector to be filtered. InOut[-orderCoef+1] 38 to InOut[-1] contains state */ 39 int16_t *Out, /* (o) Filtered vector */ 40 int16_t *B, /* (i) The filter coefficients (in Q0) */ 41 int16_t Blen, /* (i) Number of B coefficients */ 42 int16_t len, /* (i) Number of samples to be filtered */ 43 int16_t reduceDecay, 44 int16_t decay, 45 int16_t rshift ) 46 { 47 int i, j; 48 int32_t o; 49 int32_t lim = (1 << (15 + rshift)) - 1; 50 51 for (i = 0; i < len; i++) 52 { 53 const int16_t *b_ptr = &B[0]; 54 const int16_t *x_ptr = &In[i]; 55 56 o = (int32_t)0; 57 58 for (j = 0;j < Blen; j++) 59 { 60 o = WebRtcSpl_AddSatW32(o, *b_ptr * *x_ptr); 61 b_ptr++; 62 x_ptr--; 63 } 64 65 /* to round off correctly */ 66 o = WebRtcSpl_AddSatW32(o, 1 << (rshift - 1)); 67 68 /* saturate according to the domain of the filter coefficients */ 69 o = WEBRTC_SPL_SAT((int32_t)lim, o, (int32_t)-lim); 70 71 /* o should be in the range of int16_t */ 72 o >>= rshift; 73 74 /* decay the output signal; this is specific to plc */ 75 *Out++ = (int16_t)((int16_t)o * decay >> 15); 76 77 /* change the decay */ 78 decay -= reduceDecay; 79 if( decay < 0 ) 80 decay = 0; 81 } 82 return( decay ); 83 } 84 85 86 87 88 89 90 91 92 static __inline int32_t log2_Q8_T( uint32_t x ) { 93 94 int32_t zeros; 95 int16_t frac; 96 97 zeros=WebRtcSpl_NormU32(x); 98 frac = (int16_t)(((x << zeros) & 0x7FFFFFFF) >> 23); 99 100 /* log2(magn(i)) */ 101 return ((31 - zeros) << 8) + frac; 102 } 103 104 static __inline int16_t exp2_Q10_T(int16_t x) { // Both in and out in Q10 105 106 int16_t tmp16_1, tmp16_2; 107 108 tmp16_2=(int16_t)(0x0400|(x&0x03FF)); 109 tmp16_1 = -(x >> 10); 110 if(tmp16_1>0) 111 return tmp16_2 >> tmp16_1; 112 else 113 return tmp16_2 << -tmp16_1; 114 115 } 116 117 118 /* 119 This is a fixed-point version of the above code with limLow = 700 and limHigh = 5000, 120 hard-coded. The values 700 and 5000 were experimentally obtained. 121 122 The function implements membership values for two sets. The mebership functions are 123 of second orders corresponding to half-bell-shapped pulses. 124 */ 125 static void MemshipValQ15( int16_t in, int16_t *A, int16_t *B ) 126 { 127 int16_t x; 128 129 in -= 700; /* translate the lowLim to 0, limHigh = 5000 - 700, M = 2150 */ 130 131 if( in <= 2150 ) 132 { 133 if( in > 0 ) 134 { 135 /* b = in^2 / (2 * M^2), a = 1 - b in Q0. 136 We have to compute in Q15 */ 137 138 /* x = in / 2150 {in Q15} = x * 15.2409 {in Q15} = 139 x*15 + (x*983)/(2^12); note that 983/2^12 = 0.23999 */ 140 141 /* we are sure that x is in the range of int16_t */ 142 x = (int16_t)(in * 15 + (in * 983 >> 12)); 143 /* b = x^2 / 2 {in Q15} so a shift of 16 is required to 144 be in correct domain and one more for the division by 2 */ 145 *B = (int16_t)((x * x + 0x00010000) >> 17); 146 *A = WEBRTC_SPL_WORD16_MAX - *B; 147 } 148 else 149 { 150 *B = 0; 151 *A = WEBRTC_SPL_WORD16_MAX; 152 } 153 } 154 else 155 { 156 if( in < 4300 ) 157 { 158 /* This is a mirror case of the above */ 159 in = 4300 - in; 160 x = (int16_t)(in * 15 + (in * 983 >> 12)); 161 /* b = x^2 / 2 {in Q15} so a shift of 16 is required to 162 be in correct domain and one more for the division by 2 */ 163 *A = (int16_t)((x * x + 0x00010000) >> 17); 164 *B = WEBRTC_SPL_WORD16_MAX - *A; 165 166 } 167 else 168 { 169 *A = 0; 170 *B = WEBRTC_SPL_WORD16_MAX; 171 } 172 } 173 } 174 175 176 177 178 static void LinearResampler(int16_t* in, 179 int16_t* out, 180 size_t lenIn, 181 size_t lenOut) 182 { 183 size_t n = (lenIn - 1) * RESAMP_RES; 184 int16_t resOut, relativePos, diff; /* */ 185 size_t i, j; 186 uint16_t udiff; 187 188 if( lenIn == lenOut ) 189 { 190 WEBRTC_SPL_MEMCPY_W16( out, in, lenIn ); 191 return; 192 } 193 194 resOut = WebRtcSpl_DivW32W16ResW16( (int32_t)n, (int16_t)(lenOut-1) ); 195 196 out[0] = in[0]; 197 for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ ) 198 { 199 200 relativePos += resOut; 201 while( relativePos > RESAMP_RES ) 202 { 203 j++; 204 relativePos -= RESAMP_RES; 205 } 206 207 208 /* an overflow may happen and the differce in sample values may 209 * require more than 16 bits. We like to avoid 32 bit arithmatic 210 * as much as possible */ 211 212 if( (in[ j ] > 0) && (in[j + 1] < 0) ) 213 { 214 udiff = (uint16_t)(in[ j ] - in[j + 1]); 215 out[ i ] = in[ j ] - (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT); 216 } 217 else 218 { 219 if( (in[j] < 0) && (in[j+1] > 0) ) 220 { 221 udiff = (uint16_t)( in[j + 1] - in[ j ] ); 222 out[ i ] = in[ j ] + (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT); 223 } 224 else 225 { 226 diff = in[ j + 1 ] - in[ j ]; 227 out[i] = in[j] + (int16_t)(diff * relativePos >> RESAMP_RES_BIT); 228 } 229 } 230 } 231 } 232 233 234 235 236 237 void WebRtcIsacfix_DecodePlcImpl(int16_t *signal_out16, 238 IsacFixDecoderInstance *ISACdec_obj, 239 size_t *current_framesamples ) 240 { 241 int subframecnt; 242 243 int16_t* Vector_Word16_1; 244 int16_t Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; 245 int16_t* Vector_Word16_2; 246 int16_t Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; 247 248 int32_t Vector_Word32_1[FRAMESAMPLES_HALF]; 249 int32_t Vector_Word32_2[FRAMESAMPLES_HALF]; 250 251 int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs 252 int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs 253 254 int16_t pitchLags_Q7[PITCH_SUBFRAMES]; 255 int16_t pitchGains_Q12[PITCH_SUBFRAMES]; 256 257 int16_t tmp_1, tmp_2; 258 int32_t tmp32a, tmp32b; 259 int16_t gainQ13; 260 261 int16_t myDecayRate; 262 263 /* ---------- PLC variables ------------ */ 264 size_t lag0, i, k; 265 int16_t noiseIndex; 266 int16_t stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10]; 267 268 int32_t gain_lo_hiQ17[2*SUBFRAMES]; 269 270 int16_t nLP, pLP, wNoisyLP, wPriodicLP, tmp16; 271 size_t minIdx; 272 int32_t nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff; 273 int16_t noise1, rshift; 274 275 276 int16_t ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs; 277 int32_t varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs; 278 int rightShiftIn, rightShiftOut; 279 280 281 /* ------------------------------------- */ 282 283 284 myDecayRate = (DECAY_RATE); 285 Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN]; 286 Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN]; 287 288 289 /* ----- Simply Copy Previous LPC parameters ------ */ 290 for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ ) 291 { 292 /* lower Band */ 293 WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ], 294 (ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO); 295 gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0]; 296 297 /* Upper Band */ 298 WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ], 299 (ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI); 300 gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1]; 301 } 302 303 304 305 306 lag0 = (size_t)(((ISACdec_obj->plcstr_obj.lastPitchLag_Q7 + 64) >> 7) + 1); 307 308 309 if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED ) 310 { 311 (ISACdec_obj->plcstr_obj).pitchCycles = 0; 312 313 (ISACdec_obj->plcstr_obj).lastPitchLP = 314 &((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]); 315 minCorr = WEBRTC_SPL_WORD32_MAX; 316 317 if ((FRAMESAMPLES_HALF - 10) > 2 * lag0) 318 { 319 minIdx = 11; 320 for( i = 0; i < 21; i++ ) 321 { 322 corr = 0; 323 for( k = 0; k < lag0; k++ ) 324 { 325 corr = WebRtcSpl_AddSatW32(corr, WEBRTC_SPL_ABS_W32( 326 WebRtcSpl_SubSatW16( 327 (ISACdec_obj->plcstr_obj).lastPitchLP[k], 328 (ISACdec_obj->plcstr_obj).prevPitchInvIn[ 329 FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) ); 330 } 331 if( corr < minCorr ) 332 { 333 minCorr = corr; 334 minIdx = i; 335 } 336 } 337 (ISACdec_obj->plcstr_obj).prevPitchLP = 338 &( (ISACdec_obj->plcstr_obj).prevPitchInvIn[ 339 FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] ); 340 } 341 else 342 { 343 (ISACdec_obj->plcstr_obj).prevPitchLP = 344 (ISACdec_obj->plcstr_obj).lastPitchLP; 345 } 346 pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12; 347 348 WebRtcSpl_AutoCorrelation( 349 &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0], 350 lag0, 0, &varIn, &rightShiftIn); 351 WebRtcSpl_AutoCorrelation( 352 &(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0], 353 lag0, 0, &varOut, &rightShiftOut); 354 355 maxAbs = 0; 356 for( i = 0; i< lag0; i++) 357 { 358 myAbs = WEBRTC_SPL_ABS_W16( 359 (ISACdec_obj->plcstr_obj).prevPitchInvOut[ 360 PITCH_MAX_LAG + 10 - lag0 + i] ); 361 maxAbs = (myAbs > maxAbs)? myAbs:maxAbs; 362 } 363 logVarIn = log2_Q8_T( (uint32_t)( varIn ) ) + 364 (int32_t)(rightShiftIn << 8); 365 logVarOut = log2_Q8_T( (uint32_t)( varOut ) ) + 366 (int32_t)(rightShiftOut << 8); 367 logMaxAbs = log2_Q8_T( (uint32_t)( maxAbs ) ); 368 369 ltpGain = (int16_t)(logVarOut - logVarIn); 370 Q = 2 * logMaxAbs - ( logVarOut - 1512 ); 371 372 /* 373 * --- 374 * We are computing sqrt( (VarIn/lag0) / var( noise ) ) 375 * var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8 376 * so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) ) ). 377 * Note that put log function is in Q8 but the exponential function is in Q10. 378 * -- 379 */ 380 381 logVarIn -= log2_Q8_T( (uint32_t)( lag0 ) ); 382 tmp16 = (int16_t)((logVarIn<<1) - (4<<10) ); 383 rightShiftIn = 0; 384 if( tmp16 > 4096 ) 385 { 386 tmp16 -= 4096; 387 tmp16 = exp2_Q10_T( tmp16 ); 388 tmp16 >>= 6; 389 } 390 else 391 tmp16 = exp2_Q10_T( tmp16 )>>10; 392 393 (ISACdec_obj->plcstr_obj).std = tmp16 - 4; 394 395 if( (ltpGain < 110) || (ltpGain > 230) ) 396 { 397 if( ltpGain < 100 && (pitchGain < 1800) ) 398 { 399 (ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX; 400 } 401 else 402 { 403 (ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800) 404 )? WEBRTC_SPL_WORD16_MAX:0; 405 } 406 (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - 407 (ISACdec_obj->plcstr_obj).A; 408 } 409 else 410 { 411 if( (pitchGain < 450) || (pitchGain > 1600) ) 412 { 413 (ISACdec_obj->plcstr_obj).A = ((pitchGain < 450) 414 )? WEBRTC_SPL_WORD16_MAX:0; 415 (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - 416 (ISACdec_obj->plcstr_obj).A; 417 } 418 else 419 { 420 myVoiceIndicator = ltpGain * 2 + pitchGain; 421 MemshipValQ15( myVoiceIndicator, 422 &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); 423 } 424 } 425 426 427 428 myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8); 429 MemshipValQ15( myVoiceIndicator, 430 &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); 431 432 433 434 (ISACdec_obj->plcstr_obj).stretchLag = lag0; 435 (ISACdec_obj->plcstr_obj).pitchIndex = 0; 436 437 } 438 else 439 { 440 myDecayRate = (DECAY_RATE<<2); 441 } 442 443 if( (ISACdec_obj->plcstr_obj).B < 1000 ) 444 { 445 myDecayRate += (DECAY_RATE<<3); 446 } 447 448 /* ------------ reconstructing the residual signal ------------------ */ 449 450 LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, 451 stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 452 /* inverse pitch filter */ 453 454 pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] = 455 (int16_t)((ISACdec_obj->plcstr_obj).stretchLag<<7); 456 pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12); 457 pitchGains_Q12[2] = (int16_t)(pitchGains_Q12[3] * 1010 >> 10); 458 pitchGains_Q12[1] = (int16_t)(pitchGains_Q12[2] * 1010 >> 10); 459 pitchGains_Q12[0] = (int16_t)(pitchGains_Q12[1] * 1010 >> 10); 460 461 462 /* most of the time either B or A are zero so seperating */ 463 if( (ISACdec_obj->plcstr_obj).B == 0 ) 464 { 465 for( i = 0; i < FRAMESAMPLES_HALF; i++ ) 466 { 467 /* --- Low Pass */ 468 (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 469 (ISACdec_obj->plcstr_obj).seed ); 470 Vector_Word16_1[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 471 472 /* --- Highpass */ 473 (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 474 (ISACdec_obj->plcstr_obj).seed ); 475 Vector_Word16_2[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 476 477 } 478 for( i = 1; i < NOISE_FILTER_LEN; i++ ) 479 { 480 (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 481 (ISACdec_obj->plcstr_obj).seed ); 482 Vector_Word16_Extended_1[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 483 484 (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 485 (ISACdec_obj->plcstr_obj).seed ); 486 Vector_Word16_Extended_2[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 487 } 488 plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1, 489 &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - 490 NOISE_FILTER_LEN], (int16_t) NOISE_FILTER_LEN, 491 (int16_t) FRAMESAMPLES_HALF, (int16_t)(5), 492 (ISACdec_obj->plcstr_obj).decayCoeffNoise, (int16_t)(6)); 493 494 maxCoeff = WebRtcSpl_MaxAbsValueW32( 495 &(ISACdec_obj->plcstr_obj).prevHP[ 496 PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN ); 497 498 rshift = 0; 499 while( maxCoeff > WEBRTC_SPL_WORD16_MAX ) 500 { 501 maxCoeff >>= 1; 502 rshift++; 503 } 504 for( i = 0; i < NOISE_FILTER_LEN; i++ ) { 505 Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =(int16_t)( 506 ISACdec_obj->plcstr_obj.prevHP[PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + 507 i] >> rshift); 508 } 509 (ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast( 510 Vector_Word16_2, 511 Vector_Word16_Extended_2, 512 &Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN], 513 (int16_t) NOISE_FILTER_LEN, 514 (int16_t) FRAMESAMPLES_HALF, 515 (int16_t) (5), 516 (ISACdec_obj->plcstr_obj).decayCoeffNoise, 517 (int16_t) (7) ); 518 519 for( i = 0; i < FRAMESAMPLES_HALF; i++ ) 520 Vector_Word32_2[i] = Vector_Word16_Extended_2[i] << rshift; 521 522 Vector_Word16_1 = Vector_Word16_Extended_1; 523 } 524 else 525 { 526 if( (ISACdec_obj->plcstr_obj).A == 0 ) 527 { 528 /* ------ Periodic Vector --- */ 529 for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) 530 { 531 /* --- Lowpass */ 532 pLP = (int16_t)(stretchPitchLP[ISACdec_obj->plcstr_obj.pitchIndex] * 533 ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 534 535 /* --- Highpass */ 536 pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 537 (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 538 (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - 539 (ISACdec_obj->plcstr_obj).stretchLag + 540 (ISACdec_obj->plcstr_obj).pitchIndex] ); 541 542 /* --- lower the muliplier (more decay at next sample) --- */ 543 (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); 544 if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) 545 (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; 546 547 (ISACdec_obj->plcstr_obj).pitchIndex++; 548 549 if( (ISACdec_obj->plcstr_obj).pitchIndex == 550 (ISACdec_obj->plcstr_obj).stretchLag ) 551 { 552 (ISACdec_obj->plcstr_obj).pitchIndex = 0; 553 (ISACdec_obj->plcstr_obj).pitchCycles++; 554 555 if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) 556 { 557 (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; 558 } 559 else 560 { 561 (ISACdec_obj->plcstr_obj).stretchLag = lag0; 562 } 563 564 (ISACdec_obj->plcstr_obj).stretchLag = ( 565 (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG 566 )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; 567 568 LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, 569 stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 570 571 LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP, 572 stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 573 574 switch( (ISACdec_obj->plcstr_obj).pitchCycles ) 575 { 576 case 1: 577 { 578 for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 579 { 580 stretchPitchLP[k] = (int16_t)(( 581 (int32_t)stretchPitchLP[k]* 3 + 582 (int32_t)stretchPitchLP1[k])>>2); 583 } 584 break; 585 } 586 case 2: 587 { 588 for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 589 { 590 stretchPitchLP[k] = (int16_t)(( 591 (int32_t)stretchPitchLP[k] + 592 (int32_t)stretchPitchLP1[k] )>>1); 593 } 594 break; 595 } 596 case 3: 597 { 598 for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 599 { 600 stretchPitchLP[k] = (int16_t)((stretchPitchLP[k] + 601 (int32_t)stretchPitchLP1[k]*3 )>>2); 602 } 603 break; 604 } 605 } 606 607 if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) 608 { 609 myDecayRate += 35; //(myDecayRate>>1); 610 (ISACdec_obj->plcstr_obj).pitchCycles = 0; 611 } 612 613 } 614 615 /* ------ Sum the noisy and periodic signals ------ */ 616 Vector_Word16_1[i] = pLP; 617 Vector_Word32_2[i] = pHP; 618 } 619 } 620 else 621 { 622 for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) 623 { 624 625 (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 626 (ISACdec_obj->plcstr_obj).seed ); 627 628 noise1 = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 629 630 nLP = (int16_t)((int16_t)(noise1 * ISACdec_obj->plcstr_obj.std) * 631 ISACdec_obj->plcstr_obj.decayCoeffNoise >> 15); 632 633 /* --- Highpass */ 634 (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 635 (ISACdec_obj->plcstr_obj).seed ); 636 noise1 = (ISACdec_obj->plcstr_obj.seed >> 11) - 8; 637 638 nHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 639 (ISACdec_obj->plcstr_obj).decayCoeffNoise, 640 (int32_t)(noise1*(ISACdec_obj->plcstr_obj).std) ); 641 642 /* --- lower the muliplier (more decay at next sample) --- */ 643 (ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate); 644 if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 ) 645 (ISACdec_obj->plcstr_obj).decayCoeffNoise = 0; 646 647 /* ------ Periodic Vector --- */ 648 /* --- Lowpass */ 649 pLP = (int16_t)(stretchPitchLP[ISACdec_obj->plcstr_obj.pitchIndex] * 650 ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 651 652 /* --- Highpass */ 653 pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 654 (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 655 (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - 656 (ISACdec_obj->plcstr_obj).stretchLag + 657 (ISACdec_obj->plcstr_obj).pitchIndex] ); 658 659 /* --- lower the muliplier (more decay at next sample) --- */ 660 (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); 661 if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) 662 { 663 (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; 664 } 665 666 /* ------ Weighting the noisy and periodic vectors ------- */ 667 wNoisyLP = (int16_t)(ISACdec_obj->plcstr_obj.A * nLP >> 15); 668 wNoisyHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15( 669 (ISACdec_obj->plcstr_obj).A, (nHP) ) ); 670 671 wPriodicLP = (int16_t)(ISACdec_obj->plcstr_obj.B * pLP >> 15); 672 wPriodicHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15( 673 (ISACdec_obj->plcstr_obj).B, pHP)); 674 675 (ISACdec_obj->plcstr_obj).pitchIndex++; 676 677 if((ISACdec_obj->plcstr_obj).pitchIndex == 678 (ISACdec_obj->plcstr_obj).stretchLag) 679 { 680 (ISACdec_obj->plcstr_obj).pitchIndex = 0; 681 (ISACdec_obj->plcstr_obj).pitchCycles++; 682 683 if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) 684 (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; 685 else 686 (ISACdec_obj->plcstr_obj).stretchLag = lag0; 687 688 (ISACdec_obj->plcstr_obj).stretchLag = ( 689 (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG 690 )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; 691 LinearResampler( 692 (ISACdec_obj->plcstr_obj).lastPitchLP, 693 stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 694 695 LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP, 696 stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 697 698 switch((ISACdec_obj->plcstr_obj).pitchCycles) 699 { 700 case 1: 701 { 702 for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 703 { 704 stretchPitchLP[k] = (int16_t)(( 705 (int32_t)stretchPitchLP[k]* 3 + 706 (int32_t)stretchPitchLP1[k] )>>2); 707 } 708 break; 709 } 710 case 2: 711 { 712 for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 713 { 714 stretchPitchLP[k] = (int16_t)(( 715 (int32_t)stretchPitchLP[k] + 716 (int32_t)stretchPitchLP1[k])>>1); 717 } 718 break; 719 } 720 case 3: 721 { 722 for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 723 { 724 stretchPitchLP[k] = (int16_t)( 725 (stretchPitchLP[k] + 726 (int32_t)stretchPitchLP1[k]*3 )>>2); 727 } 728 break; 729 } 730 } 731 732 if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) 733 { 734 myDecayRate += 55; //(myDecayRate>>1); 735 (ISACdec_obj->plcstr_obj).pitchCycles = 0; 736 } 737 } 738 739 /* ------ Sum the noisy and periodic signals ------ */ 740 Vector_Word16_1[i] = WebRtcSpl_AddSatW16(wNoisyLP, wPriodicLP); 741 Vector_Word32_2[i] = WebRtcSpl_AddSatW32(wNoisyHP, wPriodicHP); 742 } 743 } 744 } 745 /* ----------------- residual signal is reconstructed ------------------ */ 746 747 k = (ISACdec_obj->plcstr_obj).pitchIndex; 748 /* --- Write one pitch cycle for recovery block --- */ 749 750 for( i = 0; i < RECOVERY_OVERLAP; i++ ) 751 { 752 ISACdec_obj->plcstr_obj.overlapLP[i] = (int16_t)( 753 stretchPitchLP[k] * ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 754 k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0; 755 } 756 757 (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = 758 (int16_t)((ISACdec_obj->plcstr_obj).stretchLag << 7); 759 760 761 /* --- Inverse Pitch Filter --- */ 762 WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, 763 &ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4); 764 765 /* reduce gain to compensate for pitch enhancer */ 766 /* gain = 1.0f - 0.45f * AvgPitchGain; */ 767 tmp32a = ISACdec_obj->plcstr_obj.AvgPitchGain_Q12 * 29; // Q18 768 tmp32b = 262144 - tmp32a; // Q18 769 gainQ13 = (int16_t) (tmp32b >> 5); // Q13 770 771 /* perceptual post-filtering (using normalized lattice filter) */ 772 for (k = 0; k < FRAMESAMPLES_HALF; k++) 773 Vector_Word32_1[k] = (Vector_Word16_2[k] * gainQ13) << 3; // Q25 774 775 776 WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, 777 (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0, 778 Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1); 779 780 WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, 781 (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0, 782 Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2); 783 784 /* recombine the 2 bands */ 785 786 /* Form the polyphase signals, and compensate for DC offset */ 787 for (k=0;k<FRAMESAMPLES_HALF;k++) 788 { 789 /* Construct a new upper channel signal*/ 790 tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16( 791 ((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); 792 /* Construct a new lower channel signal*/ 793 tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16( 794 ((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); 795 Vector_Word16_1[k] = tmp_1; 796 Vector_Word16_2[k] = tmp_2; 797 } 798 799 800 WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, 801 Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj); 802 803 (ISACdec_obj->plcstr_obj).used = PLC_WAS_USED; 804 *current_framesamples = 480; 805 } 806