niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | /****************************************************************** |
| 12 | |
| 13 | iLBC Speech Coder ANSI-C Source Code |
| 14 | |
| 15 | WebRtcIlbcfix_DoThePlc.c |
| 16 | |
| 17 | ******************************************************************/ |
| 18 | |
Timothy Gu | 3111783 | 2020-12-18 22:25:57 -0800 | [diff] [blame] | 19 | #include "modules/audio_coding/codecs/ilbc/do_plc.h" |
| 20 | |
Mirko Bonadei | 06c2aa9 | 2018-02-01 15:11:41 +0100 | [diff] [blame] | 21 | #include "modules/audio_coding/codecs/ilbc/bw_expand.h" |
Timothy Gu | 3111783 | 2020-12-18 22:25:57 -0800 | [diff] [blame] | 22 | #include "modules/audio_coding/codecs/ilbc/comp_corr.h" |
| 23 | #include "modules/audio_coding/codecs/ilbc/constants.h" |
| 24 | #include "modules/audio_coding/codecs/ilbc/defines.h" |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 25 | |
| 26 | /*----------------------------------------------------------------* |
| 27 | * Packet loss concealment routine. Conceals a residual signal |
| 28 | * and LP parameters. If no packet loss, update state. |
| 29 | *---------------------------------------------------------------*/ |
| 30 | |
| 31 | void WebRtcIlbcfix_DoThePlc( |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 32 | int16_t *PLCresidual, /* (o) concealed residual */ |
| 33 | int16_t *PLClpc, /* (o) concealed LP parameters */ |
| 34 | int16_t PLI, /* (i) packet loss indicator |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 35 | 0 - no PL, 1 = PL */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 36 | int16_t *decresidual, /* (i) decoded residual */ |
| 37 | int16_t *lpc, /* (i) decoded LPC (only used for no PL) */ |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 38 | size_t inlag, /* (i) pitch lag */ |
pbos@webrtc.org | eb54446 | 2014-12-17 15:23:29 +0000 | [diff] [blame] | 39 | IlbcDecoder *iLBCdec_inst |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 40 | /* (i/o) decoder instance */ |
| 41 | ){ |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 42 | size_t i; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 43 | int32_t cross, ener, cross_comp, ener_comp = 0; |
| 44 | int32_t measure, maxMeasure, energy; |
Sam Zackrisson | ae93f04 | 2018-05-15 13:41:45 +0200 | [diff] [blame] | 45 | int32_t noise_energy_threshold_30dB; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 46 | int16_t max, crossSquareMax, crossSquare; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 47 | size_t j, lag, randlag; |
| 48 | int16_t tmp1, tmp2; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 49 | int16_t shift1, shift2, shift3, shiftMax; |
| 50 | int16_t scale3; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 51 | size_t corrLen; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 52 | int32_t tmpW32, tmp2W32; |
| 53 | int16_t use_gain; |
| 54 | int16_t tot_gain; |
| 55 | int16_t max_perSquare; |
| 56 | int16_t scale1, scale2; |
| 57 | int16_t totscale; |
| 58 | int32_t nom; |
| 59 | int16_t denom; |
| 60 | int16_t pitchfact; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 61 | size_t use_lag; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 62 | int ind; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 63 | int16_t randvec[BLOCKL_MAX]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 64 | |
| 65 | /* Packet Loss */ |
| 66 | if (PLI == 1) { |
| 67 | |
| 68 | (*iLBCdec_inst).consPLICount += 1; |
| 69 | |
| 70 | /* if previous frame not lost, |
| 71 | determine pitch pred. gain */ |
| 72 | |
| 73 | if (iLBCdec_inst->prevPLI != 1) { |
| 74 | |
| 75 | /* Maximum 60 samples are correlated, preserve as high accuracy |
| 76 | as possible without getting overflow */ |
pkasting | b297c5a | 2015-07-22 15:17:22 -0700 | [diff] [blame] | 77 | max = WebRtcSpl_MaxAbsValueW16((*iLBCdec_inst).prevResidual, |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 78 | iLBCdec_inst->blockl); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 79 | scale3 = (WebRtcSpl_GetSizeInBits(max)<<1) - 25; |
| 80 | if (scale3 < 0) { |
| 81 | scale3 = 0; |
| 82 | } |
| 83 | |
| 84 | /* Store scale for use when interpolating between the |
| 85 | * concealment and the received packet */ |
| 86 | iLBCdec_inst->prevScale = scale3; |
| 87 | |
| 88 | /* Search around the previous lag +/-3 to find the |
| 89 | best pitch period */ |
| 90 | lag = inlag - 3; |
| 91 | |
| 92 | /* Guard against getting outside the frame */ |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 93 | corrLen = (size_t)WEBRTC_SPL_MIN(60, iLBCdec_inst->blockl-(inlag+3)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 94 | |
| 95 | WebRtcIlbcfix_CompCorr( &cross, &ener, |
| 96 | iLBCdec_inst->prevResidual, lag, iLBCdec_inst->blockl, corrLen, scale3); |
| 97 | |
| 98 | /* Normalize and store cross^2 and the number of shifts */ |
| 99 | shiftMax = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(cross))-15; |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 100 | crossSquareMax = (int16_t)(( |
| 101 | (int16_t)WEBRTC_SPL_SHIFT_W32(cross, -shiftMax) * |
| 102 | (int16_t)WEBRTC_SPL_SHIFT_W32(cross, -shiftMax)) >> 15); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 103 | |
| 104 | for (j=inlag-2;j<=inlag+3;j++) { |
| 105 | WebRtcIlbcfix_CompCorr( &cross_comp, &ener_comp, |
| 106 | iLBCdec_inst->prevResidual, j, iLBCdec_inst->blockl, corrLen, scale3); |
| 107 | |
| 108 | /* Use the criteria (corr*corr)/energy to compare if |
| 109 | this lag is better or not. To avoid the division, |
| 110 | do a cross multiplication */ |
| 111 | shift1 = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(cross_comp))-15; |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 112 | crossSquare = (int16_t)(( |
| 113 | (int16_t)WEBRTC_SPL_SHIFT_W32(cross_comp, -shift1) * |
| 114 | (int16_t)WEBRTC_SPL_SHIFT_W32(cross_comp, -shift1)) >> 15); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 115 | |
| 116 | shift2 = WebRtcSpl_GetSizeInBits(ener)-15; |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 117 | measure = (int16_t)WEBRTC_SPL_SHIFT_W32(ener, -shift2) * crossSquare; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 118 | |
| 119 | shift3 = WebRtcSpl_GetSizeInBits(ener_comp)-15; |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 120 | maxMeasure = (int16_t)WEBRTC_SPL_SHIFT_W32(ener_comp, -shift3) * |
| 121 | crossSquareMax; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 122 | |
| 123 | /* Calculate shift value, so that the two measures can |
| 124 | be put in the same Q domain */ |
kwiberg | 3fc8e8d | 2016-05-20 04:40:29 -0700 | [diff] [blame] | 125 | if(2 * shiftMax + shift3 > 2 * shift1 + shift2) { |
| 126 | tmp1 = |
| 127 | WEBRTC_SPL_MIN(31, 2 * shiftMax + shift3 - 2 * shift1 - shift2); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 128 | tmp2 = 0; |
| 129 | } else { |
| 130 | tmp1 = 0; |
kwiberg | 3fc8e8d | 2016-05-20 04:40:29 -0700 | [diff] [blame] | 131 | tmp2 = |
| 132 | WEBRTC_SPL_MIN(31, 2 * shift1 + shift2 - 2 * shiftMax - shift3); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | if ((measure>>tmp1) > (maxMeasure>>tmp2)) { |
| 136 | /* New lag is better => record lag, measure and domain */ |
| 137 | lag = j; |
| 138 | crossSquareMax = crossSquare; |
| 139 | cross = cross_comp; |
| 140 | shiftMax = shift1; |
| 141 | ener = ener_comp; |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | /* Calculate the periodicity for the lag with the maximum correlation. |
| 146 | |
| 147 | Definition of the periodicity: |
| 148 | abs(corr(vec1, vec2))/(sqrt(energy(vec1))*sqrt(energy(vec2))) |
| 149 | |
| 150 | Work in the Square domain to simplify the calculations |
| 151 | max_perSquare is less than 1 (in Q15) |
| 152 | */ |
| 153 | tmp2W32=WebRtcSpl_DotProductWithScale(&iLBCdec_inst->prevResidual[iLBCdec_inst->blockl-corrLen], |
| 154 | &iLBCdec_inst->prevResidual[iLBCdec_inst->blockl-corrLen], |
| 155 | corrLen, scale3); |
| 156 | |
| 157 | if ((tmp2W32>0)&&(ener_comp>0)) { |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 158 | /* norm energies to int16_t, compute the product of the energies and |
| 159 | use the upper int16_t as the denominator */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 160 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 161 | scale1=(int16_t)WebRtcSpl_NormW32(tmp2W32)-16; |
| 162 | tmp1=(int16_t)WEBRTC_SPL_SHIFT_W32(tmp2W32, scale1); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 163 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 164 | scale2=(int16_t)WebRtcSpl_NormW32(ener)-16; |
| 165 | tmp2=(int16_t)WEBRTC_SPL_SHIFT_W32(ener, scale2); |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 166 | denom = (int16_t)((tmp1 * tmp2) >> 16); /* in Q(scale1+scale2-16) */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 167 | |
| 168 | /* Square the cross correlation and norm it such that max_perSquare |
| 169 | will be in Q15 after the division */ |
| 170 | |
| 171 | totscale = scale1+scale2-1; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 172 | tmp1 = (int16_t)WEBRTC_SPL_SHIFT_W32(cross, (totscale>>1)); |
| 173 | tmp2 = (int16_t)WEBRTC_SPL_SHIFT_W32(cross, totscale-(totscale>>1)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 174 | |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 175 | nom = tmp1 * tmp2; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 176 | max_perSquare = (int16_t)WebRtcSpl_DivW32W16(nom, denom); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 177 | |
| 178 | } else { |
| 179 | max_perSquare = 0; |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | /* previous frame lost, use recorded lag and gain */ |
| 184 | |
| 185 | else { |
| 186 | lag = iLBCdec_inst->prevLag; |
| 187 | max_perSquare = iLBCdec_inst->perSquare; |
| 188 | } |
| 189 | |
| 190 | /* Attenuate signal and scale down pitch pred gain if |
| 191 | several frames lost consecutively */ |
| 192 | |
| 193 | use_gain = 32767; /* 1.0 in Q15 */ |
| 194 | |
| 195 | if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320) { |
| 196 | use_gain = 29491; /* 0.9 in Q15 */ |
| 197 | } else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>640) { |
| 198 | use_gain = 22938; /* 0.7 in Q15 */ |
| 199 | } else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>960) { |
| 200 | use_gain = 16384; /* 0.5 in Q15 */ |
| 201 | } else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>1280) { |
| 202 | use_gain = 0; /* 0.0 in Q15 */ |
| 203 | } |
| 204 | |
| 205 | /* Compute mixing factor of picth repeatition and noise: |
| 206 | for max_per>0.7 set periodicity to 1.0 |
| 207 | 0.4<max_per<0.7 set periodicity to (maxper-0.4)/0.7-0.4) |
| 208 | max_per<0.4 set periodicity to 0.0 |
| 209 | */ |
| 210 | |
| 211 | if (max_perSquare>7868) { /* periodicity > 0.7 (0.7^4=0.2401 in Q15) */ |
| 212 | pitchfact = 32767; |
| 213 | } else if (max_perSquare>839) { /* 0.4 < periodicity < 0.7 (0.4^4=0.0256 in Q15) */ |
| 214 | /* find best index and interpolate from that */ |
| 215 | ind = 5; |
| 216 | while ((max_perSquare<WebRtcIlbcfix_kPlcPerSqr[ind])&&(ind>0)) { |
| 217 | ind--; |
| 218 | } |
| 219 | /* pitch fact is approximated by first order */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 220 | tmpW32 = (int32_t)WebRtcIlbcfix_kPlcPitchFact[ind] + |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 221 | ((WebRtcIlbcfix_kPlcPfSlope[ind] * |
| 222 | (max_perSquare - WebRtcIlbcfix_kPlcPerSqr[ind])) >> 11); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 223 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 224 | pitchfact = (int16_t)WEBRTC_SPL_MIN(tmpW32, 32767); /* guard against overflow */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 225 | |
| 226 | } else { /* periodicity < 0.4 */ |
| 227 | pitchfact = 0; |
| 228 | } |
| 229 | |
| 230 | /* avoid repetition of same pitch cycle (buzzyness) */ |
| 231 | use_lag = lag; |
| 232 | if (lag<80) { |
| 233 | use_lag = 2*lag; |
| 234 | } |
| 235 | |
| 236 | /* compute concealed residual */ |
Sam Zackrisson | ae93f04 | 2018-05-15 13:41:45 +0200 | [diff] [blame] | 237 | noise_energy_threshold_30dB = (int32_t)iLBCdec_inst->blockl * 900; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 238 | energy = 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 239 | for (i=0; i<iLBCdec_inst->blockl; i++) { |
| 240 | |
| 241 | /* noise component - 52 < randlagFIX < 117 */ |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 242 | iLBCdec_inst->seed = (int16_t)(iLBCdec_inst->seed * 31821 + 13849); |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 243 | randlag = 53 + (iLBCdec_inst->seed & 63); |
Peter Kasting | f045e4d | 2015-06-10 21:15:38 -0700 | [diff] [blame] | 244 | if (randlag > i) { |
| 245 | randvec[i] = |
| 246 | iLBCdec_inst->prevResidual[iLBCdec_inst->blockl + i - randlag]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 247 | } else { |
Peter Kasting | f045e4d | 2015-06-10 21:15:38 -0700 | [diff] [blame] | 248 | randvec[i] = iLBCdec_inst->prevResidual[i - randlag]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 249 | } |
| 250 | |
| 251 | /* pitch repeatition component */ |
Peter Kasting | f045e4d | 2015-06-10 21:15:38 -0700 | [diff] [blame] | 252 | if (use_lag > i) { |
| 253 | PLCresidual[i] = |
| 254 | iLBCdec_inst->prevResidual[iLBCdec_inst->blockl + i - use_lag]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 255 | } else { |
Peter Kasting | f045e4d | 2015-06-10 21:15:38 -0700 | [diff] [blame] | 256 | PLCresidual[i] = PLCresidual[i - use_lag]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 257 | } |
| 258 | |
| 259 | /* Attinuate total gain for each 10 ms */ |
| 260 | if (i<80) { |
| 261 | tot_gain=use_gain; |
| 262 | } else if (i<160) { |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 263 | tot_gain = (int16_t)((31130 * use_gain) >> 15); /* 0.95*use_gain */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 264 | } else { |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 265 | tot_gain = (int16_t)((29491 * use_gain) >> 15); /* 0.9*use_gain */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 266 | } |
| 267 | |
| 268 | |
| 269 | /* mix noise and pitch repeatition */ |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 270 | PLCresidual[i] = (int16_t)((tot_gain * |
| 271 | ((pitchfact * PLCresidual[i] + (32767 - pitchfact) * randvec[i] + |
| 272 | 16384) >> 15)) >> 15); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 273 | |
Sam Zackrisson | ae93f04 | 2018-05-15 13:41:45 +0200 | [diff] [blame] | 274 | /* Compute energy until threshold for noise energy is reached */ |
| 275 | if (energy < noise_energy_threshold_30dB) { |
| 276 | energy += PLCresidual[i] * PLCresidual[i]; |
| 277 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 278 | } |
| 279 | |
| 280 | /* less than 30 dB, use only noise */ |
Sam Zackrisson | ae93f04 | 2018-05-15 13:41:45 +0200 | [diff] [blame] | 281 | if (energy < noise_energy_threshold_30dB) { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 282 | for (i=0; i<iLBCdec_inst->blockl; i++) { |
| 283 | PLCresidual[i] = randvec[i]; |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | /* use the old LPC */ |
| 288 | WEBRTC_SPL_MEMCPY_W16(PLClpc, (*iLBCdec_inst).prevLpc, LPC_FILTERORDER+1); |
| 289 | |
| 290 | /* Update state in case there are multiple frame losses */ |
| 291 | iLBCdec_inst->prevLag = lag; |
| 292 | iLBCdec_inst->perSquare = max_perSquare; |
| 293 | } |
| 294 | |
| 295 | /* no packet loss, copy input */ |
| 296 | |
| 297 | else { |
| 298 | WEBRTC_SPL_MEMCPY_W16(PLCresidual, decresidual, iLBCdec_inst->blockl); |
| 299 | WEBRTC_SPL_MEMCPY_W16(PLClpc, lpc, (LPC_FILTERORDER+1)); |
| 300 | iLBCdec_inst->consPLICount = 0; |
| 301 | } |
| 302 | |
| 303 | /* update state */ |
| 304 | iLBCdec_inst->prevPLI = PLI; |
| 305 | WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->prevLpc, PLClpc, (LPC_FILTERORDER+1)); |
| 306 | WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->prevResidual, PLCresidual, iLBCdec_inst->blockl); |
| 307 | |
| 308 | return; |
| 309 | } |