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_EnhancerInterface.c |
| 16 | |
| 17 | ******************************************************************/ |
| 18 | |
Timothy Gu | 3111783 | 2020-12-18 22:25:57 -0800 | [diff] [blame] | 19 | #include "modules/audio_coding/codecs/ilbc/enhancer_interface.h" |
| 20 | |
bjornv@webrtc.org | 5227534 | 2014-08-20 10:09:34 +0000 | [diff] [blame] | 21 | #include <string.h> |
| 22 | |
Mirko Bonadei | 06c2aa9 | 2018-02-01 15:11:41 +0100 | [diff] [blame] | 23 | #include "modules/audio_coding/codecs/ilbc/constants.h" |
Timothy Gu | 3111783 | 2020-12-18 22:25:57 -0800 | [diff] [blame] | 24 | #include "modules/audio_coding/codecs/ilbc/defines.h" |
Mirko Bonadei | 06c2aa9 | 2018-02-01 15:11:41 +0100 | [diff] [blame] | 25 | #include "modules/audio_coding/codecs/ilbc/enhancer.h" |
| 26 | #include "modules/audio_coding/codecs/ilbc/hp_output.h" |
Timothy Gu | 3111783 | 2020-12-18 22:25:57 -0800 | [diff] [blame] | 27 | #include "modules/audio_coding/codecs/ilbc/xcorr_coef.h" |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 28 | |
| 29 | |
| 30 | |
| 31 | /*----------------------------------------------------------------* |
| 32 | * interface for enhancer |
| 33 | *---------------------------------------------------------------*/ |
| 34 | |
kwiberg | affcac4 | 2016-09-01 12:47:17 -0700 | [diff] [blame] | 35 | size_t // (o) Estimated lag in end of in[] |
| 36 | WebRtcIlbcfix_EnhancerInterface( |
| 37 | int16_t* out, // (o) enhanced signal |
| 38 | const int16_t* in, // (i) unenhanced signal |
| 39 | IlbcDecoder* iLBCdec_inst) { // (i) buffers etc |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 40 | size_t iblock; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 41 | size_t lag=20, tlag=20; |
| 42 | size_t inLen=iLBCdec_inst->blockl+120; |
| 43 | int16_t scale, scale1; |
| 44 | size_t plc_blockl; |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 45 | int16_t *enh_buf; |
| 46 | size_t *enh_period; |
| 47 | int32_t tmp1, tmp2, max; |
| 48 | size_t new_blocks; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 49 | int16_t *enh_bufPtr1; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 50 | size_t i; |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 51 | size_t k; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 52 | int16_t EnChange; |
| 53 | int16_t SqrtEnChange; |
| 54 | int16_t inc; |
| 55 | int16_t win; |
| 56 | int16_t *tmpW16ptr; |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 57 | size_t startPos; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 58 | int16_t *plc_pred; |
kwiberg | affcac4 | 2016-09-01 12:47:17 -0700 | [diff] [blame] | 59 | const int16_t *target, *regressor; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 60 | int16_t max16; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 61 | int shifts; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 62 | int32_t ener; |
| 63 | int16_t enerSh; |
| 64 | int16_t corrSh; |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 65 | size_t ind; |
| 66 | int16_t sh; |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 67 | size_t start, stop; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 68 | /* Stack based */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 69 | int16_t totsh[3]; |
| 70 | int16_t downsampled[(BLOCKL_MAX+120)>>1]; /* length 180 */ |
| 71 | int32_t corr32[50]; |
| 72 | int32_t corrmax[3]; |
| 73 | int16_t corr16[3]; |
| 74 | int16_t en16[3]; |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 75 | size_t lagmax[3]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 76 | |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 77 | plc_pred = downsampled; /* Reuse memory since plc_pred[ENH_BLOCKL] and |
| 78 | downsampled are non overlapping */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 79 | enh_buf=iLBCdec_inst->enh_buf; |
| 80 | enh_period=iLBCdec_inst->enh_period; |
| 81 | |
| 82 | /* Copy in the new data into the enhancer buffer */ |
bjornv@webrtc.org | 5227534 | 2014-08-20 10:09:34 +0000 | [diff] [blame] | 83 | memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl], |
| 84 | (ENH_BUFL - iLBCdec_inst->blockl) * sizeof(*enh_buf)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 85 | |
| 86 | WEBRTC_SPL_MEMCPY_W16(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in, |
| 87 | iLBCdec_inst->blockl); |
| 88 | |
| 89 | /* Set variables that are dependent on frame size */ |
| 90 | if (iLBCdec_inst->mode==30) { |
| 91 | plc_blockl=ENH_BLOCKL; |
| 92 | new_blocks=3; |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 93 | startPos=320; /* Start position for enhancement |
| 94 | (640-new_blocks*ENH_BLOCKL-80) */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 95 | } else { |
| 96 | plc_blockl=40; |
| 97 | new_blocks=2; |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 98 | startPos=440; /* Start position for enhancement |
| 99 | (640-new_blocks*ENH_BLOCKL-40) */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | /* Update the pitch prediction for each enhancer block, move the old ones */ |
bjornv@webrtc.org | 5227534 | 2014-08-20 10:09:34 +0000 | [diff] [blame] | 103 | memmove(enh_period, &enh_period[new_blocks], |
| 104 | (ENH_NBLOCKS_TOT - new_blocks) * sizeof(*enh_period)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 105 | |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 106 | WebRtcSpl_DownsampleFast( |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 107 | enh_buf+ENH_BUFL-inLen, /* Input samples */ |
Peter Kasting | b7e5054 | 2015-06-11 12:55:50 -0700 | [diff] [blame] | 108 | inLen + ENH_BUFL_FILTEROVERHEAD, |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 109 | downsampled, |
Peter Kasting | b7e5054 | 2015-06-11 12:55:50 -0700 | [diff] [blame] | 110 | inLen / 2, |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 111 | (int16_t*)WebRtcIlbcfix_kLpFiltCoefs, /* Coefficients in Q12 */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 112 | FILTERORDER_DS_PLUS1, /* Length of filter (order-1) */ |
| 113 | FACTOR_DS, |
| 114 | DELAY_DS); |
| 115 | |
| 116 | /* Estimate the pitch in the down sampled domain. */ |
| 117 | for(iblock = 0; iblock<new_blocks; iblock++){ |
| 118 | |
| 119 | /* references */ |
Peter Kasting | f045e4d | 2015-06-10 21:15:38 -0700 | [diff] [blame] | 120 | target = downsampled + 60 + iblock * ENH_BLOCKL_HALF; |
| 121 | regressor = target - 10; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 122 | |
| 123 | /* scaling */ |
Peter Kasting | b7e5054 | 2015-06-11 12:55:50 -0700 | [diff] [blame] | 124 | max16 = WebRtcSpl_MaxAbsValueW16(®ressor[-50], ENH_BLOCKL_HALF + 50 - 1); |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 125 | shifts = WebRtcSpl_GetSizeInBits((uint32_t)(max16 * max16)) - 25; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 126 | shifts = WEBRTC_SPL_MAX(0, shifts); |
| 127 | |
| 128 | /* compute cross correlation */ |
Peter Kasting | a8b335c | 2015-06-11 18:51:20 -0700 | [diff] [blame] | 129 | WebRtcSpl_CrossCorrelation(corr32, target, regressor, ENH_BLOCKL_HALF, 50, |
| 130 | shifts, -1); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 131 | |
| 132 | /* Find 3 highest correlations that should be compared for the |
| 133 | highest (corr*corr)/ener */ |
| 134 | |
| 135 | for (i=0;i<2;i++) { |
| 136 | lagmax[i] = WebRtcSpl_MaxIndexW32(corr32, 50); |
| 137 | corrmax[i] = corr32[lagmax[i]]; |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 138 | start = WEBRTC_SPL_MAX(2, lagmax[i]) - 2; |
| 139 | stop = WEBRTC_SPL_MIN(47, lagmax[i]) + 2; |
| 140 | for (k = start; k <= stop; k++) { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 141 | corr32[k] = 0; |
| 142 | } |
| 143 | } |
| 144 | lagmax[2] = WebRtcSpl_MaxIndexW32(corr32, 50); |
| 145 | corrmax[2] = corr32[lagmax[2]]; |
| 146 | |
| 147 | /* Calculate normalized corr^2 and ener */ |
| 148 | for (i=0;i<3;i++) { |
| 149 | corrSh = 15-WebRtcSpl_GetSizeInBits(corrmax[i]); |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 150 | ener = WebRtcSpl_DotProductWithScale(regressor - lagmax[i], |
| 151 | regressor - lagmax[i], |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 152 | ENH_BLOCKL_HALF, shifts); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 153 | enerSh = 15-WebRtcSpl_GetSizeInBits(ener); |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 154 | corr16[i] = (int16_t)WEBRTC_SPL_SHIFT_W32(corrmax[i], corrSh); |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 155 | corr16[i] = (int16_t)((corr16[i] * corr16[i]) >> 16); |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 156 | en16[i] = (int16_t)WEBRTC_SPL_SHIFT_W32(ener, enerSh); |
kwiberg | 4f6c2b6 | 2016-05-26 03:40:51 -0700 | [diff] [blame] | 157 | totsh[i] = enerSh - 2 * corrSh; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | /* Compare lagmax[0..3] for the (corr^2)/ener criteria */ |
| 161 | ind = 0; |
| 162 | for (i=1; i<3; i++) { |
| 163 | if (totsh[ind] > totsh[i]) { |
| 164 | sh = WEBRTC_SPL_MIN(31, totsh[ind]-totsh[i]); |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 165 | if (corr16[ind] * en16[i] < (corr16[i] * en16[ind]) >> sh) { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 166 | ind = i; |
| 167 | } |
| 168 | } else { |
| 169 | sh = WEBRTC_SPL_MIN(31, totsh[i]-totsh[ind]); |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 170 | if ((corr16[ind] * en16[i]) >> sh < corr16[i] * en16[ind]) { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 171 | ind = i; |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 176 | lag = lagmax[ind] + 10; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 177 | |
| 178 | /* Store the estimated lag in the non-downsampled domain */ |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 179 | enh_period[ENH_NBLOCKS_TOT - new_blocks + iblock] = lag * 8; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 180 | |
| 181 | /* Store the estimated lag for backward PLC */ |
| 182 | if (iLBCdec_inst->prev_enh_pl==1) { |
| 183 | if (!iblock) { |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 184 | tlag = lag * 2; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 185 | } |
| 186 | } else { |
| 187 | if (iblock==1) { |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 188 | tlag = lag * 2; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 189 | } |
| 190 | } |
| 191 | |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 192 | lag *= 2; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 193 | } |
| 194 | |
| 195 | if ((iLBCdec_inst->prev_enh_pl==1)||(iLBCdec_inst->prev_enh_pl==2)) { |
| 196 | |
| 197 | /* Calculate the best lag of the new frame |
| 198 | This is used to interpolate backwards and mix with the PLC'd data |
| 199 | */ |
| 200 | |
| 201 | /* references */ |
| 202 | target=in; |
| 203 | regressor=in+tlag-1; |
| 204 | |
| 205 | /* scaling */ |
Ivo Creusen | fe06dbd | 2021-01-12 16:01:30 +0100 | [diff] [blame] | 206 | // Note that this is not abs-max, but it doesn't matter since we use only |
| 207 | // the square of it. |
| 208 | max16 = regressor[WebRtcSpl_MaxAbsIndexW16(regressor, plc_blockl + 3 - 1)]; |
Ivo Creusen | 0ff2b4c | 2020-12-16 17:37:58 +0100 | [diff] [blame] | 209 | |
| 210 | const int64_t max_val = plc_blockl * max16 * max16; |
| 211 | const int32_t factor = max_val >> 31; |
| 212 | shifts = factor == 0 ? 0 : 31 - WebRtcSpl_NormW32(factor); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 213 | |
| 214 | /* compute cross correlation */ |
Peter Kasting | a8b335c | 2015-06-11 18:51:20 -0700 | [diff] [blame] | 215 | WebRtcSpl_CrossCorrelation(corr32, target, regressor, plc_blockl, 3, shifts, |
| 216 | 1); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 217 | |
| 218 | /* find lag */ |
| 219 | lag=WebRtcSpl_MaxIndexW32(corr32, 3); |
| 220 | lag+=tlag-1; |
| 221 | |
| 222 | /* Copy the backward PLC to plc_pred */ |
| 223 | |
| 224 | if (iLBCdec_inst->prev_enh_pl==1) { |
| 225 | if (lag>plc_blockl) { |
| 226 | WEBRTC_SPL_MEMCPY_W16(plc_pred, &in[lag-plc_blockl], plc_blockl); |
| 227 | } else { |
| 228 | WEBRTC_SPL_MEMCPY_W16(&plc_pred[plc_blockl-lag], in, lag); |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 229 | WEBRTC_SPL_MEMCPY_W16( |
| 230 | plc_pred, &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl+lag], |
| 231 | (plc_blockl-lag)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 232 | } |
| 233 | } else { |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 234 | size_t pos; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 235 | |
| 236 | pos = plc_blockl; |
| 237 | |
| 238 | while (lag<pos) { |
| 239 | WEBRTC_SPL_MEMCPY_W16(&plc_pred[pos-lag], in, lag); |
| 240 | pos = pos - lag; |
| 241 | } |
| 242 | WEBRTC_SPL_MEMCPY_W16(plc_pred, &in[lag-pos], pos); |
| 243 | |
| 244 | } |
| 245 | |
| 246 | if (iLBCdec_inst->prev_enh_pl==1) { |
| 247 | /* limit energy change |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 248 | if energy in backward PLC is more than 4 times higher than the forward |
| 249 | PLC, then reduce the energy in the backward PLC vector: |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 250 | sample 1...len-16 set energy of the to 4 times forward PLC |
| 251 | sample len-15..len interpolate between 4 times fw PLC and bw PLC energy |
| 252 | |
| 253 | Note: Compared to floating point code there is a slight change, |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 254 | the window is 16 samples long instead of 10 samples to simplify the |
| 255 | calculations |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 256 | */ |
| 257 | |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 258 | max=WebRtcSpl_MaxAbsValueW16( |
| 259 | &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], plc_blockl); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 260 | max16=WebRtcSpl_MaxAbsValueW16(plc_pred, plc_blockl); |
| 261 | max = WEBRTC_SPL_MAX(max, max16); |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 262 | scale=22-(int16_t)WebRtcSpl_NormW32(max); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 263 | scale=WEBRTC_SPL_MAX(scale,0); |
| 264 | |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 265 | tmp2 = WebRtcSpl_DotProductWithScale( |
| 266 | &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], |
| 267 | &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], |
| 268 | plc_blockl, scale); |
| 269 | tmp1 = WebRtcSpl_DotProductWithScale(plc_pred, plc_pred, |
| 270 | plc_blockl, scale); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 271 | |
| 272 | /* Check the energy difference */ |
| 273 | if ((tmp1>0)&&((tmp1>>2)>tmp2)) { |
| 274 | /* EnChange is now guaranteed to be <0.5 |
| 275 | Calculate EnChange=tmp2/tmp1 in Q16 |
| 276 | */ |
| 277 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 278 | scale1=(int16_t)WebRtcSpl_NormW32(tmp1); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 279 | tmp1=WEBRTC_SPL_SHIFT_W32(tmp1, (scale1-16)); /* using 15 bits */ |
| 280 | |
| 281 | tmp2=WEBRTC_SPL_SHIFT_W32(tmp2, (scale1)); |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 282 | EnChange = (int16_t)WebRtcSpl_DivW32W16(tmp2, |
| 283 | (int16_t)tmp1); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 284 | |
| 285 | /* Calculate the Sqrt of the energy in Q15 ((14+16)/2) */ |
bjornv@webrtc.org | 4ab23d0 | 2015-03-20 06:01:06 +0000 | [diff] [blame] | 286 | SqrtEnChange = (int16_t)WebRtcSpl_SqrtFloor(EnChange << 14); |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 287 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 288 | |
| 289 | /* Multiply first part of vector with 2*SqrtEnChange */ |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 290 | WebRtcSpl_ScaleVector(plc_pred, plc_pred, SqrtEnChange, plc_blockl-16, |
| 291 | 14); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 292 | |
| 293 | /* Calculate increase parameter for window part (16 last samples) */ |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 294 | /* (1-2*SqrtEnChange)/16 in Q15 */ |
bjornv@webrtc.org | f71785c | 2014-10-08 15:36:30 +0000 | [diff] [blame] | 295 | inc = 2048 - (SqrtEnChange >> 3); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 296 | |
| 297 | win=0; |
| 298 | tmpW16ptr=&plc_pred[plc_blockl-16]; |
| 299 | |
| 300 | for (i=16;i>0;i--) { |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 301 | *tmpW16ptr = (int16_t)( |
| 302 | (*tmpW16ptr * (SqrtEnChange + (win >> 1))) >> 14); |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 303 | /* multiply by (2.0*SqrtEnChange+win) */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 304 | |
| 305 | win += inc; |
| 306 | tmpW16ptr++; |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | /* Make the linear interpolation between the forward PLC'd data |
| 311 | and the backward PLC'd data (from the new frame) |
| 312 | */ |
| 313 | |
| 314 | if (plc_blockl==40) { |
| 315 | inc=400; /* 1/41 in Q14 */ |
| 316 | } else { /* plc_blockl==80 */ |
| 317 | inc=202; /* 1/81 in Q14 */ |
| 318 | } |
| 319 | win=0; |
| 320 | enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl]; |
| 321 | for (i=0; i<plc_blockl; i++) { |
| 322 | win+=inc; |
bjornv@webrtc.org | 2f6ae0d | 2015-03-01 19:50:41 +0000 | [diff] [blame] | 323 | *enh_bufPtr1 = (int16_t)((*enh_bufPtr1 * win) >> 14); |
| 324 | *enh_bufPtr1 += (int16_t)( |
| 325 | ((16384 - win) * plc_pred[plc_blockl - 1 - i]) >> 14); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 326 | enh_bufPtr1--; |
| 327 | } |
| 328 | } else { |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 329 | int16_t *synt = &downsampled[LPC_FILTERORDER]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 330 | |
| 331 | enh_bufPtr1=&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl]; |
| 332 | WEBRTC_SPL_MEMCPY_W16(enh_bufPtr1, plc_pred, plc_blockl); |
| 333 | |
| 334 | /* Clear fileter memory */ |
| 335 | WebRtcSpl_MemSetW16(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER); |
| 336 | WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemy, 0, 4); |
| 337 | WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemx, 0, 2); |
| 338 | |
| 339 | /* Initialize filter memory by filtering through 2 lags */ |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 340 | WEBRTC_SPL_MEMCPY_W16(&synt[-LPC_FILTERORDER], iLBCdec_inst->syntMem, |
| 341 | LPC_FILTERORDER); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 342 | WebRtcSpl_FilterARFastQ12( |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 343 | enh_bufPtr1, |
| 344 | synt, |
| 345 | &iLBCdec_inst->old_syntdenum[ |
Peter Kasting | 728d903 | 2015-06-11 14:31:38 -0700 | [diff] [blame] | 346 | (iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1)], |
| 347 | LPC_FILTERORDER+1, lag); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 348 | |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 349 | WEBRTC_SPL_MEMCPY_W16(&synt[-LPC_FILTERORDER], &synt[lag-LPC_FILTERORDER], |
| 350 | LPC_FILTERORDER); |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 351 | WebRtcIlbcfix_HpOutput(synt, (int16_t*)WebRtcIlbcfix_kHpOutCoefs, |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 352 | iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx, |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 353 | lag); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 354 | WebRtcSpl_FilterARFastQ12( |
| 355 | enh_bufPtr1, synt, |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 356 | &iLBCdec_inst->old_syntdenum[ |
Peter Kasting | 728d903 | 2015-06-11 14:31:38 -0700 | [diff] [blame] | 357 | (iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1)], |
| 358 | LPC_FILTERORDER+1, lag); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 359 | |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 360 | WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &synt[lag-LPC_FILTERORDER], |
| 361 | LPC_FILTERORDER); |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 362 | WebRtcIlbcfix_HpOutput(synt, (int16_t*)WebRtcIlbcfix_kHpOutCoefs, |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 363 | iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx, |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 364 | lag); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 365 | } |
| 366 | } |
| 367 | |
| 368 | |
| 369 | /* Perform enhancement block by block */ |
| 370 | |
| 371 | for (iblock = 0; iblock<new_blocks; iblock++) { |
bjornv@webrtc.org | ba97ea6 | 2015-02-13 09:51:40 +0000 | [diff] [blame] | 372 | WebRtcIlbcfix_Enhancer(out + iblock * ENH_BLOCKL, |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 373 | enh_buf, |
| 374 | ENH_BUFL, |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 375 | iblock * ENH_BLOCKL + startPos, |
tina.legrand@webrtc.org | a41b4ce | 2011-08-29 08:19:30 +0000 | [diff] [blame] | 376 | enh_period, |
Peter Kasting | 1380e26 | 2015-08-28 17:31:03 -0700 | [diff] [blame] | 377 | WebRtcIlbcfix_kEnhPlocs, ENH_NBLOCKS_TOT); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 378 | } |
| 379 | |
| 380 | return (lag); |
| 381 | } |