decode_plc.c revision 0946a56023d821e0deca04029bb016ae1f23aa82
1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * decode_plc.c
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Packet Loss Concealment.
15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <string.h>
19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "settings.h"
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "entropy_coding.h"
22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "pitch_estimator.h"
23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "bandwidth_estimator.h"
24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "structs.h"
25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "codec.h"
26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define NO_OF_PRIMES 8
29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define NOISE_FILTER_LEN 30
30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * function to decode the bitstream
33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * returns the total number of bytes in the stream
34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic int16_t plc_filterma_Fast(
370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *In,  /* (i)   Vector to be filtered. InOut[-orderCoef+1]
38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                           to InOut[-1] contains state */
390946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *Out,  /* (o)   Filtered vector */
400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *B,   /* (i)   The filter coefficients (in Q0) */
410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t Blen,  /* (i)   Number of B coefficients */
420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t len,   /* (i)  Number of samples to be filtered */
430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t reduceDecay,
440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t decay,
450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t rshift )
46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int i, j;
480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t o;
490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t lim;
50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  lim = WEBRTC_SPL_LSHIFT_W32( (int32_t)1, 15 + rshift )-1;
52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (i = 0; i < len; i++)
54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    G_CONST int16_t *b_ptr = &B[0];
560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    G_CONST int16_t *x_ptr = &In[i];
57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    o = (int32_t)0;
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    for (j = 0;j < Blen; j++)
61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_MUL_16_16( *b_ptr, *x_ptr) );
63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      b_ptr++;
64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      x_ptr--;
65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* to round off correctly */
68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_LSHIFT_W32( 1, (rshift-1) ) );
69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* saturate according to the domain of the filter coefficients */
710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    o = WEBRTC_SPL_SAT((int32_t)lim, o, (int32_t)-lim);
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    /* o should be in the range of int16_t */
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    o = WEBRTC_SPL_RSHIFT_W32( o, rshift );
75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* decay the output signal; this is specific to plc */
770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    *Out++ = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( (int16_t)o, decay, 15); // ((o + (int32_t)2048) >> 12);
78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* change the decay */
80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    decay -= reduceDecay;
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( decay < 0 )
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      decay = 0;
83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return( decay );
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
940946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic __inline int32_t log2_Q8_T( uint32_t x ) {
95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
960946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t zeros, lg2;
970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t frac;
98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  zeros=WebRtcSpl_NormU32(x);
1000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  frac=(int16_t)WEBRTC_SPL_RSHIFT_W32(((uint32_t)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);
101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* log2(magn(i)) */
102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac);
104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return lg2;
105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1080946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic __inline int16_t  exp2_Q10_T(int16_t x) { // Both in and out in Q10
109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t tmp16_1, tmp16_2;
111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1120946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  tmp16_2=(int16_t)(0x0400|(x&0x03FF));
1130946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  tmp16_1=-(int16_t)WEBRTC_SPL_RSHIFT_W16(x,10);
114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if(tmp16_1>0)
1150946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    return (int16_t) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
1170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    return (int16_t) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  This is a fixed-point version of the above code with limLow = 700 and limHigh = 5000,
124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  hard-coded. The values 700 and 5000 were experimentally obtained.
125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  The function implements membership values for two sets. The mebership functions are
127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  of second orders corresponding to half-bell-shapped pulses.
128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/
1290946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void MemshipValQ15( int16_t in, int16_t *A, int16_t *B )
130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t x;
132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  in -= 700;    /* translate the lowLim to 0, limHigh = 5000 - 700, M = 2150 */
134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if( in <= 2150 )
136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( in > 0 )
138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* b = in^2 / (2 * M^2), a = 1 - b in Q0.
140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com         We have to compute in Q15 */
141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* x = in / 2150 {in Q15} = x * 15.2409 {in Q15} =
143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com         x*15 + (x*983)/(2^12); note that 983/2^12 = 0.23999     */
144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      /* we are sure that x is in the range of int16_t            */
1460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      x = (int16_t)( WEBRTC_SPL_MUL_16_16( in, 15 ) +
147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                           WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* b = x^2 / 2 {in Q15} so a shift of 16 is required to
149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com         be in correct domain and one more for the division by 2 */
1500946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      *B = (int16_t)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      *A = WEBRTC_SPL_WORD16_MAX - *B;
152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      *B = 0;
156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      *A = WEBRTC_SPL_WORD16_MAX;
157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( in < 4300 )
162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* This is a mirror case of the above */
164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      in = 4300 - in;
1650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      x = (int16_t)( WEBRTC_SPL_MUL_16_16( in, 15 ) +
166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                           WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* b = x^2 / 2 {in Q15} so a shift of 16 is required to
168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com         be in correct domain and one more for the division by 2 */
1690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      *A = (int16_t)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      *B = WEBRTC_SPL_WORD16_MAX - *A;
171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      *A = 0;
176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      *B = WEBRTC_SPL_WORD16_MAX;
177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1840946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void LinearResampler( int16_t *in, int16_t *out, int16_t lenIn, int16_t lenOut )
185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t n;
1870946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t resOut, i, j, relativePos, diff; /* */
1880946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  uint16_t udiff;
189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if( lenIn == lenOut )
191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WEBRTC_SPL_MEMCPY_W16( out, in, lenIn );
193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return;
194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1960946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  n = WEBRTC_SPL_MUL_16_16( (int16_t)(lenIn-1), RESAMP_RES );
1970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  resOut = WebRtcSpl_DivW32W16ResW16( n, (int16_t)(lenOut-1) );
198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  out[0] = in[0];
200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ )
201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    relativePos += resOut;
204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    while( relativePos > RESAMP_RES )
205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      j++;
207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      relativePos -= RESAMP_RES;
208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* an overflow may happen and the differce in sample values may
212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * require more than 16 bits. We like to avoid 32 bit arithmatic
213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * as much as possible */
214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( (in[ j ] > 0) && (in[j + 1] < 0) )
216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
2170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      udiff = (uint16_t)(in[ j ] - in[j + 1]);
2180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      out[ i ] = in[ j ] - (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT);
219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      if( (in[j] < 0) && (in[j+1] > 0) )
223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
2240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        udiff = (uint16_t)( in[j + 1] - in[ j ] );
2250946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        out[ i ] = in[ j ] + (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT);
226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      else
228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        diff = in[ j + 1 ] - in[ j ];
2300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        out[ i ] = in[ j ] + (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( diff, relativePos, RESAMP_RES_BIT );
231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecodePlcImpl(int16_t *signal_out16,
2410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                    ISACFIX_DecInst_t *ISACdec_obj,
2420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                    int16_t *current_framesamples )
243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int subframecnt;
2450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t len = 0;
246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t* Vector_Word16_1;
2480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t  Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN];
2490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t* Vector_Word16_2;
2500946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t  Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN];
251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2520946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t Vector_Word32_1[FRAMESAMPLES_HALF];
2530946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t Vector_Word32_2[FRAMESAMPLES_HALF];
254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
2560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t pitchLags_Q7[PITCH_SUBFRAMES];
2590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t pitchGains_Q12[PITCH_SUBFRAMES];
260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t tmp_1, tmp_2;
2620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t tmp32a, tmp32b;
2630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t gainQ13;
264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t myDecayRate;
266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* ---------- PLC variables ------------ */
2680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t lag0, i, k, noiseIndex;
2690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10];
270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t gain_lo_hiQ17[2*SUBFRAMES];
272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t nLP, pLP, wNoisyLP, wPriodicLP, tmp16, minIdx;
2740946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff;
2750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t noise1, rshift;
276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs;
2790946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs;
280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int rightShiftIn, rightShiftOut;
281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* ------------------------------------- */
284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  myDecayRate = (DECAY_RATE);
287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN];
288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN];
289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* ----- Simply Copy Previous LPC parameters ------ */
292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ )
293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* lower Band */
295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ],
296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                          (ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO);
297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0];
298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Upper Band */
300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ],
301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                          (ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI);
302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1];
303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  lag0 = WEBRTC_SPL_RSHIFT_W16(
309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 + 64, 7 ) + 1;
310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED )
313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (ISACdec_obj->plcstr_obj).pitchCycles = 0;
315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (ISACdec_obj->plcstr_obj).lastPitchLP =
317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        &((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]);
318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    minCorr = WEBRTC_SPL_WORD32_MAX;
319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ( (FRAMESAMPLES_HALF - 2*lag0 - 10) > 0 )
321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      minIdx = 11;
323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      for( i = 0; i < 21; i++ )
324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        corr = 0;
326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        for( k = 0; k < lag0; k++ )
327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          corr = WEBRTC_SPL_ADD_SAT_W32( corr, WEBRTC_SPL_ABS_W32(
329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              WEBRTC_SPL_SUB_SAT_W16(
330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                  (ISACdec_obj->plcstr_obj).lastPitchLP[k],
331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                  (ISACdec_obj->plcstr_obj).prevPitchInvIn[
332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) );
333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if( corr < minCorr )
335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          minCorr = corr;
337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          minIdx = i;
338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).prevPitchLP =
341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          &( (ISACdec_obj->plcstr_obj).prevPitchInvIn[
342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] );
343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).prevPitchLP =
347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).lastPitchLP;
348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12;
350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcSpl_AutoCorrelation(
352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0],
353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        lag0, 0, &varIn, &rightShiftIn);
354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcSpl_AutoCorrelation(
355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        &(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0],
356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        lag0, 0, &varOut, &rightShiftOut);
357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    maxAbs = 0;
359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    for( i = 0; i< lag0; i++)
360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      myAbs = WEBRTC_SPL_ABS_W16(
362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).prevPitchInvOut[
363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              PITCH_MAX_LAG + 10 - lag0 + i] );
364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      maxAbs = (myAbs > maxAbs)? myAbs:maxAbs;
365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
3660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    logVarIn = log2_Q8_T( (uint32_t)( varIn ) ) +
3670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        (int32_t)(rightShiftIn << 8);
3680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    logVarOut = log2_Q8_T( (uint32_t)( varOut ) ) +
3690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        (int32_t)(rightShiftOut << 8);
3700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    logMaxAbs = log2_Q8_T( (uint32_t)( maxAbs ) );
371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    ltpGain = (int16_t)(logVarOut - logVarIn);
373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Q = 2 * logMaxAbs - ( logVarOut - 1512 );
374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /*
376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * ---
377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * We are computing sqrt( (VarIn/lag0) / var( noise ) )
378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8
379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) )  ).
380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * Note that put log function is in Q8 but the exponential function is in Q10.
381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     * --
382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com     */
383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3840946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    logVarIn -= log2_Q8_T( (uint32_t)( lag0 ) );
3850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    tmp16 = (int16_t)((logVarIn<<1) - (4<<10) );
386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    rightShiftIn = 0;
387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( tmp16 > 4096 )
388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      tmp16 -= 4096;
390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      tmp16 = exp2_Q10_T( tmp16 );
391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      tmp16 >>= 6;
392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      tmp16 = exp2_Q10_T( tmp16 )>>10;
395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (ISACdec_obj->plcstr_obj).std = tmp16 - 4;
397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( (ltpGain < 110) || (ltpGain > 230) )
399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      if( ltpGain < 100 && (pitchGain < 1800) )
401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX;
403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      else
405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800)
407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                       )? WEBRTC_SPL_WORD16_MAX:0;
408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX -
410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).A;
411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      if( (pitchGain < 450) || (pitchGain > 1600) )
415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).A = ((pitchGain < 450)
417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                       )? WEBRTC_SPL_WORD16_MAX:0;
418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX -
419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).A;
420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      else
422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        myVoiceIndicator = ltpGain * 2 + pitchGain;
424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        MemshipValQ15( myVoiceIndicator,
425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                       &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B );
426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8);
432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    MemshipValQ15( myVoiceIndicator,
433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                   &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B );
434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (ISACdec_obj->plcstr_obj).stretchLag = lag0;
438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (ISACdec_obj->plcstr_obj).pitchIndex = 0;
439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    myDecayRate = (DECAY_RATE<<2);
444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if( (ISACdec_obj->plcstr_obj).B < 1000 )
447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    myDecayRate += (DECAY_RATE<<3);
449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* ------------ reconstructing the residual signal ------------------ */
452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP,
454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                   stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* inverse pitch filter */
456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] =
458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ((ISACdec_obj->plcstr_obj).stretchLag<<7);
459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12);
4600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  pitchGains_Q12[2] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      pitchGains_Q12[3], 1010, 10 );
4620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  pitchGains_Q12[1] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      pitchGains_Q12[2], 1010, 10 );
4640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  pitchGains_Q12[0] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      pitchGains_Q12[1], 1010, 10 );
466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* most of the time either B or A are zero so seperating */
469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if( (ISACdec_obj->plcstr_obj).B == 0 )
470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    for( i = 0; i < FRAMESAMPLES_HALF; i++ )
472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* --- Low Pass                                             */
474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed );
476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      Vector_Word16_1[i] = WEBRTC_SPL_RSHIFT_W16(
477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* --- Highpass                                              */
480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed );
482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      Vector_Word16_2[i] = WEBRTC_SPL_RSHIFT_W16(
483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    for( i = 1; i < NOISE_FILTER_LEN; i++ )
487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed );
490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      Vector_Word16_Extended_1[ i ] = WEBRTC_SPL_RSHIFT_W16(
491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed );
495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      Vector_Word16_Extended_2[ i ] = WEBRTC_SPL_RSHIFT_W16(
496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1,
499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF -
5000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                                                NOISE_FILTER_LEN], (int16_t) NOISE_FILTER_LEN,
5010946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int16_t) FRAMESAMPLES_HALF, (int16_t)(5),
5020946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (ISACdec_obj->plcstr_obj).decayCoeffNoise, (int16_t)(6));
503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    maxCoeff = WebRtcSpl_MaxAbsValueW32(
505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        &(ISACdec_obj->plcstr_obj).prevHP[
506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN );
507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    rshift = 0;
509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    while( maxCoeff > WEBRTC_SPL_WORD16_MAX )
510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      maxCoeff = WEBRTC_SPL_RSHIFT_W32(maxCoeff, 1);
512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      rshift++;
513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    for( i = 0; i < NOISE_FILTER_LEN; i++ ) {
515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      Vector_Word16_1[ FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =
5160946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org          (int16_t)WEBRTC_SPL_RSHIFT_W32(
517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              (ISACdec_obj->plcstr_obj).prevHP[
518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                  PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + i], rshift);
519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast(
521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        Vector_Word16_2,
522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        Vector_Word16_Extended_2,
523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        &Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN],
5240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        (int16_t) NOISE_FILTER_LEN,
5250946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        (int16_t) FRAMESAMPLES_HALF,
5260946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        (int16_t) (5),
527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).decayCoeffNoise,
5280946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        (int16_t) (7) );
529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    for( i = 0; i < FRAMESAMPLES_HALF; i++ )
531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      Vector_Word32_2[i] = WEBRTC_SPL_LSHIFT_W32(
5320946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org          (int32_t)Vector_Word16_Extended_2[i], rshift );
533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_1 = Vector_Word16_Extended_1;
535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if( (ISACdec_obj->plcstr_obj).A == 0 )
539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* ------ Periodic Vector ---                                */
541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ )
542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- Lowpass                                               */
5440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        pLP = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex],
546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 );
547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- Highpass                                              */
5490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15(
550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).decayCoeffPriodic,
551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 -
552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                             (ISACdec_obj->plcstr_obj).stretchLag +
553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                             (ISACdec_obj->plcstr_obj).pitchIndex] );
554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- lower the muliplier (more decay at next sample) --- */
556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate);
557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 )
558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0;
559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).pitchIndex++;
561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if( (ISACdec_obj->plcstr_obj).pitchIndex ==
563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).stretchLag )
564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).pitchIndex = 0;
566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).pitchCycles++;
567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) )
569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          {
570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1;
571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          }
572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          else
573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          {
574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).stretchLag = lag0;
575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          }
576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).stretchLag = (
578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG
579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                  )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag;
580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP,
582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                           stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP,
585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                           stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          switch( (ISACdec_obj->plcstr_obj).pitchCycles )
588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          {
589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            case 1:
590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              {
591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
5930946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                  stretchPitchLP[k] = (int16_t)((
5940946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP[k]* 3 +
5950946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP1[k])>>2);
596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                break;
598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              }
599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            case 2:
600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              {
601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
6030946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                  stretchPitchLP[k] = (int16_t)((
6040946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP[k] +
6050946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP1[k] )>>1);
606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                break;
608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              }
609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            case 3:
610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              {
611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
6130946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                  stretchPitchLP[k] = (int16_t)((stretchPitchLP[k] +
6140946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                                       (int32_t)stretchPitchLP1[k]*3 )>>2);
615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                break;
617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              }
618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          }
619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 )
621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          {
622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            myDecayRate += 35; //(myDecayRate>>1);
623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).pitchCycles = 0;
624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          }
625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* ------ Sum the noisy and periodic signals  ------ */
629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        Vector_Word16_1[i] = pLP;
630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        Vector_Word32_2[i] = pHP;
631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    else
634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    {
635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ )
636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      {
637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).seed );
640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        noise1 = WEBRTC_SPL_RSHIFT_W16(
642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        nLP = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
6450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org            (int16_t)((noise1)*(ISACdec_obj->plcstr_obj).std),
646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).decayCoeffNoise, 15 );
647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- Highpass                                              */
649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).seed );
651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        noise1 = WEBRTC_SPL_RSHIFT_W16(
652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).seed, 11 ) - 8;
653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6540946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        nHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15(
655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).decayCoeffNoise,
6560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org            (int32_t)(noise1*(ISACdec_obj->plcstr_obj).std) );
657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- lower the muliplier (more decay at next sample) --- */
659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate);
660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 )
661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).decayCoeffNoise = 0;
662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* ------ Periodic Vector ---                                */
664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- Lowpass                                               */
6650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        pLP = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex],
667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 );
668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- Highpass                                              */
6700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15(
671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).decayCoeffPriodic,
672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 -
673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                             (ISACdec_obj->plcstr_obj).stretchLag +
674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                             (ISACdec_obj->plcstr_obj).pitchIndex] );
675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* --- lower the muliplier (more decay at next sample) --- */
677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate);
678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 )
679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0;
681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* ------ Weighting the noisy and periodic vectors -------   */
6840946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        wNoisyLP = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT(
685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).A, nLP, 15 ) );
6860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        wNoisyHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15(
687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).A, (nHP) ) );
688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6890946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        wPriodicLP = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT(
690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).B, pLP, 15));
6910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        wPriodicHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15(
692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).B, pHP));
693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        (ISACdec_obj->plcstr_obj).pitchIndex++;
695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        if((ISACdec_obj->plcstr_obj).pitchIndex ==
697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com           (ISACdec_obj->plcstr_obj).stretchLag)
698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        {
699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).pitchIndex = 0;
700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).pitchCycles++;
701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) )
703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1;
704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          else
705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).stretchLag = lag0;
706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          (ISACdec_obj->plcstr_obj).stretchLag = (
708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG
709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                  )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag;
710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          LinearResampler(
711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              (ISACdec_obj->plcstr_obj).lastPitchLP,
712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP,
715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                          stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          switch((ISACdec_obj->plcstr_obj).pitchCycles)
718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          {
719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            case 1:
720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              {
721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
7230946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                  stretchPitchLP[k] = (int16_t)((
7240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP[k]* 3 +
7250946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP1[k] )>>2);
726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                break;
728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              }
729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            case 2:
730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              {
731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
7330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                  stretchPitchLP[k] = (int16_t)((
7340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP[k] +
7350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                      (int32_t)stretchPitchLP1[k])>>1);
736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                break;
738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              }
739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            case 3:
740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              {
741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                {
7430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                  stretchPitchLP[k] = (int16_t)(
744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                      (stretchPitchLP[k] +
7450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                       (int32_t)stretchPitchLP1[k]*3 )>>2);
746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                }
747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                break;
748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com              }
749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          }
750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 )
752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          {
753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            myDecayRate += 55; //(myDecayRate>>1);
754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            (ISACdec_obj->plcstr_obj).pitchCycles = 0;
755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com          }
756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        }
757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        /* ------ Sum the noisy and periodic signals  ------ */
7590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        Vector_Word16_1[i] = (int16_t)WEBRTC_SPL_ADD_SAT_W16(
760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            wNoisyLP, wPriodicLP );
7610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org        Vector_Word32_2[i] = (int32_t)WEBRTC_SPL_ADD_SAT_W32(
762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com            wNoisyHP, wPriodicHP );
763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      }
764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* ----------------- residual signal is reconstructed ------------------ */
767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  k = (ISACdec_obj->plcstr_obj).pitchIndex;
769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* --- Write one pitch cycle for recovery block --- */
770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for( i = 0; i < RECOVERY_OVERLAP; i++ )
772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
7730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    (ISACdec_obj->plcstr_obj).overlapLP[i] = (int16_t)(
774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        WEBRTC_SPL_MUL_16_16_RSFT(stretchPitchLP[k],
775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                  (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15) );
776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0;
777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = (ISACdec_obj->plcstr_obj).stretchLag << 7;
780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* --- Inverse Pitch Filter --- */
783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2,
784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                            &ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4);
785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* reduce gain to compensate for pitch enhancer */
787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* gain = 1.0f - 0.45f * AvgPitchGain; */
788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  tmp32a = WEBRTC_SPL_MUL_16_16_RSFT((ISACdec_obj->plcstr_obj).AvgPitchGain_Q12,
789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                     29, 0); // Q18
790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  tmp32b = 262144 - tmp32a;  // Q18
7910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  gainQ13 = (int16_t) (tmp32b >> 5); // Q13
792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* perceptual post-filtering (using normalized lattice filter) */
794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k = 0; k < FRAMESAMPLES_HALF; k++)
7950946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    Vector_Word32_1[k] = (int32_t) WEBRTC_SPL_MUL_16_16(
796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        Vector_Word16_2[k], gainQ13) << 3; // Q25
797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_NormLatticeFilterAr(ORDERLO,
800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_NormLatticeFilterAr(ORDERHI,
804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                    Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* recombine the 2 bands */
808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Form the polyphase signals, and compensate for DC offset */
810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<FRAMESAMPLES_HALF;k++)
811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Construct a new upper channel signal*/
8130946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16(
8140946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                           ((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1));
815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Construct a new lower channel signal*/
8160946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16(
8170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                           ((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k]));
818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_1[k] = tmp_1;
819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_2[k] = tmp_2;
820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                  Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj);
825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  (ISACdec_obj->plcstr_obj).used = PLC_WAS_USED;
827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *current_framesamples = 480;
828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return len;
830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
831