Esempio n. 1
0
INLINE void Coefficients_13_26(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp)
{
	int i;

	for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
		*LARp = SASR( *LARpp_j_1, 1) + SASR( *LARpp_j, 1 );
}
Esempio n. 2
0
INLINE void Coefficients_27_39(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp)
{
	int i;

	for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
    {
		*LARp = (gsmword)(SASR( *LARpp_j_1, 2 ) + SASR( *LARpp_j, 2 ));
		*LARp += (gsmword)SASR( *LARpp_j, 1 );
	}
}
Esempio n. 3
0
static void APCM_quantization_xmaxc_to_exp_mant (
	word		xmaxc,		/* IN 	*/
	word		* exp_out,	/* OUT	*/
	word		* mant_out )	/* OUT  */
{
	word	exp, mant;

	/* Compute exponent and mantissa of the decoded version of xmaxc
	 */

	exp = 0;
	if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
	mant = xmaxc - (exp << 3);

	if (mant == 0) {
		exp  = -4;
		mant = 7;
	}
	else {
		while (mant <= 7) {
			mant = mant << 1 | 1;
			exp--;
		}
		mant -= 8;
	}

	assert( exp  >= -4 && exp <= 6 );
	assert( mant >= 0 && mant <= 7 );

	*exp_out  = exp;
	*mant_out = mant;
}
Esempio n. 4
0
static void APCM_quantization_xmaxc_to_exp_mant(gsmword xmaxc, gsmword *exp_out,
                                                gsmword *mant_out)
{
	gsmword	exp, mant;

	exp = 0;
	if(xmaxc > 15)
        exp = (gsmword)(SASR(xmaxc, 3) - 1);
	mant = (gsmword)(xmaxc - SASL( exp, 3 ));

	if(mant == 0)
    {
		exp  = -4;
		mant = 7;
	}
	else
    {
		while(mant <= 7)
        {
			mant = (gsmword)(SASL(mant, 1) | 1);
			exp--;
		}
		mant -= 8;
	}

	*exp_out  = exp;
	*mant_out = mant;
}
Esempio n. 5
0
static void LARp_to_rp(gsmword * LARp)
{
	int 		i;
	gsmword	temp;

	for (i = 1; i <= 8; i++, LARp++)
    {

		if (*LARp < 0)
        {
			temp = (gsmword)GSM_ABS( *LARp );
			*LARp = (gsmword)(- ((temp < 11059) ? SASL( temp, 1 )
				: ((temp < 20070) ? temp + 11059
				:  ( SASR( temp, 2 ) + 26112 ))));
		}
        else
        {
			temp  = *LARp;
			*LARp =    (gsmword)((temp < 11059) ? SASL( temp, 1 )
				: ((temp < 20070) ? temp + 11059
				:  ( SASR( temp, 2 ) + 26112 )));
		}
	}
}
Esempio n. 6
0
static void APCM_inverse_quantization(gsmword *xMc, gsmword mant, gsmword exp, gsmword *xMp)
{
	int	i;
	gsmword	temp, temp1, temp2, temp3;
	longword	ltmp;

	temp1 = gsm_FACd[ mant ];	/* see 4.2-15 for mant */
	temp2 = (gsmword)GSM_SUB( 6, exp );	/* see 4.2-15 for exp  */
	temp3 = (gsmword)SASL( 1, GSM_SUB( temp2, 1 ));

	for(i = 13; i--;)
    {

		temp = (gsmword)(SASL(*xMc++, 1) - 7);	        /* restore sign   */

		temp = (gsmword)SASL(temp, 12);				/* 16 bit signed  */
		temp = (gsmword)GSM_MULT_R( temp1, temp );
		temp = (gsmword)GSM_ADD( temp, temp3 );
		*xMp++ = (gsmword)SASR( temp, temp2 );
	}
}
Esempio n. 7
0
static void Cut_Calculation_of_the_LTP_parameters (

	struct gsm_state * st,

	register int16_t	* d,		/* [0..39]	IN	*/
	register int16_t	* dp,		/* [-120..-1]	IN	*/
	int16_t		* bc_out,	/* 		OUT	*/
	int16_t		* Nc_out	/* 		OUT	*/)
{
	register int	k, lambda ;
	int16_t		Nc, bc ;
	int16_t		wt [40] ;

	int32_t	L_result ;
	int32_t	L_max, L_power ;
	int16_t		R, S, dmax, scal, best_k ;
	int16_t		ltp_cut ;

	register int16_t	temp, wt_k ;

	/*  Search of the optimum scaling of d [0..39]. */
	dmax = 0 ;
	for (k = 0 ; k <= 39 ; k++)
	{	temp = d [k] ;
		temp = GSM_ABS (temp) ;
		if (temp > dmax)
		{	dmax = temp ;
			best_k = k ;
			}
		}
	temp = 0 ;
	if (dmax == 0)
		scal = 0 ;
	else
	{	assert (dmax > 0) ;
		temp = gsm_norm ((int32_t) dmax << 16) ;
		}
	if (temp > 6) scal = 0 ;
	else scal = 6 - temp ;
	assert (scal >= 0) ;

	/* Search for the maximum cross-correlation and coding of the LTP lag
	 */
	L_max = 0 ;
	Nc = 40 ;	/* index for the maximum cross-correlation */
	wt_k = SASR_W (d [best_k], scal) ;

	for (lambda = 40 ; lambda <= 120 ; lambda++)
	{	L_result = (int32_t) wt_k * dp [best_k - lambda] ;
		if (L_result > L_max)
		{	Nc = lambda ;
			L_max = L_result ;
			}
		}
	*Nc_out = Nc ;
	L_max <<= 1 ;

	/*  Rescaling of L_max
	 */
	assert (scal <= 100 && scal >= -100) ;
	L_max = L_max >> (6 - scal) ;	/* sub (6, scal) */

	assert (Nc <= 120 && Nc >= 40) ;

	/*   Compute the power of the reconstructed short term residual
	 *   signal dp [..]
	 */
	L_power = 0 ;
	for (k = 0 ; k <= 39 ; k++)
	{	register int32_t L_temp ;

		L_temp = SASR_W (dp [k - Nc], 3) ;
		L_power += L_temp * L_temp ;
		}
	L_power <<= 1 ;	/* from L_MULT */

	/*  Normalization of L_max and L_power */

	if (L_max <= 0)
	{	*bc_out = 0 ;
		return ;
		}
	if (L_max >= L_power)
	{	*bc_out = 3 ;
		return ;
		}

	temp = gsm_norm (L_power) ;

	R = SASR (L_max << temp, 16) ;
	S = SASR (L_power << temp, 16) ;

	/*  Coding of the LTP gain
	 */

	/*  Table 4.3a must be used to obtain the level DLB [i] for the
	 *  quantization of the LTP gain b to get the coded version bc.
	 */
	for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ;
	*bc_out = bc ;
}
Esempio n. 8
0
static void Cut_Calculation_of_the_LTP_parameters (
	struct gsm_state * st,		/*              IN 	*/
	register int16_t	* d,		/* [0..39]	IN	*/
	register int16_t	* dp,		/* [-120..-1]	IN	*/
	int16_t		* bc_out,	/* 		OUT	*/
	int16_t		* Nc_out	/* 		OUT	*/)
{
	register int	k, lambda ;
	int16_t		Nc, bc ;
	int16_t		ltp_cut ;

	float		wt_float [40] ;
	float		dp_float_base [120], * dp_float = dp_float_base + 120 ;

	int32_t	L_max, L_power ;
	int16_t		R, S, dmax, scal ;
	register int16_t	temp ;

	/*  Search of the optimum scaling of d [0..39].
	 */
	dmax = 0 ;

	for (k = 0 ; k <= 39 ; k++)
	{	temp = d [k] ;
		temp = GSM_ABS (temp) ;
		if (temp > dmax) dmax = temp ;
		}

	temp = 0 ;
	if (dmax == 0) scal = 0 ;
	else
	{	assert (dmax > 0) ;
		temp = gsm_norm ((int32_t) dmax << 16) ;
		}

	if (temp > 6) scal = 0 ;
	else scal = 6 - temp ;

	assert (scal >= 0) ;
	ltp_cut = (int32_t) SASR_W (dmax, scal) * st->ltp_cut / 100 ;

	/*  Initialization of a working array wt */

	for (k = 0 ; k < 40 ; k++)
	{	register int16_t w = SASR_W (d [k], scal) ;
		if (w < 0 ? w > -ltp_cut : w < ltp_cut)
			wt_float [k] = 0.0 ;
		else
			wt_float [k] = w ;
		}
	for (k = -120 ; k < 0 ; k++) dp_float [k] = dp [k] ;

	/* Search for the maximum cross-correlation and coding of the LTP lag
	 */
	L_max = 0 ;
	Nc = 40 ;	/* index for the maximum cross-correlation */

	for (lambda = 40 ; lambda <= 120 ; lambda += 9)
	{	/*  Calculate L_result for l = lambda .. lambda + 9. */
		register float *lp = dp_float - lambda ;

		register float W ;
		register float a = lp [-8], b = lp [-7], c = lp [-6],
						d = lp [-5], e = lp [-4], f = lp [-3],
						g = lp [-2], h = lp [-1] ;
		register float E ;
		register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
						S5 = 0, S6 = 0, S7 = 0, S8 = 0 ;

#		undef STEP
#		define	STEP(K, a, b, c, d, e, f, g, h) \
			if ((W = wt_float [K]) != 0.0) {	\
			E = W * a ; S8 += E ;		\
			E = W * b ; S7 += E ;		\
			E = W * c ; S6 += E ;		\
			E = W * d ; S5 += E ;		\
			E = W * e ; S4 += E ;		\
			E = W * f ; S3 += E ;		\
			E = W * g ; S2 += E ;		\
			E = W * h ; S1 += E ;		\
			a = lp [K] ;				\
			E = W * a ; S0 += E ; } else (a = lp [K])

#		define	STEP_A(K)	STEP (K, a, b, c, d, e, f, g, h)
#		define	STEP_B(K)	STEP (K, b, c, d, e, f, g, h, a)
#		define	STEP_C(K)	STEP (K, c, d, e, f, g, h, a, b)
#		define	STEP_D(K)	STEP (K, d, e, f, g, h, a, b, c)
#		define	STEP_E(K)	STEP (K, e, f, g, h, a, b, c, d)
#		define	STEP_F(K)	STEP (K, f, g, h, a, b, c, d, e)
#		define	STEP_G(K)	STEP (K, g, h, a, b, c, d, e, f)
#		define	STEP_H(K)	STEP (K, h, a, b, c, d, e, f, g)

		STEP_A (0) ; STEP_B (1) ; STEP_C (2) ; STEP_D (3) ;
		STEP_E (4) ; STEP_F (5) ; STEP_G (6) ; STEP_H (7) ;

		STEP_A (8) ; STEP_B (9) ; STEP_C (10) ; STEP_D (11) ;
		STEP_E (12) ; STEP_F (13) ; STEP_G (14) ; STEP_H (15) ;

		STEP_A (16) ; STEP_B (17) ; STEP_C (18) ; STEP_D (19) ;
		STEP_E (20) ; STEP_F (21) ; STEP_G (22) ; STEP_H (23) ;

		STEP_A (24) ; STEP_B (25) ; STEP_C (26) ; STEP_D (27) ;
		STEP_E (28) ; STEP_F (29) ; STEP_G (30) ; STEP_H (31) ;

		STEP_A (32) ; STEP_B (33) ; STEP_C (34) ; STEP_D (35) ;
		STEP_E (36) ; STEP_F (37) ; STEP_G (38) ; STEP_H (39) ;

#		undef STEP_A
#		undef STEP_B
#		undef STEP_C
#		undef STEP_D
#		undef STEP_E
#		undef STEP_F
#		undef STEP_G
#		undef STEP_H

		if (S0 > L_max) { L_max = S0 ; Nc = lambda ; }
		if (S1 > L_max) { L_max = S1 ; Nc = lambda + 1 ; }
		if (S2 > L_max) { L_max = S2 ; Nc = lambda + 2 ; }
		if (S3 > L_max) { L_max = S3 ; Nc = lambda + 3 ; }
		if (S4 > L_max) { L_max = S4 ; Nc = lambda + 4 ; }
		if (S5 > L_max) { L_max = S5 ; Nc = lambda + 5 ; }
		if (S6 > L_max) { L_max = S6 ; Nc = lambda + 6 ; }
		if (S7 > L_max) { L_max = S7 ; Nc = lambda + 7 ; }
		if (S8 > L_max) { L_max = S8 ; Nc = lambda + 8 ; }

	}
	*Nc_out = Nc ;

	L_max <<= 1 ;

	/*  Rescaling of L_max
	 */
	assert (scal <= 100 && scal >= -100) ;
	L_max = L_max >> (6 - scal) ;	/* sub (6, scal) */

	assert (Nc <= 120 && Nc >= 40) ;

	/*   Compute the power of the reconstructed short term residual
	 *   signal dp [..]
	 */
	L_power = 0 ;
	for (k = 0 ; k <= 39 ; k++)
	{	register int32_t L_temp ;

		L_temp = SASR_W (dp [k - Nc], 3) ;
		L_power += L_temp * L_temp ;
		}
	L_power <<= 1 ;	/* from L_MULT */

	/*  Normalization of L_max and L_power
	 */

	if (L_max <= 0)
	{	*bc_out = 0 ;
		return ;
		}
	if (L_max >= L_power)
	{	*bc_out = 3 ;
		return ;
		}

	temp = gsm_norm (L_power) ;

	R = SASR (L_max << temp, 16) ;
	S = SASR (L_power << temp, 16) ;

	/*  Coding of the LTP gain
	 */

	/*  Table 4.3a must be used to obtain the level DLB [i] for the
	 *  quantization of the LTP gain b to get the coded version bc.
	 */
	for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ;
	*bc_out = bc ;
}
Esempio n. 9
0
static void APCM_quantization (
	word		* xM,		/* [0..12]		IN	*/

	word		* xMc,		/* [0..12]		OUT	*/
	word		* mant_out,	/* 			OUT	*/
	word		* exp_out,	/*			OUT	*/
	word		* xmaxc_out	/*			OUT	*/
)
{
	int	i, itest;

	word	xmax, xmaxc, temp, temp1, temp2;
	word	exp, mant;


	/*  Find the maximum absolute value xmax of xM[0..12].
	 */

	xmax = 0;
	for (i = 0; i <= 12; i++) {
		temp = xM[i];
		temp = GSM_ABS(temp);
		if (temp > xmax) xmax = temp;
	}

	/*  Qantizing and coding of xmax to get xmaxc.
	 */

	exp   = 0;
	temp  = SASR( xmax, 9 );
	itest = 0;

	for (i = 0; i <= 5; i++) {

		itest |= (temp <= 0);
		temp = SASR( temp, 1 );

		assert(exp <= 5);
		if (itest == 0) exp++;		/* exp = add (exp, 1) */
	}

	assert(exp <= 6 && exp >= 0);
	temp = exp + 5;

	assert(temp <= 11 && temp >= 0);
	xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );

	/*   Quantizing and coding of the xM[0..12] RPE sequence
	 *   to get the xMc[0..12]
	 */

	APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );

	/*  This computation uses the fact that the decoded version of xmaxc
	 *  can be calculated by using the exponent and the mantissa part of
	 *  xmaxc (logarithmic table).
	 *  So, this method avoids any division and uses only a scaling
	 *  of the RPE samples by a function of the exponent.  A direct 
	 *  multiplication by the inverse of the mantissa (NRFAC[0..7]
	 *  found in table 4.5) gives the 3 bit coded version xMc[0..12]
	 *  of the RPE samples.
	 */


	/* Direct computation of xMc[0..12] using table 4.5
	 */

	assert( exp <= 4096 && exp >= -4096);
	assert( mant >= 0 && mant <= 7 ); 

	temp1 = 6 - exp;		/* normalization by the exponent */
	temp2 = gsm_NRFAC[ mant ];  	/* inverse mantissa 		 */

	for (i = 0; i <= 12; i++) {

		assert(temp1 >= 0 && temp1 < 16);

		temp = xM[i] << temp1;
		temp = GSM_MULT( temp, temp2 );
		temp = SASR(temp, 12);
		xMc[i] = temp + 4;		/* see note below */
	}

	/*  NOTE: This equation is used to make all the xMc[i] positive.
	 */

	*mant_out  = mant;
	*exp_out   = exp;
	*xmaxc_out = xmaxc;
}
Esempio n. 10
0
static void Weighting_filter (
	register word	* e,		/* signal [-5..0.39.44]	IN  */
	word		* x		/* signal [0..39]	OUT */
)
/*
 *  The coefficients of the weighting filter are stored in a table
 *  (see table 4.4).  The following scaling is used:
 *
 *	H[0..10] = integer( real_H[ 0..10] * 8192 ); 
 */
{
	/* word			wt[ 50 ]; */

	register longword	L_result;
	register int		k /* , i */ ;

	/*  Initialization of a temporary working array wt[0...49]
	 */

	/* for (k =  0; k <=  4; k++) wt[k] = 0;
	 * for (k =  5; k <= 44; k++) wt[k] = *e++;
	 * for (k = 45; k <= 49; k++) wt[k] = 0;
	 *
	 *  (e[-5..-1] and e[40..44] are allocated by the caller,
	 *  are initially zero and are not written anywhere.)
	 */
	e -= 5;

	/*  Compute the signal x[0..39]
	 */ 
	for (k = 0; k <= 39; k++) {

		L_result = 8192 >> 1;

		/* for (i = 0; i <= 10; i++) {
		 *	L_temp   = GSM_L_MULT( wt[k+i], gsm_H[i] );
		 *	L_result = GSM_L_ADD( L_result, L_temp );
		 * }
		 */

#undef	STEP
#define	STEP( i, H )	(e[ k + i ] * (longword)H)

		/*  Every one of these multiplications is done twice --
		 *  but I don't see an elegant way to optimize this. 
		 *  Do you?
		 */

#ifdef	STUPID_COMPILER
		L_result += STEP(	0, 	-134 ) ;
		L_result += STEP(	1, 	-374 )  ;
	               /* + STEP(	2, 	0    )  */
		L_result += STEP(	3, 	2054 ) ;
		L_result += STEP(	4, 	5741 ) ;
		L_result += STEP(	5, 	8192 ) ;
		L_result += STEP(	6, 	5741 ) ;
		L_result += STEP(	7, 	2054 ) ;
	 	       /* + STEP(	8, 	0    )  */
		L_result += STEP(	9, 	-374 ) ;
		L_result += STEP(	10, 	-134 ) ;
#else
		L_result +=
		  STEP(	0, 	-134 ) 
		+ STEP(	1, 	-374 ) 
	     /* + STEP(	2, 	0    )  */
		+ STEP(	3, 	2054 ) 
		+ STEP(	4, 	5741 ) 
		+ STEP(	5, 	8192 ) 
		+ STEP(	6, 	5741 ) 
		+ STEP(	7, 	2054 ) 
	     /* + STEP(	8, 	0    )  */
		+ STEP(	9, 	-374 ) 
		+ STEP(10, 	-134 )
		;
#endif

		/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
		 * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
		 *
		 * x[k] = SASR( L_result, 16 );
		 */

		/* 2 adds vs. >>16 => 14, minus one shift to compensate for
		 * those we lost when replacing L_MULT by '*'.
		 */

		L_result = SASR( L_result, 13 );
		x[k] =  (  L_result < MIN_WORD ? MIN_WORD
			: (L_result > MAX_WORD ? MAX_WORD : L_result ));
	}
}
Esempio n. 11
0
void Gsm_Preprocess (
	struct gsm_state * S,
	word		 * s,
	word 		 * so )		/* [0..159] 	IN/OUT	*/
{

	word       z1 = S->z1;
	longword L_z2 = S->L_z2;
	word 	   mp = S->mp;

	word 	   	s1;
	longword      L_s2;

	longword      L_temp;

	word		msp, lsp;
	word		SO;

	longword	ltmp;		/* for   ADD */
	ulongword	utmp;		/* for L_ADD */

	register int		k = 160;

	while (k--) {

	/*  4.2.1   Downscaling of the input signal
	 */
		SO = SASR( *s, 3 ) << 2;
		s++;

		assert (SO >= -0x4000);	/* downscaled by     */
		assert (SO <=  0x3FFC);	/* previous routine. */


	/*  4.2.2   Offset compensation
	 * 
	 *  This part implements a high-pass filter and requires extended
	 *  arithmetic precision for the recursive part of this filter.
	 *  The input of this procedure is the array so[0...159] and the
	 *  output the array sof[ 0...159 ].
	 */
		/*   Compute the non-recursive part
		 */

		s1 = SO - z1;			/* s1 = gsm_sub( *so, z1 ); */
		z1 = SO;

		assert(s1 != MIN_WORD);

		/*   Compute the recursive part
		 */
		L_s2 = s1;
		L_s2 <<= 15;

		/*   Execution of a 31 bv 16 bits multiplication
		 */

		msp = SASR( L_z2, 15 );
		lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */

		L_s2  += GSM_MULT_R( lsp, 32735 );
		L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
		L_z2   = GSM_L_ADD( L_temp, L_s2 );

		/*    Compute sof[k] with rounding
		 */
		L_temp = GSM_L_ADD( L_z2, 16384 );

	/*   4.2.3  Preemphasis
	 */

		msp   = GSM_MULT_R( mp, -28180 );
		mp    = SASR( L_temp, 15 );
		*so++ = GSM_ADD( mp, msp );
	}

	S->z1   = z1;
	S->L_z2 = L_z2;
	S->mp   = mp;
}