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