15e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 25e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische 35e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * Universitaet Berlin. See the accompanying file "COPYRIGHT" for 45e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. 55e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 65e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 75e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */ 85e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 95e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#include <stdio.h> 105e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#include <assert.h> 115e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 125e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#include "private.h" 135e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 145e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#include "gsm.h" 155e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#include "proto.h" 165e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 175e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#undef P 185e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 195e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 205e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION 215e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 225e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 235e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 4.2.4 */ 245e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 255e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 265e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yehstatic void Autocorrelation P2((s, L_ACF), 275e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word * s, /* [0..159] IN/OUT */ 285e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh longword * L_ACF) /* [0..8] OUT */ 295e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 305e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * The goal is to compute the array L_ACF[k]. The signal s[i] must 315e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * be scaled in order to avoid an overflow situation. 325e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 335e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh{ 345e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register int k, i; 355e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 365e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word temp, smax, scalauto; 375e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 385e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#ifdef USE_FLOAT_MUL 395e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh float float_s[160]; 405e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#endif 415e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 425e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Dynamic scaling of the array s[0..159] 435e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 445e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 455e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Search for the maximum. 465e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 475e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh smax = 0; 485e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (k = 0; k <= 159; k++) { 495e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_ABS( s[k] ); 505e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (temp > smax) smax = temp; 515e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 525e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 535e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Computation of the scaling factor. 545e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 555e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (smax == 0) scalauto = 0; 565e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh else { 575e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert(smax > 0); 585e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ 595e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 605e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 615e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Scaling of the array s[0...159] 625e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 635e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 645e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (scalauto > 0) { 655e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 665e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# ifdef USE_FLOAT_MUL 675e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# define SCALE(n) \ 685e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh case n: for (k = 0; k <= 159; k++) \ 695e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh float_s[k] = (float) \ 705e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ 715e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh break; 725e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# else 735e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# define SCALE(n) \ 745e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh case n: for (k = 0; k <= 159; k++) \ 755e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ 765e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh break; 775e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# endif /* USE_FLOAT_MUL */ 785e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 795e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh switch (scalauto) { 805e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh SCALE(1) 815e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh SCALE(2) 825e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh SCALE(3) 835e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh SCALE(4) 845e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 855e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# undef SCALE 865e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 875e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# ifdef USE_FLOAT_MUL 885e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; 895e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# endif 905e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 915e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Compute the L_ACF[..]. 925e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 935e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh { 945e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# ifdef USE_FLOAT_MUL 955e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register float * sp = float_s; 965e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register float sl = *sp; 975e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 985e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); 995e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# else 1005e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word * sp = s; 1015e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word sl = *sp; 1025e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1035e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); 1045e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# endif 1055e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1065e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# define NEXTI sl = *++sp 1075e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1085e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1095e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (k = 9; k--; L_ACF[k] = 0) ; 1105e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1115e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP (0); 1125e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1135e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); 1145e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1155e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); STEP(2); 1165e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1175e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); STEP(2); STEP(3); 1185e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1195e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); 1205e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1215e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); 1225e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1235e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); 1245e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1255e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); 1265e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1275e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 8; i <= 159; i++) { 1285e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1295e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh NEXTI; 1305e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1315e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(0); 1325e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(1); STEP(2); STEP(3); STEP(4); 1335e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP(5); STEP(6); STEP(7); STEP(8); 1345e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 1355e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1365e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (k = 9; k--; L_ACF[k] <<= 1) ; 1375e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1385e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 1395e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Rescaling of the array s[0..159] 1405e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 1415e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (scalauto > 0) { 1425e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert(scalauto <= 4); 1435e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (k = 160; k--; *s++ <<= scalauto) ; 1445e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 1455e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh} 1465e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1475e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#if defined(USE_FLOAT_MUL) && defined(FAST) 1485e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1495e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yehstatic void Fast_Autocorrelation P2((s, L_ACF), 1505e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word * s, /* [0..159] IN/OUT */ 1515e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh longword * L_ACF) /* [0..8] OUT */ 1525e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh{ 1535e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register int k, i; 1545e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh float f_L_ACF[9]; 1555e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh float scale; 1565e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1575e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh float s_f[160]; 1585e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register float *sf = s_f; 1595e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1605e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 0; i < 160; ++i) sf[i] = s[i]; 1615e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (k = 0; k <= 8; k++) { 1625e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register float L_temp2 = 0; 1635e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register float *sfl = sf - k; 1645e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; 1655e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh f_L_ACF[k] = L_temp2; 1665e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 1675e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh scale = MAX_LONGWORD / f_L_ACF[0]; 1685e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1695e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (k = 0; k <= 8; k++) { 1705e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh L_ACF[k] = f_L_ACF[k] * scale; 1715e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 1725e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh} 1735e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ 1745e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1755e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 4.2.5 */ 1765e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1775e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yehstatic void Reflection_coefficients P2( (L_ACF, r), 1785e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh longword * L_ACF, /* 0...8 IN */ 1795e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register word * r /* 0...7 OUT */ 1805e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh) 1815e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh{ 1825e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register int i, m, n; 1835e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register word temp; 1845e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register longword ltmp; 1855e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word ACF[9]; /* 0..8 */ 1865e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word P[ 9]; /* 0..8 */ 1875e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word K[ 9]; /* 2..8 */ 1885e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1895e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Schur recursion with 16 bits arithmetic. 1905e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 1915e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1925e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (L_ACF[0] == 0) { 1935e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 8; i--; *r++ = 0) ; 1945e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh return; 1955e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 1965e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 1975e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert( L_ACF[0] != 0 ); 1985e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = gsm_norm( L_ACF[0] ); 1995e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2005e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert(temp >= 0 && temp < 32); 2015e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2025e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* ? overflow ? */ 2035e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); 2045e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2055e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Initialize array P[..] and K[..] for the recursion. 2065e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 2075e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2085e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; 2095e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; 2105e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2115e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Compute reflection coefficients 2125e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 2135e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (n = 1; n <= 8; n++, r++) { 2145e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2155e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = P[1]; 2165e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_ABS(temp); 2175e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (P[0] < temp) { 2185e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = n; i <= 8; i++) *r++ = 0; 2195e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh return; 2205e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 2215e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2225e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh *r = gsm_div( temp, P[0] ); 2235e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2245e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert(*r >= 0); 2255e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ 2265e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert (*r != MIN_WORD); 2275e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (n == 8) return; 2285e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2295e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Schur recursion 2305e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 2315e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_MULT_R( P[1], *r ); 2325e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh P[0] = GSM_ADD( P[0], temp ); 2335e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2345e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (m = 1; m <= 8 - n; m++) { 2355e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_MULT_R( K[ m ], *r ); 2365e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh P[m] = GSM_ADD( P[ m+1 ], temp ); 2375e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2385e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_MULT_R( P[ m+1 ], *r ); 2395e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh K[m] = GSM_ADD( K[ m ], temp ); 2405e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 2415e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 2425e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh} 2435e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2445e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 4.2.6 */ 2455e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2465e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yehstatic void Transformation_to_Log_Area_Ratios P1((r), 2475e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register word * r /* 0..7 IN/OUT */ 2485e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh) 2495e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 2505e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * The following scaling for r[..] and LAR[..] has been used: 2515e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * 2525e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. 2535e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * LAR[..] = integer( real_LAR[..] * 16384 ); 2545e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * with -1.625 <= real_LAR <= 1.625 2555e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 2565e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh{ 2575e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register word temp; 2585e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register int i; 2595e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2605e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2615e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* Computation of the LAR[0..7] from the r[0..7] 2625e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 2635e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh for (i = 1; i <= 8; i++, r++) { 2645e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2655e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = *r; 2665e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_ABS(temp); 2675e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert(temp >= 0); 2685e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2695e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (temp < 22118) { 2705e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp >>= 1; 2715e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } else if (temp < 31130) { 2725e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert( temp >= 11059 ); 2735e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp -= 11059; 2745e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } else { 2755e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert( temp >= 26112 ); 2765e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp -= 26112; 2775e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp <<= 2; 2785e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 2795e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2805e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh *r = *r < 0 ? -temp : temp; 2815e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh assert( *r != MIN_WORD ); 2825e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh } 2835e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh} 2845e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2855e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh/* 4.2.7 */ 2865e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2875e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yehstatic void Quantization_and_coding P1((LAR), 2885e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register word * LAR /* [0..7] IN/OUT */ 2895e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh) 2905e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh{ 2915e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh register word temp; 2925e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh longword ltmp; 2935e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2945e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 2955e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh /* This procedure needs four tables; the following equations 2965e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * give the optimum scaling for the constants: 2975e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * 2985e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * A[0..7] = integer( real_A[0..7] * 1024 ) 2995e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * B[0..7] = integer( real_B[0..7] * 512 ) 3005e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * MAC[0..7] = maximum of the LARc[0..7] 3015e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh * MIC[0..7] = minimum of the LARc[0..7] 3025e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh */ 3035e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 3045e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# undef STEP 3055e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# define STEP( A, B, MAC, MIC ) \ 3065e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_MULT( A, *LAR ); \ 3075e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_ADD( temp, B ); \ 3085e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = GSM_ADD( temp, 256 ); \ 3095e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh temp = SASR( temp, 9 ); \ 3105e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh *LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \ 3115e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh LAR++; 3125e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 3135e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 20480, 0, 31, -32 ); 3145e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 20480, 0, 31, -32 ); 3155e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 20480, 2048, 15, -16 ); 3165e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 20480, -2560, 15, -16 ); 3175e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 3185e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 13964, 94, 7, -8 ); 3195e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 15360, -1792, 7, -8 ); 3205e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 8534, -341, 3, -4 ); 3215e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh STEP( 9036, -1144, 3, -4 ); 3225e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 3235e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh# undef STEP 3245e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh} 3255e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 3265e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yehvoid Gsm_LPC_Analysis P3((S, s,LARc), 3275e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh struct gsm_state *S, 3285e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word * s, /* 0..159 signals IN/OUT */ 3295e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh word * LARc) /* 0..7 LARc's OUT */ 3305e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh{ 3315e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh longword L_ACF[9]; 3325e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh 3335e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#if defined(USE_FLOAT_MUL) && defined(FAST) 3345e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh if (S->fast) Fast_Autocorrelation (s, L_ACF ); 3355e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh else 3365e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh#endif 3375e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh Autocorrelation (s, L_ACF ); 3385e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh Reflection_coefficients (L_ACF, LARc ); 3395e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh Transformation_to_Log_Area_Ratios (LARc); 3405e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh Quantization_and_coding (LARc); 3415e4516958690b9a1b2c98f88eeecba3edd2dbda4Chia-chi Yeh} 342