⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sp_dec.c

📁 AMR-NB的解码程序,纯C, VC建立工程即可使用.标准测试序列通过测试,与编码配合使用.
💻 C
📖 第 1 页 / 共 5 页
字号:

	/* initialize states */
	memcpy( aState, a, M <<2 );

	/* backward Levinson recursion */
	for ( i = M - 1; i >= 0; i-- ) 
	{
		if ( labs( aState[i] ) >= 4096 ) 
		{
			 goto ExitRefl;
		}
		
		refl[i] = aState[i] << 3;
		temp = ( refl[i] * refl[i] ) << 1;
		acc = ( MAX_32 - temp );
		normShift=0;

		if (acc != 0)
		{
			 temp = acc;
			 while (!(temp & 0x40000000))
			 {
				normShift++;
				temp = temp << 1;
			 }
		}
		else
		{
			 normShift = 0;
		}
		scale = 15 - normShift;
		acc = ( acc << normShift );
		temp = ( acc + ( Word32 )0x00008000L );

		if ( temp > 0 ) 
		{
			 normProd = temp >> 16;
			 mult = 0x20000000L / normProd;
		}
		else
			 mult = 16384;

		for ( j = 0; j < i; j++ ) 
		{
			acc = aState[j] << 16;
			acc -= ( refl[i] * aState[i - j - 1] ) << 1;
			temp = ( acc + ( Word32 )0x00008000L ) >> 16;
			temp = ( mult * temp ) << 1;

			if ( scale > 0 ) 
			{
				if ( ( temp & ( ( Word32 )1 << ( scale - 1 ) ) ) != 0 ) 
				{
					temp = ( temp >> scale ) + 1;
				}
				else
					temp = ( temp >> scale );
			}
			else
				temp = ( temp >> scale );

			if ( labs( temp ) > 32767 ) 
			{
				goto ExitRefl;
			}
			bState[j] = temp;
		}
		
		memcpy( aState, bState, i <<2 );
	}
	return;
	ExitRefl:
	memset( refl, 0, M <<2 );
}


/************************************************************************************
 * Log2_norm
 *
 *
 * Parameters:
 *    x                 I: input value
 *    exp               I: exponent
 *    exponent          O: Integer part of Log2. (range: 0<=val<=30)
 *    fraction          O: Fractional part of Log2. (range: 0<=val<1)
 *
 * Function:
 *    Computes log2
 *
 *    Computes log2(L_x, exp),  where   L_x is positive and
 *    normalized, and exp is the normalisation exponent
 *    If L_x is negative or zero, the result is 0.
 *
 *    The function Log2(L_x) is approximated by a table and linear
 *    interpolation. The following steps are used to compute Log2(L_x)
 *
 *    exponent = 30-normExponent
 *    i = bit25-b31 of L_x;  32<=i<=63  (because of normalization).
 *    a = bit10-b24
 *    i -=32
 *    fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
 *
 * Returns:
 *    void
 *************************************************************************************/
static void Log2_norm( Word32 x, Word32 exp, Word32 *exponent, Word32 *
      fraction )
{
	Word32 y, i, a;


	if ( x <= 0 )
	{
		*exponent = 0;
		*fraction = 0;
		return;
	}

	/* Extract b25-b31 */
	i = x >> 25;
	i = i - 32;

	/* Extract b10-b24 of fraction */
	a = x >> 9;
	a = a & 0xFFFE;   /* 2a */

	/* fraction */
	y = ( log2_table[i] << 16 ) - a * ( log2_table[i] - log2_table[i + 1] );
	*fraction = y >> 16;
	*exponent = 30 - exp;
	return;
}


/************************************************************************************
 * Log2
 *
 *
 * Parameters:
 *    x                 I: input value
 *    exponent          O: Integer part of Log2. (range: 0<=val<=30)
 *    fraction          O: Fractional part of Log2. (range: 0<=val<1)
 *
 * Function:
 *    Computes log2(L_x)
 *    If x is negative or zero, the result is 0.
 *
 * Returns:
 *    void
 *************************************************************************************/
static void Log2( Word32 x, Word32 *exponent, Word32 *fraction )
{
	int tmp, exp=0;

	if (x != 0)
	{
		 tmp = x;
		 while (!((tmp & 0x80000000) ^ ((tmp & 0x40000000) << 1)))
		 {
			exp++;
			tmp = tmp << 1;
		 }
	}
	Log2_norm( x <<exp, exp, exponent, fraction );
}


/************************************************************************************
 * Pow2
 *
 *
 * Parameters:
 *    exponent          I: Integer part. (range: 0<=val<=30)
 *    fraction          O: Fractional part. (range: 0.0<=val<1.0)
 *
 * Function:
 *    pow(2.0, exponent.fraction)
 *
 *    The function Pow2(L_x) is approximated by a table and linear interpolation.
 *
 *    i = bit10-b15 of fraction, 0 <= i <= 31
 *    a = biT0-b9   of fraction
 *    x = table[i]<<16 - (table[i] - table[i+1]) * a * 2
 *    x = L_x >> (30-exponent) (with rounding)
 *
 * Returns:
 *    result (range: 0<=val<=0x7fffffff)
 **************************************************************************************/
static Word32 Pow2( Word32 exponent, Word32 fraction )
{
	Word32 i, a, tmp, x, exp;


	i = fraction >> 10;

	a = ( fraction << 5 ) & 0x7fff;

	x = pow2_table[i] << 16;

	tmp = pow2_table[i] - pow2_table[i + 1];

	x -= ( tmp * a ) << 1;

	if ( exponent >= -1 ) 
	{
		exp = ( 30 - exponent );

		if ( ( x & ( ( Word32 )1 << ( exp - 1 ) ) ) != 0 ) 
		{
			x = ( x >> exp ) + 1;
		}
		else
			x = x >> exp;
	}
	else
		x = 0;
	return( x );
}


/************************************************************************************
 * Build_CN_code
 *
 *
 * Parameters:
 *    seed              B: Old CN generator shift register state
 *    cod               O: Generated CN fixed codebook vector
 *
 * Function:
 *    Generate CN fixed codebook vector
 *
 * Returns:
 *    void
 ************************************************************************************/
static void Build_CN_code( Word32 *seed, Word32 cod[] )
{
	Word32 i, j, k;


	memset( cod, 0, L_SUBFR <<2 );

	for ( k = 0; k < 10; k++ ) 
	{
		i = pseudonoise( seed, 2 );   /* generate pulse position */
		i = ( i * 20 ) >> 1;
		i = ( i + k );
		j = pseudonoise( seed, 1 );   /* generate sign           */

		if ( j > 0 ) 
		{
			 cod[i] = 4096;
		}
		else 
		{
			 cod[i] = -4096;
		}
	}
	return;
}


/*************************************************************************************
 * Build_CN_param
 *
 *
 * Parameters:
 *    seed              B: Old CN generator shift register state
 *    nParam            I: number of params
 *    paramSizeTable    I: size of params
 *    parm              O: CN Generated params
 *
 * Function:
 *    Generate parameters for comfort noise generation
 *
 * Returns:
 *    void
 *************************************************************************************/
static void Build_CN_param( Word16 *seed, enum Mode mode, Word16 parm[] )
{
	Word32 i;
	const Word32 *p;


	*seed = ( Word16 )( ( *seed * 31821 ) + 13849L );
	p = &window_200_40[ * seed & 0x7F];

	switch ( mode ) 
	{
		case MR122:
			for ( i = 0; i < PRMNO_MR122; i++ ) 
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR122[i] ) );
			}
			
			break;

		case MR102:
			for ( i = 0; i < PRMNO_MR102; i++ ) 
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR102[i] ) );
			}
			break;

		case MR795:
			for ( i = 0; i < PRMNO_MR795; i++ ) 
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR795[i] ) );
			}
			break;

		case MR74:
			for ( i = 0; i < PRMNO_MR74; i++ ) 
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR74[i] ) );
			}
			break;

		case MR67:
			for ( i = 0; i < PRMNO_MR67; i++ )
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR67[i] ) );
			}
			break;

		case MR59:
			for ( i = 0; i < PRMNO_MR59; i++ ) 
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR59[i] ) );
			}
			break;

		case MR515:
			for ( i = 0; i < PRMNO_MR515; i++ )
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR515[i] ) );
			}
			break;

		case MR475:
			for ( i = 0; i < PRMNO_MR475; i++ ) 
			{
				parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR475[i] ) );
			}
			break;
	}
}


/************************************************************************************
 * Syn_filt
 *
 *
 * Parameters:
 *    a                 I: prediction coefficients [M+1]
 *    x                 I: input signal
 *    y                 O: output signal
 *    lg                I: size of filtering
 *    mem               B: memory associated with this filtering
 *    update            I: 0=no update, 1=update of memory.
 *
 * Function:
 *    Perform synthesis filtering through 1/A(z).
 *
 * Returns:
 *    void
 ************************************************************************************/
static Word32 Syn_filt( Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
      , Word32 update )
{/*合成滤波器重构语音*/
	Word32 tmp[50];   /* malloc is slow */
	Word32 s, a0, overflow = 0;
	Word32 *yy, *yy_limit;


	/* Copy mem[] to yy[] */
	memcpy( tmp, mem, 40 );
	yy = tmp + M;
	yy_limit = yy + lg;
	a0 = a[0];

	/* Do the filtering. */
	while ( yy < yy_limit ) 
	{

		s = *x++ * a0;
		s -= yy[-1] * a[1];
		s -= yy[-2] * a[2];
		s -= yy[-3] * a[3];
		s -= yy[-4] * a[4];
		s -= yy[-5] * a[5];
		s -= yy[-6] * a[6];
		s -= yy[-7] * a[7];
		s -= yy[-8] * a[8];
		s -= yy[-9] * a[9];
		s -= yy[-10] * a[10];
		if ( labs( s ) < 0x7ffffff )
			 *yy = ( s + 0x800L ) >> 12;
		else if ( s > 0 ) 
		{
			 *yy = 32767;
			 overflow = 1;
		}
		else 
		{
			 *yy = -32768;
			 overflow = 1;
		}
		yy++;
	}
	memcpy( y, &tmp[M], lg <<2 );

	/* Update of memory if update==1 */
	if ( update ) 
	{
		memcpy( mem, &y[lg - M], 40 );
	}
	return overflow;
}

/*************************************************************************************
 * Syn_filt_overflow
 *
 *
 * Parameters:
 *    a                 I: prediction coefficients [M+1]
 *    x                 I: input signal
 *    y                 O: output signal
 *    lg                I: size of filtering
 *    mem               B: memory associated with this filtering
 *    update            I: 0=no update, 1=update of memory.
 *
 * Function:
 *    Perform synthesis filtering through 1/A(z).
 *    Saturate after every multiplication.
 * Returns:
 *    void
 *************************************************************************************/
static void Syn_filt_overflow( Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
      , Word32 update )
{
	Word32 tmp[50];   /* malloc is slow */
	Word32 i, j, s, a0;
	Word32 *yy;


	/* Copy mem[] to yy[] */
	memcpy( tmp, mem, 40 );
	yy = tmp + M;
	a0 = a[0];

	/* Do the filtering. */
	for ( i = 0; i < lg; i++ ) 
	{
		s = x[i] * a0;

		for ( j = 1; j <= M; j++ ) 
		{
			 s -= a[j] * yy[ - j];
			 if (s > 1073741823)
			{
				s = 1073741823;
			 }
			 else if ( s < -1073741824) 
			{
				s = -1073741824;
			 }
		}

		if ( labs( s ) < 0x7FFE800 )
			 *yy = ( s + 0x800L ) >> 12;
		else if ( s > 0 ) 
		{
			 *yy = 32767;
		}
		else 
		{
			 *yy = -32768;
		}
		yy++;
	}
	memcpy( y, &tmp[M], lg <<2 );

	/* Update of memory if update==1 */
	if ( update ) 
	{
		memcpy( mem, &y[lg - M], 40 );
	}
	return;
}

/************************************************************************************
 * dtx_dec
 *
 *
 * Parameters:
 *    st                            B: DTX state struct
 *    mem_syn                       I: AMR decoder state
 *    lsfState                      B: LSF state struct
 *    pred_state->past_qua_en       O: table of past quantized energies
 *    pred_state->past_qua_en_MR122 O: table of past quantized energies MR122
 *    averState->hangVar            O:
 *    averState->hangCount          O: hangover variable
 *    new_state                     I: new DTX state
 *    mode                          I: AMR mode
 *    parm                          I: vector of synthesis parameters
 *    synth                         O: synthesised speech
 *    A_t                           O: decoded LP filter in 4 subframes
 *
 * Function:
 *    DTX
 *
 * Returns:
 *    void
 *************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -