1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische 3b815c7f3Sopenharmony_ci * Universitaet Berlin. See the accompanying file "COPYRIGHT" for 4b815c7f3Sopenharmony_ci * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. 5b815c7f3Sopenharmony_ci */ 6b815c7f3Sopenharmony_ci 7b815c7f3Sopenharmony_ci#include <stdio.h> 8b815c7f3Sopenharmony_ci#include <assert.h> 9b815c7f3Sopenharmony_ci 10b815c7f3Sopenharmony_ci#include "gsm610_priv.h" 11b815c7f3Sopenharmony_ci 12b815c7f3Sopenharmony_ci/* 13b815c7f3Sopenharmony_ci * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION 14b815c7f3Sopenharmony_ci */ 15b815c7f3Sopenharmony_ci 16b815c7f3Sopenharmony_ci 17b815c7f3Sopenharmony_ci/* 18b815c7f3Sopenharmony_ci * This module computes the LTP gain (bc) and the LTP lag (Nc) 19b815c7f3Sopenharmony_ci * for the long term analysis filter. This is done by calculating a 20b815c7f3Sopenharmony_ci * maximum of the cross-correlation function between the current 21b815c7f3Sopenharmony_ci * sub-segment short term residual signal d [0..39] (output of 22b815c7f3Sopenharmony_ci * the short term analysis filter ; for simplification the index 23b815c7f3Sopenharmony_ci * of this array begins at 0 and ends at 39 for each sub-segment of the 24b815c7f3Sopenharmony_ci * RPE-LTP analysis) and the previous reconstructed short term 25b815c7f3Sopenharmony_ci * residual signal dp [-120 .. -1]. A dynamic scaling must be 26b815c7f3Sopenharmony_ci * performed to avoid overflow. 27b815c7f3Sopenharmony_ci */ 28b815c7f3Sopenharmony_ci 29b815c7f3Sopenharmony_ci /* The next procedure exists in six versions. First two integer 30b815c7f3Sopenharmony_ci * version (if USE_FLOAT_MUL is not defined) ; then four floating 31b815c7f3Sopenharmony_ci * point versions, twice with proper scaling (USE_FLOAT_MUL defined), 32b815c7f3Sopenharmony_ci * once without (USE_FLOAT_MUL and FAST defined, and fast run-time 33b815c7f3Sopenharmony_ci * option used). Every pair has first a Cut version (see the -C 34b815c7f3Sopenharmony_ci * option to toast or the LTP_CUT option to gsm_option ()), then the 35b815c7f3Sopenharmony_ci * uncut one. (For a detailed explanation of why this is altogether 36b815c7f3Sopenharmony_ci * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered 37b815c7f3Sopenharmony_ci * Harmful''.) 38b815c7f3Sopenharmony_ci */ 39b815c7f3Sopenharmony_ci 40b815c7f3Sopenharmony_ci#ifndef USE_FLOAT_MUL 41b815c7f3Sopenharmony_ci 42b815c7f3Sopenharmony_ci#ifdef LTP_CUT 43b815c7f3Sopenharmony_ci 44b815c7f3Sopenharmony_cistatic void Cut_Calculation_of_the_LTP_parameters ( 45b815c7f3Sopenharmony_ci 46b815c7f3Sopenharmony_ci struct gsm_state * st, 47b815c7f3Sopenharmony_ci 48b815c7f3Sopenharmony_ci register int16_t * d, /* [0..39] IN */ 49b815c7f3Sopenharmony_ci register int16_t * dp, /* [-120..-1] IN */ 50b815c7f3Sopenharmony_ci int16_t * bc_out, /* OUT */ 51b815c7f3Sopenharmony_ci int16_t * Nc_out /* OUT */) 52b815c7f3Sopenharmony_ci{ 53b815c7f3Sopenharmony_ci register int k, lambda ; 54b815c7f3Sopenharmony_ci int16_t Nc, bc ; 55b815c7f3Sopenharmony_ci int16_t wt [40] ; 56b815c7f3Sopenharmony_ci 57b815c7f3Sopenharmony_ci int32_t L_result ; 58b815c7f3Sopenharmony_ci int32_t L_max, L_power ; 59b815c7f3Sopenharmony_ci int16_t R, S, dmax, scal, best_k ; 60b815c7f3Sopenharmony_ci int16_t ltp_cut ; 61b815c7f3Sopenharmony_ci 62b815c7f3Sopenharmony_ci register int16_t temp, wt_k ; 63b815c7f3Sopenharmony_ci 64b815c7f3Sopenharmony_ci /* Search of the optimum scaling of d [0..39]. */ 65b815c7f3Sopenharmony_ci dmax = 0 ; 66b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 67b815c7f3Sopenharmony_ci { temp = d [k] ; 68b815c7f3Sopenharmony_ci temp = GSM_ABS (temp) ; 69b815c7f3Sopenharmony_ci if (temp > dmax) 70b815c7f3Sopenharmony_ci { dmax = temp ; 71b815c7f3Sopenharmony_ci best_k = k ; 72b815c7f3Sopenharmony_ci } 73b815c7f3Sopenharmony_ci } 74b815c7f3Sopenharmony_ci temp = 0 ; 75b815c7f3Sopenharmony_ci if (dmax == 0) 76b815c7f3Sopenharmony_ci scal = 0 ; 77b815c7f3Sopenharmony_ci else 78b815c7f3Sopenharmony_ci { assert (dmax > 0) ; 79b815c7f3Sopenharmony_ci temp = gsm_norm ((int32_t) dmax << 16) ; 80b815c7f3Sopenharmony_ci } 81b815c7f3Sopenharmony_ci if (temp > 6) scal = 0 ; 82b815c7f3Sopenharmony_ci else scal = 6 - temp ; 83b815c7f3Sopenharmony_ci assert (scal >= 0) ; 84b815c7f3Sopenharmony_ci 85b815c7f3Sopenharmony_ci /* Search for the maximum cross-correlation and coding of the LTP lag 86b815c7f3Sopenharmony_ci */ 87b815c7f3Sopenharmony_ci L_max = 0 ; 88b815c7f3Sopenharmony_ci Nc = 40 ; /* index for the maximum cross-correlation */ 89b815c7f3Sopenharmony_ci wt_k = SASR_W (d [best_k], scal) ; 90b815c7f3Sopenharmony_ci 91b815c7f3Sopenharmony_ci for (lambda = 40 ; lambda <= 120 ; lambda++) 92b815c7f3Sopenharmony_ci { L_result = (int32_t) wt_k * dp [best_k - lambda] ; 93b815c7f3Sopenharmony_ci if (L_result > L_max) 94b815c7f3Sopenharmony_ci { Nc = lambda ; 95b815c7f3Sopenharmony_ci L_max = L_result ; 96b815c7f3Sopenharmony_ci } 97b815c7f3Sopenharmony_ci } 98b815c7f3Sopenharmony_ci *Nc_out = Nc ; 99b815c7f3Sopenharmony_ci L_max <<= 1 ; 100b815c7f3Sopenharmony_ci 101b815c7f3Sopenharmony_ci /* Rescaling of L_max 102b815c7f3Sopenharmony_ci */ 103b815c7f3Sopenharmony_ci assert (scal <= 100 && scal >= -100) ; 104b815c7f3Sopenharmony_ci L_max = L_max >> (6 - scal) ; /* sub (6, scal) */ 105b815c7f3Sopenharmony_ci 106b815c7f3Sopenharmony_ci assert (Nc <= 120 && Nc >= 40) ; 107b815c7f3Sopenharmony_ci 108b815c7f3Sopenharmony_ci /* Compute the power of the reconstructed short term residual 109b815c7f3Sopenharmony_ci * signal dp [..] 110b815c7f3Sopenharmony_ci */ 111b815c7f3Sopenharmony_ci L_power = 0 ; 112b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 113b815c7f3Sopenharmony_ci { register int32_t L_temp ; 114b815c7f3Sopenharmony_ci 115b815c7f3Sopenharmony_ci L_temp = SASR_W (dp [k - Nc], 3) ; 116b815c7f3Sopenharmony_ci L_power += L_temp * L_temp ; 117b815c7f3Sopenharmony_ci } 118b815c7f3Sopenharmony_ci L_power <<= 1 ; /* from L_MULT */ 119b815c7f3Sopenharmony_ci 120b815c7f3Sopenharmony_ci /* Normalization of L_max and L_power */ 121b815c7f3Sopenharmony_ci 122b815c7f3Sopenharmony_ci if (L_max <= 0) 123b815c7f3Sopenharmony_ci { *bc_out = 0 ; 124b815c7f3Sopenharmony_ci return ; 125b815c7f3Sopenharmony_ci } 126b815c7f3Sopenharmony_ci if (L_max >= L_power) 127b815c7f3Sopenharmony_ci { *bc_out = 3 ; 128b815c7f3Sopenharmony_ci return ; 129b815c7f3Sopenharmony_ci } 130b815c7f3Sopenharmony_ci 131b815c7f3Sopenharmony_ci temp = gsm_norm (L_power) ; 132b815c7f3Sopenharmony_ci 133b815c7f3Sopenharmony_ci R = SASR (L_max << temp, 16) ; 134b815c7f3Sopenharmony_ci S = SASR (L_power << temp, 16) ; 135b815c7f3Sopenharmony_ci 136b815c7f3Sopenharmony_ci /* Coding of the LTP gain 137b815c7f3Sopenharmony_ci */ 138b815c7f3Sopenharmony_ci 139b815c7f3Sopenharmony_ci /* Table 4.3a must be used to obtain the level DLB [i] for the 140b815c7f3Sopenharmony_ci * quantization of the LTP gain b to get the coded version bc. 141b815c7f3Sopenharmony_ci */ 142b815c7f3Sopenharmony_ci for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ; 143b815c7f3Sopenharmony_ci *bc_out = bc ; 144b815c7f3Sopenharmony_ci} 145b815c7f3Sopenharmony_ci 146b815c7f3Sopenharmony_ci#endif /* LTP_CUT */ 147b815c7f3Sopenharmony_ci 148b815c7f3Sopenharmony_cistatic void Calculation_of_the_LTP_parameters ( 149b815c7f3Sopenharmony_ci register int16_t * d, /* [0..39] IN */ 150b815c7f3Sopenharmony_ci register int16_t * dp, /* [-120..-1] IN */ 151b815c7f3Sopenharmony_ci int16_t * bc_out, /* OUT */ 152b815c7f3Sopenharmony_ci int16_t * Nc_out /* OUT */) 153b815c7f3Sopenharmony_ci{ 154b815c7f3Sopenharmony_ci register int k, lambda ; 155b815c7f3Sopenharmony_ci int16_t Nc, bc ; 156b815c7f3Sopenharmony_ci int16_t wt [40] ; 157b815c7f3Sopenharmony_ci 158b815c7f3Sopenharmony_ci int32_t L_max, L_power ; 159b815c7f3Sopenharmony_ci int16_t R, S, dmax, scal ; 160b815c7f3Sopenharmony_ci register int16_t temp ; 161b815c7f3Sopenharmony_ci 162b815c7f3Sopenharmony_ci /* Search of the optimum scaling of d [0..39]. 163b815c7f3Sopenharmony_ci */ 164b815c7f3Sopenharmony_ci dmax = 0 ; 165b815c7f3Sopenharmony_ci 166b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 167b815c7f3Sopenharmony_ci { temp = d [k] ; 168b815c7f3Sopenharmony_ci temp = GSM_ABS (temp) ; 169b815c7f3Sopenharmony_ci if (temp > dmax) dmax = temp ; 170b815c7f3Sopenharmony_ci } 171b815c7f3Sopenharmony_ci 172b815c7f3Sopenharmony_ci temp = 0 ; 173b815c7f3Sopenharmony_ci if (dmax == 0) 174b815c7f3Sopenharmony_ci scal = 0 ; 175b815c7f3Sopenharmony_ci else 176b815c7f3Sopenharmony_ci { assert (dmax > 0) ; 177b815c7f3Sopenharmony_ci temp = gsm_norm ((int32_t) dmax << 16) ; 178b815c7f3Sopenharmony_ci } 179b815c7f3Sopenharmony_ci 180b815c7f3Sopenharmony_ci if (temp > 6) scal = 0 ; 181b815c7f3Sopenharmony_ci else scal = 6 - temp ; 182b815c7f3Sopenharmony_ci 183b815c7f3Sopenharmony_ci assert (scal >= 0) ; 184b815c7f3Sopenharmony_ci 185b815c7f3Sopenharmony_ci /* Initialization of a working array wt 186b815c7f3Sopenharmony_ci */ 187b815c7f3Sopenharmony_ci 188b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) wt [k] = SASR_W (d [k], scal) ; 189b815c7f3Sopenharmony_ci 190b815c7f3Sopenharmony_ci /* Search for the maximum cross-correlation and coding of the LTP lag */ 191b815c7f3Sopenharmony_ci L_max = 0 ; 192b815c7f3Sopenharmony_ci Nc = 40 ; /* index for the maximum cross-correlation */ 193b815c7f3Sopenharmony_ci 194b815c7f3Sopenharmony_ci for (lambda = 40 ; lambda <= 120 ; lambda++) 195b815c7f3Sopenharmony_ci { 196b815c7f3Sopenharmony_ci 197b815c7f3Sopenharmony_ci# undef STEP 198b815c7f3Sopenharmony_ci# define STEP(k) (int32_t) wt [k] * dp [k - lambda] 199b815c7f3Sopenharmony_ci 200b815c7f3Sopenharmony_ci register int32_t L_result ; 201b815c7f3Sopenharmony_ci 202b815c7f3Sopenharmony_ci L_result = STEP (0) ; L_result += STEP (1) ; 203b815c7f3Sopenharmony_ci L_result += STEP (2) ; L_result += STEP (3) ; 204b815c7f3Sopenharmony_ci L_result += STEP (4) ; L_result += STEP (5) ; 205b815c7f3Sopenharmony_ci L_result += STEP (6) ; L_result += STEP (7) ; 206b815c7f3Sopenharmony_ci L_result += STEP (8) ; L_result += STEP (9) ; 207b815c7f3Sopenharmony_ci L_result += STEP (10) ; L_result += STEP (11) ; 208b815c7f3Sopenharmony_ci L_result += STEP (12) ; L_result += STEP (13) ; 209b815c7f3Sopenharmony_ci L_result += STEP (14) ; L_result += STEP (15) ; 210b815c7f3Sopenharmony_ci L_result += STEP (16) ; L_result += STEP (17) ; 211b815c7f3Sopenharmony_ci L_result += STEP (18) ; L_result += STEP (19) ; 212b815c7f3Sopenharmony_ci L_result += STEP (20) ; L_result += STEP (21) ; 213b815c7f3Sopenharmony_ci L_result += STEP (22) ; L_result += STEP (23) ; 214b815c7f3Sopenharmony_ci L_result += STEP (24) ; L_result += STEP (25) ; 215b815c7f3Sopenharmony_ci L_result += STEP (26) ; L_result += STEP (27) ; 216b815c7f3Sopenharmony_ci L_result += STEP (28) ; L_result += STEP (29) ; 217b815c7f3Sopenharmony_ci L_result += STEP (30) ; L_result += STEP (31) ; 218b815c7f3Sopenharmony_ci L_result += STEP (32) ; L_result += STEP (33) ; 219b815c7f3Sopenharmony_ci L_result += STEP (34) ; L_result += STEP (35) ; 220b815c7f3Sopenharmony_ci L_result += STEP (36) ; L_result += STEP (37) ; 221b815c7f3Sopenharmony_ci L_result += STEP (38) ; L_result += STEP (39) ; 222b815c7f3Sopenharmony_ci 223b815c7f3Sopenharmony_ci if (L_result > L_max) 224b815c7f3Sopenharmony_ci { Nc = lambda ; 225b815c7f3Sopenharmony_ci L_max = L_result ; 226b815c7f3Sopenharmony_ci } 227b815c7f3Sopenharmony_ci } 228b815c7f3Sopenharmony_ci 229b815c7f3Sopenharmony_ci *Nc_out = Nc ; 230b815c7f3Sopenharmony_ci 231b815c7f3Sopenharmony_ci L_max <<= 1 ; 232b815c7f3Sopenharmony_ci 233b815c7f3Sopenharmony_ci /* Rescaling of L_max 234b815c7f3Sopenharmony_ci */ 235b815c7f3Sopenharmony_ci assert (scal <= 100 && scal >= -100) ; 236b815c7f3Sopenharmony_ci L_max = L_max >> (6 - scal) ; /* sub (6, scal) */ 237b815c7f3Sopenharmony_ci 238b815c7f3Sopenharmony_ci assert (Nc <= 120 && Nc >= 40) ; 239b815c7f3Sopenharmony_ci 240b815c7f3Sopenharmony_ci /* Compute the power of the reconstructed short term residual 241b815c7f3Sopenharmony_ci * signal dp [..] 242b815c7f3Sopenharmony_ci */ 243b815c7f3Sopenharmony_ci L_power = 0 ; 244b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 245b815c7f3Sopenharmony_ci { register int32_t L_temp ; 246b815c7f3Sopenharmony_ci 247b815c7f3Sopenharmony_ci L_temp = SASR_W (dp [k - Nc], 3) ; 248b815c7f3Sopenharmony_ci L_power += L_temp * L_temp ; 249b815c7f3Sopenharmony_ci } 250b815c7f3Sopenharmony_ci L_power <<= 1 ; /* from L_MULT */ 251b815c7f3Sopenharmony_ci 252b815c7f3Sopenharmony_ci /* Normalization of L_max and L_power 253b815c7f3Sopenharmony_ci */ 254b815c7f3Sopenharmony_ci 255b815c7f3Sopenharmony_ci if (L_max <= 0) 256b815c7f3Sopenharmony_ci { *bc_out = 0 ; 257b815c7f3Sopenharmony_ci return ; 258b815c7f3Sopenharmony_ci } 259b815c7f3Sopenharmony_ci if (L_max >= L_power) 260b815c7f3Sopenharmony_ci { *bc_out = 3 ; 261b815c7f3Sopenharmony_ci return ; 262b815c7f3Sopenharmony_ci } 263b815c7f3Sopenharmony_ci 264b815c7f3Sopenharmony_ci temp = gsm_norm (L_power) ; 265b815c7f3Sopenharmony_ci 266b815c7f3Sopenharmony_ci R = SASR_L (L_max << temp, 16) ; 267b815c7f3Sopenharmony_ci S = SASR_L (L_power << temp, 16) ; 268b815c7f3Sopenharmony_ci 269b815c7f3Sopenharmony_ci /* Coding of the LTP gain 270b815c7f3Sopenharmony_ci */ 271b815c7f3Sopenharmony_ci 272b815c7f3Sopenharmony_ci /* Table 4.3a must be used to obtain the level DLB [i] for the 273b815c7f3Sopenharmony_ci * quantization of the LTP gain b to get the coded version bc. 274b815c7f3Sopenharmony_ci */ 275b815c7f3Sopenharmony_ci for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ; 276b815c7f3Sopenharmony_ci *bc_out = bc ; 277b815c7f3Sopenharmony_ci} 278b815c7f3Sopenharmony_ci 279b815c7f3Sopenharmony_ci#else /* USE_FLOAT_MUL */ 280b815c7f3Sopenharmony_ci 281b815c7f3Sopenharmony_ci#ifdef LTP_CUT 282b815c7f3Sopenharmony_ci 283b815c7f3Sopenharmony_cistatic void Cut_Calculation_of_the_LTP_parameters ( 284b815c7f3Sopenharmony_ci struct gsm_state * st, /* IN */ 285b815c7f3Sopenharmony_ci register int16_t * d, /* [0..39] IN */ 286b815c7f3Sopenharmony_ci register int16_t * dp, /* [-120..-1] IN */ 287b815c7f3Sopenharmony_ci int16_t * bc_out, /* OUT */ 288b815c7f3Sopenharmony_ci int16_t * Nc_out /* OUT */) 289b815c7f3Sopenharmony_ci{ 290b815c7f3Sopenharmony_ci register int k, lambda ; 291b815c7f3Sopenharmony_ci int16_t Nc, bc ; 292b815c7f3Sopenharmony_ci int16_t ltp_cut ; 293b815c7f3Sopenharmony_ci 294b815c7f3Sopenharmony_ci float wt_float [40] ; 295b815c7f3Sopenharmony_ci float dp_float_base [120], * dp_float = dp_float_base + 120 ; 296b815c7f3Sopenharmony_ci 297b815c7f3Sopenharmony_ci int32_t L_max, L_power ; 298b815c7f3Sopenharmony_ci int16_t R, S, dmax, scal ; 299b815c7f3Sopenharmony_ci register int16_t temp ; 300b815c7f3Sopenharmony_ci 301b815c7f3Sopenharmony_ci /* Search of the optimum scaling of d [0..39]. 302b815c7f3Sopenharmony_ci */ 303b815c7f3Sopenharmony_ci dmax = 0 ; 304b815c7f3Sopenharmony_ci 305b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 306b815c7f3Sopenharmony_ci { temp = d [k] ; 307b815c7f3Sopenharmony_ci temp = GSM_ABS (temp) ; 308b815c7f3Sopenharmony_ci if (temp > dmax) dmax = temp ; 309b815c7f3Sopenharmony_ci } 310b815c7f3Sopenharmony_ci 311b815c7f3Sopenharmony_ci temp = 0 ; 312b815c7f3Sopenharmony_ci if (dmax == 0) scal = 0 ; 313b815c7f3Sopenharmony_ci else 314b815c7f3Sopenharmony_ci { assert (dmax > 0) ; 315b815c7f3Sopenharmony_ci temp = gsm_norm ((int32_t) dmax << 16) ; 316b815c7f3Sopenharmony_ci } 317b815c7f3Sopenharmony_ci 318b815c7f3Sopenharmony_ci if (temp > 6) scal = 0 ; 319b815c7f3Sopenharmony_ci else scal = 6 - temp ; 320b815c7f3Sopenharmony_ci 321b815c7f3Sopenharmony_ci assert (scal >= 0) ; 322b815c7f3Sopenharmony_ci ltp_cut = (int32_t) SASR_W (dmax, scal) * st->ltp_cut / 100 ; 323b815c7f3Sopenharmony_ci 324b815c7f3Sopenharmony_ci /* Initialization of a working array wt */ 325b815c7f3Sopenharmony_ci 326b815c7f3Sopenharmony_ci for (k = 0 ; k < 40 ; k++) 327b815c7f3Sopenharmony_ci { register int16_t w = SASR_W (d [k], scal) ; 328b815c7f3Sopenharmony_ci if (w < 0 ? w > -ltp_cut : w < ltp_cut) 329b815c7f3Sopenharmony_ci wt_float [k] = 0.0 ; 330b815c7f3Sopenharmony_ci else 331b815c7f3Sopenharmony_ci wt_float [k] = w ; 332b815c7f3Sopenharmony_ci } 333b815c7f3Sopenharmony_ci for (k = -120 ; k < 0 ; k++) dp_float [k] = dp [k] ; 334b815c7f3Sopenharmony_ci 335b815c7f3Sopenharmony_ci /* Search for the maximum cross-correlation and coding of the LTP lag 336b815c7f3Sopenharmony_ci */ 337b815c7f3Sopenharmony_ci L_max = 0 ; 338b815c7f3Sopenharmony_ci Nc = 40 ; /* index for the maximum cross-correlation */ 339b815c7f3Sopenharmony_ci 340b815c7f3Sopenharmony_ci for (lambda = 40 ; lambda <= 120 ; lambda += 9) 341b815c7f3Sopenharmony_ci { /* Calculate L_result for l = lambda .. lambda + 9. */ 342b815c7f3Sopenharmony_ci register float *lp = dp_float - lambda ; 343b815c7f3Sopenharmony_ci 344b815c7f3Sopenharmony_ci register float W ; 345b815c7f3Sopenharmony_ci register float a = lp [-8], b = lp [-7], c = lp [-6], 346b815c7f3Sopenharmony_ci d = lp [-5], e = lp [-4], f = lp [-3], 347b815c7f3Sopenharmony_ci g = lp [-2], h = lp [-1] ; 348b815c7f3Sopenharmony_ci register float E ; 349b815c7f3Sopenharmony_ci register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, 350b815c7f3Sopenharmony_ci S5 = 0, S6 = 0, S7 = 0, S8 = 0 ; 351b815c7f3Sopenharmony_ci 352b815c7f3Sopenharmony_ci# undef STEP 353b815c7f3Sopenharmony_ci# define STEP(K, a, b, c, d, e, f, g, h) \ 354b815c7f3Sopenharmony_ci if ((W = wt_float [K]) != 0.0) { \ 355b815c7f3Sopenharmony_ci E = W * a ; S8 += E ; \ 356b815c7f3Sopenharmony_ci E = W * b ; S7 += E ; \ 357b815c7f3Sopenharmony_ci E = W * c ; S6 += E ; \ 358b815c7f3Sopenharmony_ci E = W * d ; S5 += E ; \ 359b815c7f3Sopenharmony_ci E = W * e ; S4 += E ; \ 360b815c7f3Sopenharmony_ci E = W * f ; S3 += E ; \ 361b815c7f3Sopenharmony_ci E = W * g ; S2 += E ; \ 362b815c7f3Sopenharmony_ci E = W * h ; S1 += E ; \ 363b815c7f3Sopenharmony_ci a = lp [K] ; \ 364b815c7f3Sopenharmony_ci E = W * a ; S0 += E ; } else (a = lp [K]) 365b815c7f3Sopenharmony_ci 366b815c7f3Sopenharmony_ci# define STEP_A(K) STEP (K, a, b, c, d, e, f, g, h) 367b815c7f3Sopenharmony_ci# define STEP_B(K) STEP (K, b, c, d, e, f, g, h, a) 368b815c7f3Sopenharmony_ci# define STEP_C(K) STEP (K, c, d, e, f, g, h, a, b) 369b815c7f3Sopenharmony_ci# define STEP_D(K) STEP (K, d, e, f, g, h, a, b, c) 370b815c7f3Sopenharmony_ci# define STEP_E(K) STEP (K, e, f, g, h, a, b, c, d) 371b815c7f3Sopenharmony_ci# define STEP_F(K) STEP (K, f, g, h, a, b, c, d, e) 372b815c7f3Sopenharmony_ci# define STEP_G(K) STEP (K, g, h, a, b, c, d, e, f) 373b815c7f3Sopenharmony_ci# define STEP_H(K) STEP (K, h, a, b, c, d, e, f, g) 374b815c7f3Sopenharmony_ci 375b815c7f3Sopenharmony_ci STEP_A (0) ; STEP_B (1) ; STEP_C (2) ; STEP_D (3) ; 376b815c7f3Sopenharmony_ci STEP_E (4) ; STEP_F (5) ; STEP_G (6) ; STEP_H (7) ; 377b815c7f3Sopenharmony_ci 378b815c7f3Sopenharmony_ci STEP_A (8) ; STEP_B (9) ; STEP_C (10) ; STEP_D (11) ; 379b815c7f3Sopenharmony_ci STEP_E (12) ; STEP_F (13) ; STEP_G (14) ; STEP_H (15) ; 380b815c7f3Sopenharmony_ci 381b815c7f3Sopenharmony_ci STEP_A (16) ; STEP_B (17) ; STEP_C (18) ; STEP_D (19) ; 382b815c7f3Sopenharmony_ci STEP_E (20) ; STEP_F (21) ; STEP_G (22) ; STEP_H (23) ; 383b815c7f3Sopenharmony_ci 384b815c7f3Sopenharmony_ci STEP_A (24) ; STEP_B (25) ; STEP_C (26) ; STEP_D (27) ; 385b815c7f3Sopenharmony_ci STEP_E (28) ; STEP_F (29) ; STEP_G (30) ; STEP_H (31) ; 386b815c7f3Sopenharmony_ci 387b815c7f3Sopenharmony_ci STEP_A (32) ; STEP_B (33) ; STEP_C (34) ; STEP_D (35) ; 388b815c7f3Sopenharmony_ci STEP_E (36) ; STEP_F (37) ; STEP_G (38) ; STEP_H (39) ; 389b815c7f3Sopenharmony_ci 390b815c7f3Sopenharmony_ci# undef STEP_A 391b815c7f3Sopenharmony_ci# undef STEP_B 392b815c7f3Sopenharmony_ci# undef STEP_C 393b815c7f3Sopenharmony_ci# undef STEP_D 394b815c7f3Sopenharmony_ci# undef STEP_E 395b815c7f3Sopenharmony_ci# undef STEP_F 396b815c7f3Sopenharmony_ci# undef STEP_G 397b815c7f3Sopenharmony_ci# undef STEP_H 398b815c7f3Sopenharmony_ci 399b815c7f3Sopenharmony_ci if (S0 > L_max) { L_max = S0 ; Nc = lambda ; } 400b815c7f3Sopenharmony_ci if (S1 > L_max) { L_max = S1 ; Nc = lambda + 1 ; } 401b815c7f3Sopenharmony_ci if (S2 > L_max) { L_max = S2 ; Nc = lambda + 2 ; } 402b815c7f3Sopenharmony_ci if (S3 > L_max) { L_max = S3 ; Nc = lambda + 3 ; } 403b815c7f3Sopenharmony_ci if (S4 > L_max) { L_max = S4 ; Nc = lambda + 4 ; } 404b815c7f3Sopenharmony_ci if (S5 > L_max) { L_max = S5 ; Nc = lambda + 5 ; } 405b815c7f3Sopenharmony_ci if (S6 > L_max) { L_max = S6 ; Nc = lambda + 6 ; } 406b815c7f3Sopenharmony_ci if (S7 > L_max) { L_max = S7 ; Nc = lambda + 7 ; } 407b815c7f3Sopenharmony_ci if (S8 > L_max) { L_max = S8 ; Nc = lambda + 8 ; } 408b815c7f3Sopenharmony_ci 409b815c7f3Sopenharmony_ci } 410b815c7f3Sopenharmony_ci *Nc_out = Nc ; 411b815c7f3Sopenharmony_ci 412b815c7f3Sopenharmony_ci L_max <<= 1 ; 413b815c7f3Sopenharmony_ci 414b815c7f3Sopenharmony_ci /* Rescaling of L_max 415b815c7f3Sopenharmony_ci */ 416b815c7f3Sopenharmony_ci assert (scal <= 100 && scal >= -100) ; 417b815c7f3Sopenharmony_ci L_max = L_max >> (6 - scal) ; /* sub (6, scal) */ 418b815c7f3Sopenharmony_ci 419b815c7f3Sopenharmony_ci assert (Nc <= 120 && Nc >= 40) ; 420b815c7f3Sopenharmony_ci 421b815c7f3Sopenharmony_ci /* Compute the power of the reconstructed short term residual 422b815c7f3Sopenharmony_ci * signal dp [..] 423b815c7f3Sopenharmony_ci */ 424b815c7f3Sopenharmony_ci L_power = 0 ; 425b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 426b815c7f3Sopenharmony_ci { register int32_t L_temp ; 427b815c7f3Sopenharmony_ci 428b815c7f3Sopenharmony_ci L_temp = SASR_W (dp [k - Nc], 3) ; 429b815c7f3Sopenharmony_ci L_power += L_temp * L_temp ; 430b815c7f3Sopenharmony_ci } 431b815c7f3Sopenharmony_ci L_power <<= 1 ; /* from L_MULT */ 432b815c7f3Sopenharmony_ci 433b815c7f3Sopenharmony_ci /* Normalization of L_max and L_power 434b815c7f3Sopenharmony_ci */ 435b815c7f3Sopenharmony_ci 436b815c7f3Sopenharmony_ci if (L_max <= 0) 437b815c7f3Sopenharmony_ci { *bc_out = 0 ; 438b815c7f3Sopenharmony_ci return ; 439b815c7f3Sopenharmony_ci } 440b815c7f3Sopenharmony_ci if (L_max >= L_power) 441b815c7f3Sopenharmony_ci { *bc_out = 3 ; 442b815c7f3Sopenharmony_ci return ; 443b815c7f3Sopenharmony_ci } 444b815c7f3Sopenharmony_ci 445b815c7f3Sopenharmony_ci temp = gsm_norm (L_power) ; 446b815c7f3Sopenharmony_ci 447b815c7f3Sopenharmony_ci R = SASR (L_max << temp, 16) ; 448b815c7f3Sopenharmony_ci S = SASR (L_power << temp, 16) ; 449b815c7f3Sopenharmony_ci 450b815c7f3Sopenharmony_ci /* Coding of the LTP gain 451b815c7f3Sopenharmony_ci */ 452b815c7f3Sopenharmony_ci 453b815c7f3Sopenharmony_ci /* Table 4.3a must be used to obtain the level DLB [i] for the 454b815c7f3Sopenharmony_ci * quantization of the LTP gain b to get the coded version bc. 455b815c7f3Sopenharmony_ci */ 456b815c7f3Sopenharmony_ci for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ; 457b815c7f3Sopenharmony_ci *bc_out = bc ; 458b815c7f3Sopenharmony_ci} 459b815c7f3Sopenharmony_ci 460b815c7f3Sopenharmony_ci#endif /* LTP_CUT */ 461b815c7f3Sopenharmony_ci 462b815c7f3Sopenharmony_cistatic void Calculation_of_the_LTP_parameters ( 463b815c7f3Sopenharmony_ci register int16_t * din, /* [0..39] IN */ 464b815c7f3Sopenharmony_ci register int16_t * dp, /* [-120..-1] IN */ 465b815c7f3Sopenharmony_ci int16_t * bc_out, /* OUT */ 466b815c7f3Sopenharmony_ci int16_t * Nc_out /* OUT */) 467b815c7f3Sopenharmony_ci{ 468b815c7f3Sopenharmony_ci register int k, lambda ; 469b815c7f3Sopenharmony_ci int16_t Nc, bc ; 470b815c7f3Sopenharmony_ci 471b815c7f3Sopenharmony_ci float wt_float [40] ; 472b815c7f3Sopenharmony_ci float dp_float_base [120], * dp_float = dp_float_base + 120 ; 473b815c7f3Sopenharmony_ci 474b815c7f3Sopenharmony_ci int32_t L_max, L_power ; 475b815c7f3Sopenharmony_ci int16_t R, S, dmax, scal ; 476b815c7f3Sopenharmony_ci register int16_t temp ; 477b815c7f3Sopenharmony_ci 478b815c7f3Sopenharmony_ci /* Search of the optimum scaling of d [0..39]. 479b815c7f3Sopenharmony_ci */ 480b815c7f3Sopenharmony_ci dmax = 0 ; 481b815c7f3Sopenharmony_ci 482b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 483b815c7f3Sopenharmony_ci { temp = din [k] ; 484b815c7f3Sopenharmony_ci temp = GSM_ABS (temp) ; 485b815c7f3Sopenharmony_ci if (temp > dmax) dmax = temp ; 486b815c7f3Sopenharmony_ci } 487b815c7f3Sopenharmony_ci 488b815c7f3Sopenharmony_ci temp = 0 ; 489b815c7f3Sopenharmony_ci if (dmax == 0) scal = 0 ; 490b815c7f3Sopenharmony_ci else 491b815c7f3Sopenharmony_ci { assert (dmax > 0) ; 492b815c7f3Sopenharmony_ci temp = gsm_norm ((int32_t) dmax << 16) ; 493b815c7f3Sopenharmony_ci } 494b815c7f3Sopenharmony_ci 495b815c7f3Sopenharmony_ci if (temp > 6) scal = 0 ; 496b815c7f3Sopenharmony_ci else scal = 6 - temp ; 497b815c7f3Sopenharmony_ci 498b815c7f3Sopenharmony_ci assert (scal >= 0) ; 499b815c7f3Sopenharmony_ci 500b815c7f3Sopenharmony_ci /* Initialization of a working array wt */ 501b815c7f3Sopenharmony_ci 502b815c7f3Sopenharmony_ci for (k = 0 ; k < 40 ; k++) wt_float [k] = SASR_W (din [k], scal) ; 503b815c7f3Sopenharmony_ci for (k = -120 ; k < 0 ; k++) dp_float [k] = dp [k] ; 504b815c7f3Sopenharmony_ci 505b815c7f3Sopenharmony_ci /* Search for the maximum cross-correlation and coding of the LTP lag 506b815c7f3Sopenharmony_ci */ 507b815c7f3Sopenharmony_ci L_max = 0 ; 508b815c7f3Sopenharmony_ci Nc = 40 ; /* index for the maximum cross-correlation */ 509b815c7f3Sopenharmony_ci 510b815c7f3Sopenharmony_ci for (lambda = 40 ; lambda <= 120 ; lambda += 9) 511b815c7f3Sopenharmony_ci { /* Calculate L_result for l = lambda .. lambda + 9. */ 512b815c7f3Sopenharmony_ci register float *lp = dp_float - lambda ; 513b815c7f3Sopenharmony_ci 514b815c7f3Sopenharmony_ci register float W ; 515b815c7f3Sopenharmony_ci register float a = lp [-8], b = lp [-7], c = lp [-6], 516b815c7f3Sopenharmony_ci d = lp [-5], e = lp [-4], f = lp [-3], 517b815c7f3Sopenharmony_ci g = lp [-2], h = lp [-1] ; 518b815c7f3Sopenharmony_ci register float E ; 519b815c7f3Sopenharmony_ci register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, 520b815c7f3Sopenharmony_ci S5 = 0, S6 = 0, S7 = 0, S8 = 0 ; 521b815c7f3Sopenharmony_ci 522b815c7f3Sopenharmony_ci# undef STEP 523b815c7f3Sopenharmony_ci# define STEP(K, a, b, c, d, e, f, g, h) \ 524b815c7f3Sopenharmony_ci W = wt_float [K] ; \ 525b815c7f3Sopenharmony_ci E = W * a ; S8 += E ; \ 526b815c7f3Sopenharmony_ci E = W * b ; S7 += E ; \ 527b815c7f3Sopenharmony_ci E = W * c ; S6 += E ; \ 528b815c7f3Sopenharmony_ci E = W * d ; S5 += E ; \ 529b815c7f3Sopenharmony_ci E = W * e ; S4 += E ; \ 530b815c7f3Sopenharmony_ci E = W * f ; S3 += E ; \ 531b815c7f3Sopenharmony_ci E = W * g ; S2 += E ; \ 532b815c7f3Sopenharmony_ci E = W * h ; S1 += E ; \ 533b815c7f3Sopenharmony_ci a = lp [K] ; \ 534b815c7f3Sopenharmony_ci E = W * a ; S0 += E 535b815c7f3Sopenharmony_ci 536b815c7f3Sopenharmony_ci# define STEP_A(K) STEP (K, a, b, c, d, e, f, g, h) 537b815c7f3Sopenharmony_ci# define STEP_B(K) STEP (K, b, c, d, e, f, g, h, a) 538b815c7f3Sopenharmony_ci# define STEP_C(K) STEP (K, c, d, e, f, g, h, a, b) 539b815c7f3Sopenharmony_ci# define STEP_D(K) STEP (K, d, e, f, g, h, a, b, c) 540b815c7f3Sopenharmony_ci# define STEP_E(K) STEP (K, e, f, g, h, a, b, c, d) 541b815c7f3Sopenharmony_ci# define STEP_F(K) STEP (K, f, g, h, a, b, c, d, e) 542b815c7f3Sopenharmony_ci# define STEP_G(K) STEP (K, g, h, a, b, c, d, e, f) 543b815c7f3Sopenharmony_ci# define STEP_H(K) STEP (K, h, a, b, c, d, e, f, g) 544b815c7f3Sopenharmony_ci 545b815c7f3Sopenharmony_ci STEP_A (0) ; STEP_B (1) ; STEP_C (2) ; STEP_D (3) ; 546b815c7f3Sopenharmony_ci STEP_E (4) ; STEP_F (5) ; STEP_G (6) ; STEP_H (7) ; 547b815c7f3Sopenharmony_ci 548b815c7f3Sopenharmony_ci STEP_A (8) ; STEP_B (9) ; STEP_C (10) ; STEP_D (11) ; 549b815c7f3Sopenharmony_ci STEP_E (12) ; STEP_F (13) ; STEP_G (14) ; STEP_H (15) ; 550b815c7f3Sopenharmony_ci 551b815c7f3Sopenharmony_ci STEP_A (16) ; STEP_B (17) ; STEP_C (18) ; STEP_D (19) ; 552b815c7f3Sopenharmony_ci STEP_E (20) ; STEP_F (21) ; STEP_G (22) ; STEP_H (23) ; 553b815c7f3Sopenharmony_ci 554b815c7f3Sopenharmony_ci STEP_A (24) ; STEP_B (25) ; STEP_C (26) ; STEP_D (27) ; 555b815c7f3Sopenharmony_ci STEP_E (28) ; STEP_F (29) ; STEP_G (30) ; STEP_H (31) ; 556b815c7f3Sopenharmony_ci 557b815c7f3Sopenharmony_ci STEP_A (32) ; STEP_B (33) ; STEP_C (34) ; STEP_D (35) ; 558b815c7f3Sopenharmony_ci STEP_E (36) ; STEP_F (37) ; STEP_G (38) ; STEP_H (39) ; 559b815c7f3Sopenharmony_ci 560b815c7f3Sopenharmony_ci# undef STEP_A 561b815c7f3Sopenharmony_ci# undef STEP_B 562b815c7f3Sopenharmony_ci# undef STEP_C 563b815c7f3Sopenharmony_ci# undef STEP_D 564b815c7f3Sopenharmony_ci# undef STEP_E 565b815c7f3Sopenharmony_ci# undef STEP_F 566b815c7f3Sopenharmony_ci# undef STEP_G 567b815c7f3Sopenharmony_ci# undef STEP_H 568b815c7f3Sopenharmony_ci 569b815c7f3Sopenharmony_ci if (S0 > L_max) { L_max = S0 ; Nc = lambda ; } 570b815c7f3Sopenharmony_ci if (S1 > L_max) { L_max = S1 ; Nc = lambda + 1 ; } 571b815c7f3Sopenharmony_ci if (S2 > L_max) { L_max = S2 ; Nc = lambda + 2 ; } 572b815c7f3Sopenharmony_ci if (S3 > L_max) { L_max = S3 ; Nc = lambda + 3 ; } 573b815c7f3Sopenharmony_ci if (S4 > L_max) { L_max = S4 ; Nc = lambda + 4 ; } 574b815c7f3Sopenharmony_ci if (S5 > L_max) { L_max = S5 ; Nc = lambda + 5 ; } 575b815c7f3Sopenharmony_ci if (S6 > L_max) { L_max = S6 ; Nc = lambda + 6 ; } 576b815c7f3Sopenharmony_ci if (S7 > L_max) { L_max = S7 ; Nc = lambda + 7 ; } 577b815c7f3Sopenharmony_ci if (S8 > L_max) { L_max = S8 ; Nc = lambda + 8 ; } 578b815c7f3Sopenharmony_ci } 579b815c7f3Sopenharmony_ci *Nc_out = Nc ; 580b815c7f3Sopenharmony_ci 581b815c7f3Sopenharmony_ci L_max <<= 1 ; 582b815c7f3Sopenharmony_ci 583b815c7f3Sopenharmony_ci /* Rescaling of L_max 584b815c7f3Sopenharmony_ci */ 585b815c7f3Sopenharmony_ci assert (scal <= 100 && scal >= -100) ; 586b815c7f3Sopenharmony_ci L_max = L_max >> (6 - scal) ; /* sub (6, scal) */ 587b815c7f3Sopenharmony_ci 588b815c7f3Sopenharmony_ci assert (Nc <= 120 && Nc >= 40) ; 589b815c7f3Sopenharmony_ci 590b815c7f3Sopenharmony_ci /* Compute the power of the reconstructed short term residual 591b815c7f3Sopenharmony_ci * signal dp [..] 592b815c7f3Sopenharmony_ci */ 593b815c7f3Sopenharmony_ci L_power = 0 ; 594b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 595b815c7f3Sopenharmony_ci { register int32_t L_temp ; 596b815c7f3Sopenharmony_ci 597b815c7f3Sopenharmony_ci L_temp = SASR_W (dp [k - Nc], 3) ; 598b815c7f3Sopenharmony_ci L_power += L_temp * L_temp ; 599b815c7f3Sopenharmony_ci } 600b815c7f3Sopenharmony_ci L_power <<= 1 ; /* from L_MULT */ 601b815c7f3Sopenharmony_ci 602b815c7f3Sopenharmony_ci /* Normalization of L_max and L_power 603b815c7f3Sopenharmony_ci */ 604b815c7f3Sopenharmony_ci 605b815c7f3Sopenharmony_ci if (L_max <= 0) 606b815c7f3Sopenharmony_ci { *bc_out = 0 ; 607b815c7f3Sopenharmony_ci return ; 608b815c7f3Sopenharmony_ci } 609b815c7f3Sopenharmony_ci if (L_max >= L_power) 610b815c7f3Sopenharmony_ci { *bc_out = 3 ; 611b815c7f3Sopenharmony_ci return ; 612b815c7f3Sopenharmony_ci } 613b815c7f3Sopenharmony_ci 614b815c7f3Sopenharmony_ci temp = gsm_norm (L_power) ; 615b815c7f3Sopenharmony_ci 616b815c7f3Sopenharmony_ci R = SASR_L (L_max << temp, 16) ; 617b815c7f3Sopenharmony_ci S = SASR_L (L_power << temp, 16) ; 618b815c7f3Sopenharmony_ci 619b815c7f3Sopenharmony_ci /* Coding of the LTP gain 620b815c7f3Sopenharmony_ci */ 621b815c7f3Sopenharmony_ci 622b815c7f3Sopenharmony_ci /* Table 4.3a must be used to obtain the level DLB [i] for the 623b815c7f3Sopenharmony_ci * quantization of the LTP gain b to get the coded version bc. 624b815c7f3Sopenharmony_ci */ 625b815c7f3Sopenharmony_ci for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ; 626b815c7f3Sopenharmony_ci *bc_out = bc ; 627b815c7f3Sopenharmony_ci} 628b815c7f3Sopenharmony_ci 629b815c7f3Sopenharmony_ci#ifdef FAST 630b815c7f3Sopenharmony_ci#ifdef LTP_CUT 631b815c7f3Sopenharmony_ci 632b815c7f3Sopenharmony_cistatic void Cut_Fast_Calculation_of_the_LTP_parameters ( 633b815c7f3Sopenharmony_ci struct gsm_state * st, /* IN */ 634b815c7f3Sopenharmony_ci register int16_t * d, /* [0..39] IN */ 635b815c7f3Sopenharmony_ci register int16_t * dp, /* [-120..-1] IN */ 636b815c7f3Sopenharmony_ci int16_t * bc_out, /* OUT */ 637b815c7f3Sopenharmony_ci int16_t * Nc_out /* OUT */) 638b815c7f3Sopenharmony_ci{ 639b815c7f3Sopenharmony_ci register int k, lambda ; 640b815c7f3Sopenharmony_ci register float wt_float ; 641b815c7f3Sopenharmony_ci int16_t Nc, bc ; 642b815c7f3Sopenharmony_ci int16_t wt_max, best_k, ltp_cut ; 643b815c7f3Sopenharmony_ci 644b815c7f3Sopenharmony_ci float dp_float_base [120], * dp_float = dp_float_base + 120 ; 645b815c7f3Sopenharmony_ci 646b815c7f3Sopenharmony_ci register float L_result, L_max, L_power ; 647b815c7f3Sopenharmony_ci 648b815c7f3Sopenharmony_ci wt_max = 0 ; 649b815c7f3Sopenharmony_ci 650b815c7f3Sopenharmony_ci for (k = 0 ; k < 40 ; ++k) 651b815c7f3Sopenharmony_ci { if (d [k] > wt_max) wt_max = d [best_k = k] ; 652b815c7f3Sopenharmony_ci else if (-d [k] > wt_max) wt_max = -d [best_k = k] ; 653b815c7f3Sopenharmony_ci } 654b815c7f3Sopenharmony_ci 655b815c7f3Sopenharmony_ci assert (wt_max >= 0) ; 656b815c7f3Sopenharmony_ci wt_float = (float) wt_max ; 657b815c7f3Sopenharmony_ci 658b815c7f3Sopenharmony_ci for (k = -120 ; k < 0 ; ++k) dp_float [k] = (float) dp [k] ; 659b815c7f3Sopenharmony_ci 660b815c7f3Sopenharmony_ci /* Search for the maximum cross-correlation and coding of the LTP lag */ 661b815c7f3Sopenharmony_ci L_max = 0 ; 662b815c7f3Sopenharmony_ci Nc = 40 ; /* index for the maximum cross-correlation */ 663b815c7f3Sopenharmony_ci 664b815c7f3Sopenharmony_ci for (lambda = 40 ; lambda <= 120 ; lambda++) 665b815c7f3Sopenharmony_ci { L_result = wt_float * dp_float [best_k - lambda] ; 666b815c7f3Sopenharmony_ci if (L_result > L_max) 667b815c7f3Sopenharmony_ci { Nc = lambda ; 668b815c7f3Sopenharmony_ci L_max = L_result ; 669b815c7f3Sopenharmony_ci } 670b815c7f3Sopenharmony_ci } 671b815c7f3Sopenharmony_ci 672b815c7f3Sopenharmony_ci *Nc_out = Nc ; 673b815c7f3Sopenharmony_ci if (L_max <= 0.) 674b815c7f3Sopenharmony_ci { *bc_out = 0 ; 675b815c7f3Sopenharmony_ci return ; 676b815c7f3Sopenharmony_ci } 677b815c7f3Sopenharmony_ci 678b815c7f3Sopenharmony_ci /* Compute the power of the reconstructed short term residual 679b815c7f3Sopenharmony_ci * signal dp [..] 680b815c7f3Sopenharmony_ci */ 681b815c7f3Sopenharmony_ci dp_float -= Nc ; 682b815c7f3Sopenharmony_ci L_power = 0 ; 683b815c7f3Sopenharmony_ci for (k = 0 ; k < 40 ; ++k) 684b815c7f3Sopenharmony_ci { register float f = dp_float [k] ; 685b815c7f3Sopenharmony_ci L_power += f * f ; 686b815c7f3Sopenharmony_ci } 687b815c7f3Sopenharmony_ci 688b815c7f3Sopenharmony_ci if (L_max >= L_power) 689b815c7f3Sopenharmony_ci { *bc_out = 3 ; 690b815c7f3Sopenharmony_ci return ; 691b815c7f3Sopenharmony_ci } 692b815c7f3Sopenharmony_ci 693b815c7f3Sopenharmony_ci /* Coding of the LTP gain 694b815c7f3Sopenharmony_ci * Table 4.3a must be used to obtain the level DLB [i] for the 695b815c7f3Sopenharmony_ci * quantization of the LTP gain b to get the coded version bc. 696b815c7f3Sopenharmony_ci */ 697b815c7f3Sopenharmony_ci lambda = L_max / L_power * 32768.0 ; 698b815c7f3Sopenharmony_ci for (bc = 0 ; bc <= 2 ; ++bc) if (lambda <= gsm_DLB [bc]) break ; 699b815c7f3Sopenharmony_ci *bc_out = bc ; 700b815c7f3Sopenharmony_ci} 701b815c7f3Sopenharmony_ci 702b815c7f3Sopenharmony_ci#endif /* LTP_CUT */ 703b815c7f3Sopenharmony_ci 704b815c7f3Sopenharmony_cistatic void Fast_Calculation_of_the_LTP_parameters ( 705b815c7f3Sopenharmony_ci register int16_t * din, /* [0..39] IN */ 706b815c7f3Sopenharmony_ci register int16_t * dp, /* [-120..-1] IN */ 707b815c7f3Sopenharmony_ci int16_t * bc_out, /* OUT */ 708b815c7f3Sopenharmony_ci int16_t * Nc_out /* OUT */) 709b815c7f3Sopenharmony_ci{ 710b815c7f3Sopenharmony_ci register int k, lambda ; 711b815c7f3Sopenharmony_ci int16_t Nc, bc ; 712b815c7f3Sopenharmony_ci 713b815c7f3Sopenharmony_ci float wt_float [40] ; 714b815c7f3Sopenharmony_ci float dp_float_base [120], * dp_float = dp_float_base + 120 ; 715b815c7f3Sopenharmony_ci 716b815c7f3Sopenharmony_ci register float L_max, L_power ; 717b815c7f3Sopenharmony_ci 718b815c7f3Sopenharmony_ci for (k = 0 ; k < 40 ; ++k) wt_float [k] = (float) din [k] ; 719b815c7f3Sopenharmony_ci for (k = -120 ; k < 0 ; ++k) dp_float [k] = (float) dp [k] ; 720b815c7f3Sopenharmony_ci 721b815c7f3Sopenharmony_ci /* Search for the maximum cross-correlation and coding of the LTP lag */ 722b815c7f3Sopenharmony_ci L_max = 0 ; 723b815c7f3Sopenharmony_ci Nc = 40 ; /* index for the maximum cross-correlation */ 724b815c7f3Sopenharmony_ci 725b815c7f3Sopenharmony_ci for (lambda = 40 ; lambda <= 120 ; lambda += 9) 726b815c7f3Sopenharmony_ci { /* Calculate L_result for l = lambda .. lambda + 9. */ 727b815c7f3Sopenharmony_ci register float *lp = dp_float - lambda ; 728b815c7f3Sopenharmony_ci 729b815c7f3Sopenharmony_ci register float W ; 730b815c7f3Sopenharmony_ci register float a = lp [-8], b = lp [-7], c = lp [-6], 731b815c7f3Sopenharmony_ci d = lp [-5], e = lp [-4], f = lp [-3], 732b815c7f3Sopenharmony_ci g = lp [-2], h = lp [-1] ; 733b815c7f3Sopenharmony_ci register float E ; 734b815c7f3Sopenharmony_ci register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, 735b815c7f3Sopenharmony_ci S5 = 0, S6 = 0, S7 = 0, S8 = 0 ; 736b815c7f3Sopenharmony_ci 737b815c7f3Sopenharmony_ci# undef STEP 738b815c7f3Sopenharmony_ci# define STEP(K, a, b, c, d, e, f, g, h) \ 739b815c7f3Sopenharmony_ci W = wt_float [K] ; \ 740b815c7f3Sopenharmony_ci E = W * a ; S8 += E ; \ 741b815c7f3Sopenharmony_ci E = W * b ; S7 += E ; \ 742b815c7f3Sopenharmony_ci E = W * c ; S6 += E ; \ 743b815c7f3Sopenharmony_ci E = W * d ; S5 += E ; \ 744b815c7f3Sopenharmony_ci E = W * e ; S4 += E ; \ 745b815c7f3Sopenharmony_ci E = W * f ; S3 += E ; \ 746b815c7f3Sopenharmony_ci E = W * g ; S2 += E ; \ 747b815c7f3Sopenharmony_ci E = W * h ; S1 += E ; \ 748b815c7f3Sopenharmony_ci a = lp [K] ; \ 749b815c7f3Sopenharmony_ci E = W * a ; S0 += E 750b815c7f3Sopenharmony_ci 751b815c7f3Sopenharmony_ci# define STEP_A(K) STEP (K, a, b, c, d, e, f, g, h) 752b815c7f3Sopenharmony_ci# define STEP_B(K) STEP (K, b, c, d, e, f, g, h, a) 753b815c7f3Sopenharmony_ci# define STEP_C(K) STEP (K, c, d, e, f, g, h, a, b) 754b815c7f3Sopenharmony_ci# define STEP_D(K) STEP (K, d, e, f, g, h, a, b, c) 755b815c7f3Sopenharmony_ci# define STEP_E(K) STEP (K, e, f, g, h, a, b, c, d) 756b815c7f3Sopenharmony_ci# define STEP_F(K) STEP (K, f, g, h, a, b, c, d, e) 757b815c7f3Sopenharmony_ci# define STEP_G(K) STEP (K, g, h, a, b, c, d, e, f) 758b815c7f3Sopenharmony_ci# define STEP_H(K) STEP (K, h, a, b, c, d, e, f, g) 759b815c7f3Sopenharmony_ci 760b815c7f3Sopenharmony_ci STEP_A (0) ; STEP_B (1) ; STEP_C (2) ; STEP_D (3) ; 761b815c7f3Sopenharmony_ci STEP_E (4) ; STEP_F (5) ; STEP_G (6) ; STEP_H (7) ; 762b815c7f3Sopenharmony_ci 763b815c7f3Sopenharmony_ci STEP_A (8) ; STEP_B (9) ; STEP_C (10) ; STEP_D (11) ; 764b815c7f3Sopenharmony_ci STEP_E (12) ; STEP_F (13) ; STEP_G (14) ; STEP_H (15) ; 765b815c7f3Sopenharmony_ci 766b815c7f3Sopenharmony_ci STEP_A (16) ; STEP_B (17) ; STEP_C (18) ; STEP_D (19) ; 767b815c7f3Sopenharmony_ci STEP_E (20) ; STEP_F (21) ; STEP_G (22) ; STEP_H (23) ; 768b815c7f3Sopenharmony_ci 769b815c7f3Sopenharmony_ci STEP_A (24) ; STEP_B (25) ; STEP_C (26) ; STEP_D (27) ; 770b815c7f3Sopenharmony_ci STEP_E (28) ; STEP_F (29) ; STEP_G (30) ; STEP_H (31) ; 771b815c7f3Sopenharmony_ci 772b815c7f3Sopenharmony_ci STEP_A (32) ; STEP_B (33) ; STEP_C (34) ; STEP_D (35) ; 773b815c7f3Sopenharmony_ci STEP_E (36) ; STEP_F (37) ; STEP_G (38) ; STEP_H (39) ; 774b815c7f3Sopenharmony_ci 775b815c7f3Sopenharmony_ci if (S0 > L_max) { L_max = S0 ; Nc = lambda ; } 776b815c7f3Sopenharmony_ci if (S1 > L_max) { L_max = S1 ; Nc = lambda + 1 ; } 777b815c7f3Sopenharmony_ci if (S2 > L_max) { L_max = S2 ; Nc = lambda + 2 ; } 778b815c7f3Sopenharmony_ci if (S3 > L_max) { L_max = S3 ; Nc = lambda + 3 ; } 779b815c7f3Sopenharmony_ci if (S4 > L_max) { L_max = S4 ; Nc = lambda + 4 ; } 780b815c7f3Sopenharmony_ci if (S5 > L_max) { L_max = S5 ; Nc = lambda + 5 ; } 781b815c7f3Sopenharmony_ci if (S6 > L_max) { L_max = S6 ; Nc = lambda + 6 ; } 782b815c7f3Sopenharmony_ci if (S7 > L_max) { L_max = S7 ; Nc = lambda + 7 ; } 783b815c7f3Sopenharmony_ci if (S8 > L_max) { L_max = S8 ; Nc = lambda + 8 ; } 784b815c7f3Sopenharmony_ci } 785b815c7f3Sopenharmony_ci *Nc_out = Nc ; 786b815c7f3Sopenharmony_ci 787b815c7f3Sopenharmony_ci if (L_max <= 0.0) 788b815c7f3Sopenharmony_ci { *bc_out = 0 ; 789b815c7f3Sopenharmony_ci return ; 790b815c7f3Sopenharmony_ci } 791b815c7f3Sopenharmony_ci 792b815c7f3Sopenharmony_ci /* Compute the power of the reconstructed short term residual 793b815c7f3Sopenharmony_ci * signal dp [..] 794b815c7f3Sopenharmony_ci */ 795b815c7f3Sopenharmony_ci dp_float -= Nc ; 796b815c7f3Sopenharmony_ci L_power = 0 ; 797b815c7f3Sopenharmony_ci for (k = 0 ; k < 40 ; ++k) 798b815c7f3Sopenharmony_ci { register float f = dp_float [k] ; 799b815c7f3Sopenharmony_ci L_power += f * f ; 800b815c7f3Sopenharmony_ci } 801b815c7f3Sopenharmony_ci 802b815c7f3Sopenharmony_ci if (L_max >= L_power) 803b815c7f3Sopenharmony_ci { *bc_out = 3 ; 804b815c7f3Sopenharmony_ci return ; 805b815c7f3Sopenharmony_ci } 806b815c7f3Sopenharmony_ci 807b815c7f3Sopenharmony_ci /* Coding of the LTP gain 808b815c7f3Sopenharmony_ci * Table 4.3a must be used to obtain the level DLB [i] for the 809b815c7f3Sopenharmony_ci * quantization of the LTP gain b to get the coded version bc. 810b815c7f3Sopenharmony_ci */ 811b815c7f3Sopenharmony_ci lambda = L_max / L_power * 32768.0 ; 812b815c7f3Sopenharmony_ci for (bc = 0 ; bc <= 2 ; ++bc) if (lambda <= gsm_DLB [bc]) break ; 813b815c7f3Sopenharmony_ci *bc_out = bc ; 814b815c7f3Sopenharmony_ci} 815b815c7f3Sopenharmony_ci 816b815c7f3Sopenharmony_ci#endif /* FAST */ 817b815c7f3Sopenharmony_ci#endif /* USE_FLOAT_MUL */ 818b815c7f3Sopenharmony_ci 819b815c7f3Sopenharmony_ci 820b815c7f3Sopenharmony_ci/* 4.2.12 */ 821b815c7f3Sopenharmony_ci 822b815c7f3Sopenharmony_cistatic void Long_term_analysis_filtering ( 823b815c7f3Sopenharmony_ci int16_t bc, /* IN */ 824b815c7f3Sopenharmony_ci int16_t Nc, /* IN */ 825b815c7f3Sopenharmony_ci register int16_t * dp, /* previous d [-120..-1] IN */ 826b815c7f3Sopenharmony_ci register int16_t * d, /* d [0..39] IN */ 827b815c7f3Sopenharmony_ci register int16_t * dpp, /* estimate [0..39] OUT */ 828b815c7f3Sopenharmony_ci register int16_t * e /* long term res. signal [0..39] OUT */) 829b815c7f3Sopenharmony_ci/* 830b815c7f3Sopenharmony_ci * In this part, we have to decode the bc parameter to compute 831b815c7f3Sopenharmony_ci * the samples of the estimate dpp [0..39]. The decoding of bc needs the 832b815c7f3Sopenharmony_ci * use of table 4.3b. The long term residual signal e [0..39] 833b815c7f3Sopenharmony_ci * is then calculated to be fed to the RPE encoding section. 834b815c7f3Sopenharmony_ci */ 835b815c7f3Sopenharmony_ci{ 836b815c7f3Sopenharmony_ci register int k ; 837b815c7f3Sopenharmony_ci 838b815c7f3Sopenharmony_ci# undef STEP 839b815c7f3Sopenharmony_ci# define STEP(BP) \ 840b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) \ 841b815c7f3Sopenharmony_ci { dpp [k] = GSM_MULT_R (BP, dp [k - Nc]) ; \ 842b815c7f3Sopenharmony_ci e [k] = GSM_SUB (d [k], dpp [k]) ; \ 843b815c7f3Sopenharmony_ci } 844b815c7f3Sopenharmony_ci 845b815c7f3Sopenharmony_ci switch (bc) 846b815c7f3Sopenharmony_ci { case 0: STEP (3277) ; break ; 847b815c7f3Sopenharmony_ci case 1: STEP (11469) ; break ; 848b815c7f3Sopenharmony_ci case 2: STEP (21299) ; break ; 849b815c7f3Sopenharmony_ci case 3: STEP (32767) ; break ; 850b815c7f3Sopenharmony_ci } 851b815c7f3Sopenharmony_ci} 852b815c7f3Sopenharmony_ci 853b815c7f3Sopenharmony_civoid Gsm_Long_Term_Predictor ( /* 4x for 160 samples */ 854b815c7f3Sopenharmony_ci 855b815c7f3Sopenharmony_ci struct gsm_state * S, 856b815c7f3Sopenharmony_ci 857b815c7f3Sopenharmony_ci int16_t * d, /* [0..39] residual signal IN */ 858b815c7f3Sopenharmony_ci int16_t * dp, /* [-120..-1] d' IN */ 859b815c7f3Sopenharmony_ci 860b815c7f3Sopenharmony_ci int16_t * e, /* [0..39] OUT */ 861b815c7f3Sopenharmony_ci int16_t * dpp, /* [0..39] OUT */ 862b815c7f3Sopenharmony_ci int16_t * Nc, /* correlation lag OUT */ 863b815c7f3Sopenharmony_ci int16_t * bc /* gain factor OUT */) 864b815c7f3Sopenharmony_ci{ 865b815c7f3Sopenharmony_ci assert (d) ; assert (dp) ; assert (e) ; 866b815c7f3Sopenharmony_ci assert (dpp) ; assert (Nc) ; assert (bc) ; 867b815c7f3Sopenharmony_ci 868b815c7f3Sopenharmony_ci#if defined (FAST) && defined (USE_FLOAT_MUL) 869b815c7f3Sopenharmony_ci if (S->fast) 870b815c7f3Sopenharmony_ci#if defined (LTP_CUT) 871b815c7f3Sopenharmony_ci if (S->ltp_cut) 872b815c7f3Sopenharmony_ci Cut_Fast_Calculation_of_the_LTP_parameters (S, 873b815c7f3Sopenharmony_ci d, dp, bc, Nc) ; 874b815c7f3Sopenharmony_ci else 875b815c7f3Sopenharmony_ci#endif /* LTP_CUT */ 876b815c7f3Sopenharmony_ci Fast_Calculation_of_the_LTP_parameters (d, dp, bc, Nc) ; 877b815c7f3Sopenharmony_ci else 878b815c7f3Sopenharmony_ci#endif /* FAST & USE_FLOAT_MUL */ 879b815c7f3Sopenharmony_ci#ifdef LTP_CUT 880b815c7f3Sopenharmony_ci if (S->ltp_cut) 881b815c7f3Sopenharmony_ci Cut_Calculation_of_the_LTP_parameters (S, d, dp, bc, Nc) ; 882b815c7f3Sopenharmony_ci else 883b815c7f3Sopenharmony_ci#endif 884b815c7f3Sopenharmony_ci Calculation_of_the_LTP_parameters (d, dp, bc, Nc) ; 885b815c7f3Sopenharmony_ci 886b815c7f3Sopenharmony_ci Long_term_analysis_filtering (*bc, *Nc, dp, d, dpp, e) ; 887b815c7f3Sopenharmony_ci} 888b815c7f3Sopenharmony_ci 889b815c7f3Sopenharmony_ci/* 4.3.2 */ 890b815c7f3Sopenharmony_civoid Gsm_Long_Term_Synthesis_Filtering ( 891b815c7f3Sopenharmony_ci struct gsm_state * S, 892b815c7f3Sopenharmony_ci 893b815c7f3Sopenharmony_ci int16_t Ncr, 894b815c7f3Sopenharmony_ci int16_t bcr, 895b815c7f3Sopenharmony_ci register int16_t * erp, /* [0..39] IN */ 896b815c7f3Sopenharmony_ci register int16_t * drp /* [-120..-1] IN, [-120..40] OUT */) 897b815c7f3Sopenharmony_ci/* 898b815c7f3Sopenharmony_ci * This procedure uses the bcr and Ncr parameter to realize the 899b815c7f3Sopenharmony_ci * long term synthesis filtering. The decoding of bcr needs 900b815c7f3Sopenharmony_ci * table 4.3b. 901b815c7f3Sopenharmony_ci */ 902b815c7f3Sopenharmony_ci{ 903b815c7f3Sopenharmony_ci register int k ; 904b815c7f3Sopenharmony_ci int16_t brp, drpp, Nr ; 905b815c7f3Sopenharmony_ci 906b815c7f3Sopenharmony_ci /* Check the limits of Nr. 907b815c7f3Sopenharmony_ci */ 908b815c7f3Sopenharmony_ci Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr ; 909b815c7f3Sopenharmony_ci S->nrp = Nr ; 910b815c7f3Sopenharmony_ci assert (Nr >= 40 && Nr <= 120) ; 911b815c7f3Sopenharmony_ci 912b815c7f3Sopenharmony_ci /* Decoding of the LTP gain bcr 913b815c7f3Sopenharmony_ci */ 914b815c7f3Sopenharmony_ci brp = gsm_QLB [bcr] ; 915b815c7f3Sopenharmony_ci 916b815c7f3Sopenharmony_ci /* Computation of the reconstructed short term residual 917b815c7f3Sopenharmony_ci * signal drp [0..39] 918b815c7f3Sopenharmony_ci */ 919b815c7f3Sopenharmony_ci assert (brp != MIN_WORD) ; 920b815c7f3Sopenharmony_ci 921b815c7f3Sopenharmony_ci for (k = 0 ; k <= 39 ; k++) 922b815c7f3Sopenharmony_ci { drpp = GSM_MULT_R (brp, drp [k - Nr]) ; 923b815c7f3Sopenharmony_ci drp [k] = GSM_ADD (erp [k], drpp) ; 924b815c7f3Sopenharmony_ci } 925b815c7f3Sopenharmony_ci 926b815c7f3Sopenharmony_ci /* 927b815c7f3Sopenharmony_ci * Update of the reconstructed short term residual signal 928b815c7f3Sopenharmony_ci * drp [-1..-120] 929b815c7f3Sopenharmony_ci */ 930b815c7f3Sopenharmony_ci 931b815c7f3Sopenharmony_ci for (k = 0 ; k <= 119 ; k++) drp [-120 + k] = drp [-80 + k] ; 932b815c7f3Sopenharmony_ci} 933