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

📄 sp_dec.c

📁 AMR-NB的解码程序,纯C, VC建立工程即可使用.标准测试序列通过测试,与编码配合使用.
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
		lsp[i] = ( lsp_mid[i] >> 1 ) + ( lsp_new[i] >> 1 );
	}

	/* Subframe 3 */
	Lsp_Az( lsp, Az );
	Az += MP1;

	/* Subframe 4 */
	Lsp_Az( lsp_new, Az );
	return;
}


/************************************************************************************
 * Int_lpc_1to3
 *
 *
 * Parameters:
 *    lsp_old           I: LSP vector at the 4th subframe of past frame    [M]
 *    lsp_new           I: LSP vector at the 4th subframe of present frame [M]
 *    Az                O: interpolated LP parameters in all subframes
 *                                                                   [AZ_SIZE]
 *
 * Function:
 *    Interpolates the LSPs and converts to LPC parameters to get a different
 *    LP filter in each subframe.
 *
 *    The 20 ms speech frame is divided into 4 subframes.
 *    The LSPs are quantized and transmitted at the 4th
 *    subframes (once per frame) and interpolated at the
 *    1st, 2nd and 3rd subframe.
 *
 * Returns:
 *    void
 ************************************************************************************/
static void Int_lpc_1to3( Word32 lsp_old[], Word32 lsp_new[], Word32 Az[] )
{/*lsp系数内插得到内插lsp矢量*/
	Word32 lsp[M];
	Word32 i;


	for ( i = 0; i < 10; i+=2 ) 
	{
		lsp[i] = ( lsp_new[i] >> 2 ) + ( lsp_old[i] - ( lsp_old[i] >> 2 ) );
		lsp[i+1] = ( lsp_new[i+1] >> 2 ) + ( lsp_old[i+1] - ( lsp_old[i+1] >> 2 ) );
	}

	/* Subframe 1 */
	Lsp_Az( lsp, Az );
	Az += MP1;

	for ( i = 0; i < 10; i+=2 ) 
	{
		lsp[i] = ( lsp_old[i] >> 1 ) + ( lsp_new[i] >> 1 );
		lsp[i+1] = ( lsp_old[i+1] >> 1 ) + ( lsp_new[i+1] >> 1 );
	}

	/* Subframe 2 */
	Lsp_Az( lsp, Az );
	Az += MP1;

	for ( i = 0; i < 10; i+=2 ) 
	{
		lsp[i] = ( lsp_old[i] >> 2 ) + ( lsp_new[i] - ( lsp_new[i] >> 2 ) );
		lsp[i+1] = ( lsp_old[i+1] >> 2 ) + ( lsp_new[i+1] - ( lsp_new[i+1] >> 2 ) );
	}

	/* Subframe 3 */
	Lsp_Az( lsp, Az );
	Az += MP1;

	/* Subframe 4 */
	Lsp_Az( lsp_new, Az );
	return;
}


/************************************************************************************
 * D_plsf_5
 *
 *
 * Parameters:
 *    st->past_lsf_q I: Past dequantized LFSs
 *    st->past_r_q      B: past quantized residual
 *    bfi               B: bad frame indicator
 *    indice            I: quantization indices of 3 submatrices, Q0
 *    lsp1_q            O: quantized 1st LSP vector
 *    lsp2_q            O: quantized 2nd LSP vector
 *
 * Function:
 *    Decodes the 2 sets of LSP parameters in a frame
 *    using the received quantization indices.
 *
 * Returns:
 *    void
 **************************************************************************************/
static void D_plsf_5( D_plsfState *st, Word16 bfi, Word16 *indice, Word32 *lsp1_q
      , Word32 *lsp2_q )
{/*根据lsf的索引号重构lsp系数*/
	Word32 lsf1_r[M], lsf2_r[M], lsf1_q[M], lsf2_q[M];
	Word32 i, temp1, temp2, sign;
	const Word32 *p_dico;


	/* if bad frame */
	if ( bfi != 0 ) 
	{
		/* use the past LSFs slightly shifted towards their mean */
		for ( i = 0; i < M; i += 2 ) 
		{
			lsf1_q[i] = ( ( st->past_lsf_q[i] * ALPHA_122 ) >> 15 ) + ( ( mean_lsf_5[i]
			* ONE_ALPHA_122 ) >> 15 );
			lsf1_q[i + 1] = ( ( st->past_lsf_q[i + 1] * ALPHA_122 ) >> 15 ) + ( (
			mean_lsf_5[i + 1] * ONE_ALPHA_122 ) >> 15 );
		}
		memcpy( lsf2_q, lsf1_q, M <<2 );

		/* estimate past quantized residual to be used in next frame */
		for ( i = 0; i < M; i += 2 ) 
		{
			temp1 = mean_lsf_5[i] + ( ( st->past_r_q[i] * LSP_PRED_FAC_MR122 ) >>15 );
			temp2 = mean_lsf_5[i + 1] +( ( st->past_r_q[i + 1] *LSP_PRED_FAC_MR122	) >> 15 );
			
			st->past_r_q[i] = lsf2_q[i] - temp1;
			st->past_r_q[i + 1] = lsf2_q[i + 1] -temp2;
		}
	}

	/* if good LSFs received */
	else 
	{
		/* decode prediction residuals from 5 received indices */
		p_dico = &dico1_lsf_5[indice[0] << 2];
		lsf1_r[0] = *p_dico++;
		lsf1_r[1] = *p_dico++;
		lsf2_r[0] = *p_dico++;
		lsf2_r[1] = *p_dico++;
		p_dico = &dico2_lsf_5[indice[1] << 2];
		lsf1_r[2] = *p_dico++;
		lsf1_r[3] = *p_dico++;
		lsf2_r[2] = *p_dico++;
		lsf2_r[3] = *p_dico++;

		sign = ( Word16 )( indice[2] & 1 );
		i = indice[2] >> 1;
		p_dico = &dico3_lsf_5[i << 2];

		if ( sign == 0 ) 
		{
			lsf1_r[4] = *p_dico++;
			lsf1_r[5] = *p_dico++;
			lsf2_r[4] = *p_dico++;
			lsf2_r[5] = *p_dico++;
		}
		else 
		{
			lsf1_r[4] = ( Word16 )( -( *p_dico++ ) );
			lsf1_r[5] = ( Word16 )( -( *p_dico++ ) );
			lsf2_r[4] = ( Word16 )( -( *p_dico++ ) );
			lsf2_r[5] = ( Word16 )( -( *p_dico++ ) );
		}
		p_dico = &dico4_lsf_5[( indice[3]<<2 )];
		lsf1_r[6] = *p_dico++;
		lsf1_r[7] = *p_dico++;
		lsf2_r[6] = *p_dico++;
		lsf2_r[7] = *p_dico++;
		p_dico = &dico5_lsf_5[( indice[4]<<2 )];
		lsf1_r[8] = *p_dico++;
		lsf1_r[9] = *p_dico++;
		lsf2_r[8] = *p_dico++;
		lsf2_r[9] = *p_dico++;

		/* Compute quantized LSFs and update the past quantized residual */
		for ( i = 0; i < M; i++ ) 
		{
			temp1 = mean_lsf_5[i] + ( ( st->past_r_q[i] * LSP_PRED_FAC_MR122 ) >>15 );
			
			lsf1_q[i] = lsf1_r[i] + temp1;
			lsf2_q[i] = lsf2_r[i] + temp1;
			st->past_r_q[i] = lsf2_r[i];
		}
	}

	/* verification that LSFs have minimum distance of LSF_GAP Hz */
	Reorder_lsf( lsf1_q, LSF_GAP );
	Reorder_lsf( lsf2_q, LSF_GAP );
	memcpy( st->past_lsf_q, lsf2_q, M <<2 );

	/*  convert LSFs to the cosine domain */
	Lsf_lsp( lsf1_q, lsp1_q );
	Lsf_lsp( lsf2_q, lsp2_q );
	return;
}


/************************************************************************************
 * Dec_lag3
 *
 *
 * Parameters:
 *    index             I: received pitch index
 *    t0_min            I: minimum of search range
 *    t0_max            I: maximum of search range
 *    i_subfr           I: subframe flag
 *    T0_prev           I: integer pitch delay of last subframe used
 *                         in 2nd and 4th subframes
 *    T0                O: integer part of pitch lag
 *    T0_frac           O : fractional part of pitch lag
 *    flag4             I : flag for encoding with 4 bits
 * Function:
 *    Decoding of fractional pitch lag with 1/3 resolution.
 *    Extract the integer and fraction parts of the pitch lag from
 *    the received adaptive codebook index.
 *
 *    The fractional lag in 1st and 3rd subframes is encoded with 8 bits
 *    while that in 2nd and 4th subframes is relatively encoded with 4, 5
 *    and 6 bits depending on the mode.
 *
 * Returns:
 *    void
  ************************************************************************************/
static void Dec_lag3( Word32 index, Word32 t0_min, Word32 t0_max, Word32 i_subfr
      , Word32 T0_prev, Word32 *T0, Word32 *T0_frac, Word32 flag4 )
{
	Word32 i, tmp_lag;


	/* if 1st or 3rd subframe */
	if ( i_subfr == 0 ) 
	{
		if ( index < 197 ) 
		{
			*T0 = ( ( ( index + 2 ) * 10923 ) >> 15 ) + 19;
			i = *T0 + *T0 + *T0;
			*T0_frac = ( index - i ) + 58;
		}
		else 
		{
			*T0 = index - 112;
			*T0_frac = 0;
		}
	}

	/* 2nd or 4th subframe */
	else 
	{
		if ( flag4 == 0 ) 
		{
			/* 'normal' decoding: either with 5 or 6 bit resolution */
			i = ( ( ( index + 2 ) * 10923 ) >> 15 ) - 1;
			*T0 = i + t0_min;
			i = i + i + i;
			*T0_frac = ( index - 2 ) - i;
		}
		else 
		{
			/* decoding with 4 bit resolution */
			tmp_lag = T0_prev;

			if ( ( tmp_lag - t0_min ) > 5 )
				tmp_lag = t0_min + 5;

			if ( ( t0_max - tmp_lag ) > 4 )
				tmp_lag = t0_max - 4;

			if ( index < 4 ) 
			{
				i = ( tmp_lag - 5 );
				*T0 = i + index;
				*T0_frac = 0;
			}
			else 
			{
				if ( index < 12 ) 
				{
					i = ( ( ( index - 5 ) * 10923 ) >> 15 ) - 1;
					*T0 = i + tmp_lag;
					i = i + i + i;
					*T0_frac = ( index - 9 ) - i;
				}
				else 
				{
					i = ( index - 12 ) + tmp_lag;
					*T0 = i + 1;
					*T0_frac = 0;
				}
			}
		}   /* end if (decoding with 4 bit resolution) */
	}
	return;
}


/************************************************************************************
 * Pred_lt_3or6_40
 *
 *
 * Parameters:
 *    exc               B: excitation buffer
 *    T0                I: integer pitch lag
 *    frac              I: fraction of lag
 *    flag3             I: if set, upsampling rate = 3 (6 otherwise)
 *
 * Function:
 *    Compute the result of long term prediction with fractional
 *    interpolation of resolution 1/3 or 1/6. (Interpolated past excitation).
 *
 *    Once the fractional pitch lag is determined,
 *    the adaptive codebook vector v(n) is computed by interpolating
 *    the past excitation signal u(n) at the given integer delay k
 *    and phase (fraction)  :
 *
 *          9                       9
 *    v(n) = SUM[ u(n-k-i) * b60(t+i*6) ] + SUM[ u(n-k+1+i) * b60(6-t+i*6) ],
 *          i=0                       i=0
 *    n = 0, ...,39, t = 0, ...,5.
 *
 *    The interpolation filter b60 is based on a Hamming windowed sin(x)/x
 *    function truncated at ?59 and padded with zeros at ?60 (b60(60)=0)).
 *    The filter has a cut-off frequency (-3 dB) at 3 600 Hz in
 *    the over-sampled domain.
 *
 * Returns:
 *    void
 *************************************************************************************/
static void Pred_lt_3or6_40( Word32 exc[], Word32 T0, Word32 frac, Word32 flag3 )
{/*内插过去的激励得到自适应码本矢量元素*/
	Word32 s, i;
	Word32 *x0, *x1, *x2;
	const Word32 *c1, *c2;


	x0 = &exc[ - T0];
	frac = -frac;

	if ( flag3 != 0 ) 
	{
		frac <<= 1;   /* inter_3l[k] = inter6[2*k] -> k' = 2*k */
	}

	if ( frac < 0 ) 
	{
		frac += 6;
		x0--;
	}
	c1 = &inter6[frac];
	c2 = &inter6[6 - frac];

	for ( i = 0; i < 40; i++ ) 
	{
		x1 = x0++;
		x2 = x0;
		s = x1[0] * c1[0];
		s += x1[ - 1] * c1[6];
		s += x1[ - 2] * c1[12];
		s += x1[ - 3] * c1[18];
		s += x1[ - 4] * c1[24];
		s += x1[ - 5] * c1[30];
		s += x1[ - 6] * c1[36];
		s += x1[ - 7] * c1[42];
		s += x1[ - 8] * c1[48];
		s += x1[ - 9] * c1[54];
		s += x2[0] * c2[0];
		s += x2[1] * c2[6];
		s += x2[2] * c2[12];
		s += x2[3] * c2[18];
		s += x2[4] * c2[24];
		s += x2[5] * c2[30];
		s += x2[6] * c2[36];
		s += x2[7] * c2[42];
		s += x2[8] * c2[48];
		s += x2[9] * c2[54];
		exc[i] = ( s + 0x4000 ) >> 15;

	}
}


/************************************************************************************
 * Dec_lag6
 *
 *
 * Parameters:
 *    index             I: received pitch index
 *    pit_min           I: minimum pitch lag
 *    pit_max           I: maximum pitch lag
 *    i_subfr           I: subframe flag
 *    T0                B: integer part of pitch lag
 *    T0_frac           O : fractional part of pitch lag
 *
 * Function:
 *    Decoding of fractional pitch lag with 1/6 resolution.
 *    Extract the integer and fraction parts of the pitch lag from
 *    the received adaptive codebook index.
 *
 *    The fractional lag in 1st and 3rd subframes is encoded with 9 bits
 *    while that in 2nd and 4th subframes is relatively encoded with 6 bits.
 *    Note that in relative encoding only 61 values are used. If the
 *    decoder receives 61, 62, or 63 as the relative pitch index, it means
 *    that a transmission error occurred. In this case, the pitch lag from
 *    previous subframe (actually from previous frame) is used.
 *
 * Returns:
 *    void
 *************************************************************************************/
static void Dec_lag6( Word32 index, Word32 pit_min, Word32 pit_max, Word32
      i_subfr, Word32 *T0, Word32 *T0_frac )
{/*根据基音索引得到基音延时的整数部分和分数部分*/
	Word32 t0_min, t0_max, i;


	/* if 1st or 3rd subframe */
	if ( i_subfr == 0 ) 
	{
		if ( index < 463 ) 
		{
			 /* T0 = (index+5)/6 + 17 */
			 *T0 = ( index + 5 ) / 6 + 17;
			 i = *T0 + *T0 + *T0;

			 /* *T0_frac = index - T0*6 + 105 */
			 *T0_frac = ( index - ( i + i ) ) + 105;
		}
		else 
		{
			 *T0 = index - 368;
			 *T0_frac = 0;
		}
	}

	/* second or fourth subframe */
	else 
	{
		/* find t0_min and t0_max for 2nd (or 4th) subframe */
		t0_min = *T0 - 5;

		if ( t0_min < pit_min ) 
		{
			 t0_min = pit_min;
		}
		t0_max = t0_min + 9;

		if ( t0_max > pit_max ) 
		{
			 t0_max = pit_max;
			 t0_min = t0_max - 9;
		}

		/* i = (index+5)/6 - 1 */
		i = ( index + 5 ) / 6 - 1;
		*T0 = i + t0_min;
		i = i + i + i;
		*T0_frac = ( index - 3 ) - ( i + i );
	}
}


/************************************************************************************
 * decompress10
 *
 *
 * Parameters:
 *    MSBs              I: MSB part of the index
 *    LSBs              I: LSB part of the index
 *    index1            I: index for first pos in posIndex
 *    index2            I: index for second pos in posIndex
 *    index3            I: index for third pos in posIndex
 *    pos_indx          O: position of 3 pulses (decompressed)
 * Function:
 *    Decompression of the linear codeword
 *
 * Returns:
 *    void
 *************************************************************************************/
static void decompress10( Word32 MSBs, Word32 LSBs, Word32 index1, Word32 index2
      , Word32 index3, Word32 pos_indx[] )
{
   Word32 divMSB;

   if (MSBs > 124)
   {
      MSBs = 124;
   }
   /*
    * pos_indx[index1] = ((MSBs-25*(MSBs/25))%5)*2 + (LSBs-4*(LSBs/4))%2;
    * pos_indx[index2] = ((MSBs-25*(MSBs/25))/5)*2 + (LSBs-4*(LSBs/4))/2;
    * pos_indx[index3] = (MSBs/25)*2 + LSBs/4;
    */
   divMSB = MSBs / 25;
   pos_indx[index1] = ( ( ( MSBs - 25 * ( divMSB ) ) % 5 ) << 1 ) + ( LSBs & 0x1
         );
   pos_indx[index2] = ( ( ( MSBs - 25 * ( divMSB ) ) / 5 ) << 1 ) + ( ( LSBs &
         0x2 ) >> 1 );
   pos_indx[index3] = ( divMSB << 1 ) + ( LSBs >> 2 );
   return;
}


/************************************************************************************
 * decompress_codewords
 *
 *
 * Parameters:
 *    indx              I: position of 8 pulses (compressed)
 *    pos_indx          O: position index of 8 pulses (position only)
 *
 * Function:
 *    Decompression of the linear codewords to 4+three indeces
 *    one bit from each pulse is made robust to errors by
 *    minimizing the phase shift of a bit error

⌨️ 快捷键说明

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