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