1 /* 2 * rpe.c 3 * 4 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische 5 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for 6 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. 7 */ 8 9 10 #include <stdio.h> 11 #include <assert.h> 12 13 #include "private.h" 14 15 #include "gsm.h" 16 #include "proto.h" 17 18 /* 4.2.13 .. 4.2.17 RPE ENCODING SECTION 19 */ 20 21 /* 4.2.13 */ 22 23 static void Weighting_filter P2((e, x), 24 register word * e, /* signal [-5..0.39.44] IN */ 25 word * x /* signal [0..39] OUT */ 26 ) 27 /* 28 * The coefficients of the weighting filter are stored in a table 29 * (see table 4.4). The following scaling is used: 30 * 31 * H[0..10] = integer( real_H[ 0..10] * 8192 ); 32 */ 33 { 34 /* word wt[ 50 ]; */ 35 36 register longword L_result; 37 register int k /* , i */ ; 38 39 /* Initialization of a temporary working array wt[0...49] 40 */ 41 42 /* for (k = 0; k <= 4; k++) wt[k] = 0; 43 * for (k = 5; k <= 44; k++) wt[k] = *e++; 44 * for (k = 45; k <= 49; k++) wt[k] = 0; 45 * 46 * (e[-5..-1] and e[40..44] are allocated by the caller, 47 * are initially zero and are not written anywhere.) 48 */ 49 e -= 5; 50 51 /* Compute the signal x[0..39] 52 */ 53 for (k = 0; k <= 39; k++) { 54 55 L_result = 8192 >> 1; 56 57 /* for (i = 0; i <= 10; i++) { 58 * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); 59 * L_result = GSM_L_ADD( L_result, L_temp ); 60 * } 61 */ 62 63 #undef STEP 64 #define STEP( i, H ) (e[ k + i ] * (longword)H) 65 66 /* Every one of these multiplications is done twice -- 67 * but I don't see an elegant way to optimize this. 68 * Do you? 69 */ 70 71 #ifdef STUPID_COMPILER 72 L_result += STEP( 0, -134 ) ; 73 L_result += STEP( 1, -374 ) ; 74 /* + STEP( 2, 0 ) */ 75 L_result += STEP( 3, 2054 ) ; 76 L_result += STEP( 4, 5741 ) ; 77 L_result += STEP( 5, 8192 ) ; 78 L_result += STEP( 6, 5741 ) ; 79 L_result += STEP( 7, 2054 ) ; 80 /* + STEP( 8, 0 ) */ 81 L_result += STEP( 9, -374 ) ; 82 L_result += STEP( 10, -134 ) ; 83 #else 84 L_result += 85 STEP( 0, -134 ) 86 + STEP( 1, -374 ) 87 /* + STEP( 2, 0 ) */ 88 + STEP( 3, 2054 ) 89 + STEP( 4, 5741 ) 90 + STEP( 5, 8192 ) 91 + STEP( 6, 5741 ) 92 + STEP( 7, 2054 ) 93 /* + STEP( 8, 0 ) */ 94 + STEP( 9, -374 ) 95 + STEP(10, -134 ) 96 ; 97 #endif 98 99 /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) 100 * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) 101 * 102 * x[k] = SASR( L_result, 16 ); 103 */ 104 105 /* 2 adds vs. >>16 => 14, minus one shift to compensate for 106 * those we lost when replacing L_MULT by '*'. 107 */ 108 109 L_result = SASR( L_result, 13 ); 110 x[k] = (word) (( L_result < MIN_WORD ? MIN_WORD 111 : (L_result > MAX_WORD ? MAX_WORD : L_result ))); 112 } 113 } 114 115 /* 4.2.14 */ 116 117 static void RPE_grid_selection P3((x,xM,Mc_out), 118 word * x, /* [0..39] IN */ 119 word * xM, /* [0..12] OUT */ 120 word * Mc_out /* OUT */ 121 ) 122 /* 123 * The signal x[0..39] is used to select the RPE grid which is 124 * represented by Mc. 125 */ 126 { 127 /* register word temp1; */ 128 register int /* m, */ i; 129 register longword L_result, L_temp; 130 longword EM; /* xxx should be L_EM? */ 131 word Mc; 132 133 longword L_common_0_3; 134 135 EM = 0; 136 Mc = 0; 137 138 /* for (m = 0; m <= 3; m++) { 139 * L_result = 0; 140 * 141 * 142 * for (i = 0; i <= 12; i++) { 143 * 144 * temp1 = SASR( x[m + 3*i], 2 ); 145 * 146 * assert(temp1 != MIN_WORD); 147 * 148 * L_temp = GSM_L_MULT( temp1, temp1 ); 149 * L_result = GSM_L_ADD( L_temp, L_result ); 150 * } 151 * 152 * if (L_result > EM) { 153 * Mc = m; 154 * EM = L_result; 155 * } 156 * } 157 */ 158 159 #undef STEP 160 #define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ 161 L_result += L_temp * L_temp; 162 163 /* common part of 0 and 3 */ 164 165 L_result = 0; 166 STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); 167 STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); 168 STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); 169 L_common_0_3 = L_result; 170 171 /* i = 0 */ 172 173 STEP( 0, 0 ); 174 L_result <<= 1; /* implicit in L_MULT */ 175 EM = L_result; 176 177 /* i = 1 */ 178 179 L_result = 0; 180 STEP( 1, 0 ); 181 STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); 182 STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); 183 STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); 184 L_result <<= 1; 185 if (L_result > EM) { 186 Mc = 1; 187 EM = L_result; 188 } 189 190 /* i = 2 */ 191 192 L_result = 0; 193 STEP( 2, 0 ); 194 STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); 195 STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); 196 STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); 197 L_result <<= 1; 198 if (L_result > EM) { 199 Mc = 2; 200 EM = L_result; 201 } 202 203 /* i = 3 */ 204 205 L_result = L_common_0_3; 206 STEP( 3, 12 ); 207 L_result <<= 1; 208 if (L_result > EM) { 209 Mc = 3; 210 EM = L_result; 211 } 212 213 /**/ 214 215 /* Down-sampling by a factor 3 to get the selected xM[0..12] 216 * RPE sequence. 217 */ 218 for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; 219 *Mc_out = Mc; 220 } 221 222 /* 4.12.15 */ 223 224 static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), 225 word xmaxc, /* IN */ 226 word * exp_out, /* OUT */ 227 word * mant_out ) /* OUT */ 228 { 229 word exp, mant; 230 231 /* Compute exponent and mantissa of the decoded version of xmaxc 232 */ 233 234 exp = 0; 235 if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; 236 mant = xmaxc - (exp << 3); 237 238 if (mant == 0) { 239 exp = -4; 240 mant = 7; 241 } 242 else { 243 while (mant <= 7) { 244 mant = mant << 1 | 1; 245 exp--; 246 } 247 mant -= 8; 248 } 249 250 assert( exp >= -4 && exp <= 6 ); 251 assert( mant >= 0 && mant <= 7 ); 252 253 *exp_out = exp; 254 *mant_out = mant; 255 } 256 257 static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), 258 word * xM, /* [0..12] IN */ 259 260 word * xMc, /* [0..12] OUT */ 261 word * mant_out, /* OUT */ 262 word * exp_out, /* OUT */ 263 word * xmaxc_out /* OUT */ 264 ) 265 { 266 int i, itest; 267 268 word xmax, xmaxc, temp, temp1, temp2; 269 word exp, mant; 270 271 272 /* Find the maximum absolute value xmax of xM[0..12]. 273 */ 274 275 xmax = 0; 276 for (i = 0; i <= 12; i++) { 277 temp = xM[i]; 278 temp = GSM_ABS(temp); 279 if (temp > xmax) xmax = temp; 280 } 281 282 /* Qantizing and coding of xmax to get xmaxc. 283 */ 284 285 exp = 0; 286 temp = SASR( xmax, 9 ); 287 itest = 0; 288 289 for (i = 0; i <= 5; i++) { 290 291 itest |= (temp <= 0); 292 temp = SASR( temp, 1 ); 293 294 assert(exp <= 5); 295 if (itest == 0) exp++; /* exp = add (exp, 1) */ 296 } 297 298 assert(exp <= 6 && exp >= 0); 299 temp = exp + 5; 300 301 assert(temp <= 11 && temp >= 0); 302 xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); 303 304 /* Quantizing and coding of the xM[0..12] RPE sequence 305 * to get the xMc[0..12] 306 */ 307 308 APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); 309 310 /* This computation uses the fact that the decoded version of xmaxc 311 * can be calculated by using the exponent and the mantissa part of 312 * xmaxc (logarithmic table). 313 * So, this method avoids any division and uses only a scaling 314 * of the RPE samples by a function of the exponent. A direct 315 * multiplication by the inverse of the mantissa (NRFAC[0..7] 316 * found in table 4.5) gives the 3 bit coded version xMc[0..12] 317 * of the RPE samples. 318 */ 319 320 321 /* Direct computation of xMc[0..12] using table 4.5 322 */ 323 324 assert( exp <= 4096 && exp >= -4096); 325 assert( mant >= 0 && mant <= 7 ); 326 327 temp1 = 6 - exp; /* normalization by the exponent */ 328 temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ 329 330 for (i = 0; i <= 12; i++) { 331 332 assert(temp1 >= 0 && temp1 < 16); 333 334 temp = xM[i] << temp1; 335 temp = GSM_MULT( temp, temp2 ); 336 temp = SASR(temp, 12); 337 xMc[i] = temp + 4; /* see note below */ 338 } 339 340 /* NOTE: This equation is used to make all the xMc[i] positive. 341 */ 342 343 *mant_out = mant; 344 *exp_out = exp; 345 *xmaxc_out = xmaxc; 346 } 347 348 /* 4.2.16 */ 349 350 static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), 351 register word * xMc, /* [0..12] IN */ 352 word mant, 353 word exp, 354 register word * xMp) /* [0..12] OUT */ 355 /* 356 * This part is for decoding the RPE sequence of coded xMc[0..12] 357 * samples to obtain the xMp[0..12] array. Table 4.6 is used to get 358 * the mantissa of xmaxc (FAC[0..7]). 359 */ 360 { 361 int i; 362 word temp, temp1, temp2, temp3; 363 longword ltmp; 364 365 assert( mant >= 0 && mant <= 7 ); 366 367 temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ 368 temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ 369 temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); 370 371 for (i = 13; i--;) { 372 373 assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */ 374 375 /* temp = gsm_sub( *xMc++ << 1, 7 ); */ 376 temp = (*xMc++ << 1) - 7; /* restore sign */ 377 assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */ 378 379 temp <<= 12; /* 16 bit signed */ 380 temp = GSM_MULT_R( temp1, temp ); 381 temp = (word) GSM_ADD( temp, temp3 ); 382 *xMp++ = gsm_asr( temp, temp2 ); 383 } 384 } 385 386 /* 4.2.17 */ 387 388 static void RPE_grid_positioning P3((Mc,xMp,ep), 389 word Mc, /* grid position IN */ 390 register word * xMp, /* [0..12] IN */ 391 register word * ep /* [0..39] OUT */ 392 ) 393 /* 394 * This procedure computes the reconstructed long term residual signal 395 * ep[0..39] for the LTP analysis filter. The inputs are the Mc 396 * which is the grid position selection and the xMp[0..12] decoded 397 * RPE samples which are upsampled by a factor of 3 by inserting zero 398 * values. 399 */ 400 { 401 int i = 13; 402 403 assert(0 <= Mc && Mc <= 3); 404 405 switch (Mc) { 406 case 3: *ep++ = 0; 407 case 2: do { 408 *ep++ = 0; 409 case 1: *ep++ = 0; 410 case 0: *ep++ = *xMp++; 411 } while (--i); 412 } 413 while (++Mc < 4) *ep++ = 0; 414 415 /* 416 417 int i, k; 418 for (k = 0; k <= 39; k++) ep[k] = 0; 419 for (i = 0; i <= 12; i++) { 420 ep[ Mc + (3*i) ] = xMp[i]; 421 } 422 */ 423 } 424 425 /* 4.2.18 */ 426 427 /* This procedure adds the reconstructed long term residual signal 428 * ep[0..39] to the estimated signal dpp[0..39] from the long term 429 * analysis filter to compute the reconstructed short term residual 430 * signal dp[-40..-1]; also the reconstructed short term residual 431 * array dp[-120..-41] is updated. 432 */ 433 434 #if 0 /* Has been inlined in code.c */ 435 void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), 436 word * dpp, /* [0...39] IN */ 437 word * ep, /* [0...39] IN */ 438 word * dp) /* [-120...-1] IN/OUT */ 439 { 440 int k; 441 442 for (k = 0; k <= 79; k++) 443 dp[ -120 + k ] = dp[ -80 + k ]; 444 445 for (k = 0; k <= 39; k++) 446 dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); 447 } 448 #endif /* Has been inlined in code.c */ 449 450 void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), 451 452 struct gsm_state * S, 453 454 word * e, /* -5..-1][0..39][40..44 IN/OUT */ 455 word * xmaxc, /* OUT */ 456 word * Mc, /* OUT */ 457 word * xMc) /* [0..12] OUT */ 458 { 459 word x[40]; 460 word xM[13], xMp[13]; 461 word mant, exp; 462 463 Weighting_filter(e, x); 464 RPE_grid_selection(x, xM, Mc); 465 466 APCM_quantization( xM, xMc, &mant, &exp, xmaxc); 467 APCM_inverse_quantization( xMc, mant, exp, xMp); 468 469 RPE_grid_positioning( *Mc, xMp, e ); 470 471 } 472 473 void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), 474 struct gsm_state * S, 475 476 word xmaxcr, 477 word Mcr, 478 word * xMcr, /* [0..12], 3 bits IN */ 479 word * erp /* [0..39] OUT */ 480 ) 481 { 482 word exp, mant; 483 word xMp[ 13 ]; 484 485 APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); 486 APCM_inverse_quantization( xMcr, mant, exp, xMp ); 487 RPE_grid_positioning( Mcr, xMp, erp ); 488 489 } 490