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