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