1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /**************************************************************************************** 19 Portions of this file are derived from the following 3GPP standard: 20 21 3GPP TS 26.173 22 ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec 23 Available from http://www.3gpp.org 24 25 (C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) 26 Permission to distribute, modify and use this file under the standard license 27 terms listed above has been obtained from the copyright holder. 28 ****************************************************************************************/ 29 /* 30 ------------------------------------------------------------------------------ 31 32 33 34 Filename: lagconceal.cpp 35 36 Date: 05/08/2007 37 38 ------------------------------------------------------------------------------ 39 REVISION HISTORY 40 41 42 Description: 43 44 ------------------------------------------------------------------------------ 45 INPUT AND OUTPUT DEFINITIONS 46 47 int16 gain_hist[], (i) : Gain history 48 int16 lag_hist[], (i) : Subframe size 49 int16 * T0, (i/o): current lag 50 int16 * old_T0, (i/o): previous lag 51 int16 * seed, 52 int16 unusable_frame 53 54 ------------------------------------------------------------------------------ 55 FUNCTION DESCRIPTION 56 57 Concealment of LTP lags during bad frames 58 59 ------------------------------------------------------------------------------ 60 REQUIREMENTS 61 62 63 ------------------------------------------------------------------------------ 64 REFERENCES 65 66 ------------------------------------------------------------------------------ 67 PSEUDO-CODE 68 69 ------------------------------------------------------------------------------ 70 */ 71 72 73 /*---------------------------------------------------------------------------- 74 ; INCLUDES 75 ----------------------------------------------------------------------------*/ 76 77 #include "pv_amr_wb_type_defs.h" 78 #include "pvamrwbdecoder_basic_op.h" 79 #include "pvamrwbdecoder_cnst.h" 80 #include "pvamrwbdecoder_acelp.h" 81 82 /*---------------------------------------------------------------------------- 83 ; MACROS 84 ; Define module specific macros here 85 ----------------------------------------------------------------------------*/ 86 87 88 /*---------------------------------------------------------------------------- 89 ; DEFINES 90 ; Include all pre-processor statements here. Include conditional 91 ; compile variables also. 92 ----------------------------------------------------------------------------*/ 93 #define L_LTPHIST 5 94 #define ONE_PER_3 10923 95 #define ONE_PER_LTPHIST 6554 96 97 /*---------------------------------------------------------------------------- 98 ; LOCAL FUNCTION DEFINITIONS 99 ; Function Prototype declaration 100 ----------------------------------------------------------------------------*/ 101 void insertion_sort(int16 array[], int16 n); 102 void insert(int16 array[], int16 num, int16 x); 103 104 /*---------------------------------------------------------------------------- 105 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 106 ; Variable declaration - defined here and used outside this module 107 ----------------------------------------------------------------------------*/ 108 109 /*---------------------------------------------------------------------------- 110 ; EXTERNAL FUNCTION REFERENCES 111 ; Declare functions defined elsewhere and referenced in this module 112 ----------------------------------------------------------------------------*/ 113 114 /*---------------------------------------------------------------------------- 115 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 116 ; Declare variables used in this module but defined elsewhere 117 ----------------------------------------------------------------------------*/ 118 119 /*---------------------------------------------------------------------------- 120 ; FUNCTION CODE 121 ----------------------------------------------------------------------------*/ 122 123 124 void Init_Lagconc(int16 lag_hist[]) 125 { 126 int16 i; 127 128 for (i = 0; i < L_LTPHIST; i++) 129 { 130 lag_hist[i] = 64; 131 } 132 } 133 134 /*---------------------------------------------------------------------------- 135 ; FUNCTION CODE 136 ----------------------------------------------------------------------------*/ 137 138 void lagconceal( 139 int16 gain_hist[], /* (i) : Gain history */ 140 int16 lag_hist[], /* (i) : Subframe size */ 141 int16 * T0, 142 int16 * old_T0, 143 int16 * seed, 144 int16 unusable_frame 145 ) 146 { 147 int16 maxLag, minLag, lastLag, lagDif, meanLag = 0; 148 int16 lag_hist2[L_LTPHIST] = {0}; 149 int16 i, tmp, tmp2; 150 int16 minGain, lastGain, secLastGain; 151 int16 D, D2; 152 153 /* Is lag index such that it can be aplied directly or does it has to be subtituted */ 154 155 lastGain = gain_hist[4]; 156 secLastGain = gain_hist[3]; 157 158 lastLag = lag_hist[0]; 159 160 /******* SMALLEST history lag *******/ 161 minLag = lag_hist[0]; 162 /******* BIGGEST history lag *******/ 163 maxLag = lag_hist[0]; 164 for (i = 1; i < L_LTPHIST; i++) 165 { 166 if (lag_hist[i] < minLag) 167 { 168 minLag = lag_hist[i]; 169 } 170 if (lag_hist[i] > maxLag) 171 { 172 maxLag = lag_hist[i]; 173 } 174 } 175 /***********SMALLEST history gain***********/ 176 minGain = gain_hist[0]; 177 for (i = 1; i < L_LTPHIST; i++) 178 { 179 180 if (gain_hist[i] < minGain) 181 { 182 minGain = gain_hist[i]; 183 } 184 } 185 /***Difference between MAX and MIN lag**/ 186 lagDif = sub_int16(maxLag, minLag); 187 188 189 if (unusable_frame != 0) 190 { 191 /* LTP-lag for RX_SPEECH_LOST */ 192 /**********Recognition of the LTP-history*********/ 193 194 if ((minGain > 8192) && (lagDif < 10)) 195 { 196 *T0 = *old_T0; 197 } 198 else if (lastGain > 8192 && secLastGain > 8192) 199 { 200 *T0 = lag_hist[0]; 201 } 202 else 203 { 204 /********SORT************/ 205 /* The sorting of the lag history */ 206 for (i = 0; i < L_LTPHIST; i++) 207 { 208 lag_hist2[i] = lag_hist[i]; 209 } 210 insertion_sort(lag_hist2, 5); 211 212 /* Lag is weighted towards bigger lags */ 213 /* and random variation is added */ 214 lagDif = sub_int16(lag_hist2[4], lag_hist2[2]); 215 216 217 if (lagDif > 40) 218 { 219 lagDif = 40; 220 } 221 222 D = noise_gen_amrwb(seed); /* D={-1, ...,1} */ 223 /* D2={-lagDif/2..lagDif/2} */ 224 tmp = lagDif >> 1; 225 D2 = mult_int16(tmp, D); 226 tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]); 227 *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2); 228 } 229 /* New lag is not allowed to be bigger or smaller than last lag values */ 230 231 if (*T0 > maxLag) 232 { 233 *T0 = maxLag; 234 } 235 236 if (*T0 < minLag) 237 { 238 *T0 = minLag; 239 } 240 } 241 else 242 { 243 /* LTP-lag for RX_BAD_FRAME */ 244 245 /***********MEAN lag**************/ 246 meanLag = 0; 247 for (i = 0; i < L_LTPHIST; i++) 248 { 249 meanLag = add_int16(meanLag, lag_hist[i]); 250 } 251 meanLag = mult_int16(meanLag, ONE_PER_LTPHIST); 252 253 tmp = *T0 - maxLag; 254 tmp2 = *T0 - lastLag; 255 256 if ((lagDif < 10) && (*T0 > (minLag - 5)) && (tmp < 5)) 257 { 258 *T0 = *T0; 259 } 260 else if ((lastGain > 8192) && (secLastGain > 8192) && ((tmp2 + 10) > 0 && tmp2 < 10)) 261 { 262 *T0 = *T0; 263 } 264 else if ((minGain < 6554) && (lastGain == minGain) && (*T0 > minLag && *T0 < maxLag)) 265 { 266 *T0 = *T0; 267 } 268 else if ((lagDif < 70) && (*T0 > minLag) && (*T0 < maxLag)) 269 { 270 *T0 = *T0; 271 } 272 else if ((*T0 > meanLag) && (*T0 < maxLag)) 273 { 274 *T0 = *T0; 275 } 276 else 277 { 278 279 280 if ((minGain > 8192) & (lagDif < 10)) 281 { 282 *T0 = lag_hist[0]; 283 } 284 else if ((lastGain > 8192) && (secLastGain > 8192)) 285 { 286 *T0 = lag_hist[0]; 287 } 288 else 289 { 290 /********SORT************/ 291 /* The sorting of the lag history */ 292 for (i = 0; i < L_LTPHIST; i++) 293 { 294 lag_hist2[i] = lag_hist[i]; 295 } 296 insertion_sort(lag_hist2, 5); 297 298 /* Lag is weighted towards bigger lags */ 299 /* and random variation is added */ 300 lagDif = sub_int16(lag_hist2[4], lag_hist2[2]); 301 302 if (lagDif > 40) 303 { 304 lagDif = 40; 305 } 306 307 D = noise_gen_amrwb(seed); /* D={-1,.., 1} */ 308 /* D2={-lagDif/2..lagDif/2} */ 309 tmp = lagDif >> 1; 310 D2 = mult_int16(tmp, D); 311 tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]); 312 *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2); 313 } 314 /* New lag is not allowed to be bigger or smaller than last lag values */ 315 316 if (*T0 > maxLag) 317 { 318 *T0 = maxLag; 319 } 320 321 if (*T0 < minLag) 322 { 323 *T0 = minLag; 324 } 325 } 326 } 327 } 328 329 /*---------------------------------------------------------------------------- 330 ; FUNCTION CODE 331 ----------------------------------------------------------------------------*/ 332 333 void insertion_sort(int16 array[], int16 n) 334 { 335 int16 i; 336 337 for (i = 0; i < n; i++) 338 { 339 insert(array, i, array[i]); 340 } 341 } 342 343 /*---------------------------------------------------------------------------- 344 ; FUNCTION CODE 345 ----------------------------------------------------------------------------*/ 346 347 void insert(int16 array[], int16 n, int16 x) 348 { 349 int16 i; 350 351 for (i = (n - 1); i >= 0; i--) 352 { 353 354 if (x < array[i]) 355 { 356 array[i + 1] = array[i]; 357 } 358 else 359 { 360 break; 361 } 362 } 363 array[i + 1] = x; 364 } 365