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