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

📄 ol_ltp.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 4 页
字号:

#include "ol_ltp.h"
#include "basic_op.h"
#include "autocorr.h"
#include "qgain475.h"
#include "vad.h"
#include "qgain795.h"



#define UP_SAMP_MAX  6
#define L_INTER_SRCH  4  #define FIR_SIZE     (UP_SAMP_MAX*L_INTER_SRCH+1)

static const Word16 inter_6[FIR_SIZE] ={    29519,    28316, 24906, 19838, 13896, 7945, 2755,    -1127, -3459, -4304, -3969, -2899, -1561,    -336, 534, 970, 1023, 823, 516,    220, 0, -131, -194, -215, 0};



static const Word16 corrweight[251] = {	20473,	20506,	20539,	20572,	20605,	20644,	20677,	20716,	20749,	20788,	20821,	20860,	20893,	20932,	20972,	21011,	21050,	21089,	21129,	21168,	21207,	21247,	21286,	21332,	21371,	21417,	21456,	21502,	21542,	21588,	21633,	21679,	21725,	21771,	21817,	21863,	21909,	21961,	22007,	22059,	22105,	22158,	22210,	22263,	22315,	22367,	22420,	22472,	22531,	22584,	22643,	22702,	22761,	22820,	22879,	22938,	23003,	23062,	23128,	23193,	23252,	23324,	23390,	23455,	23527,	23600,	23665,	23744,	23816,	23888,	23967,	24045,	24124,	24202,	24288,	24366,	24451,	24537,	24628,	24714,	24805,	24904,	24995,	25094,	25192,	25297,	25395,	25500,	25611,	25723,	25834,	25952,	26070,	26188,	26313,	26444,	26575,	26706,	26844,	26988,	27132,	27283,	27440,	27597,	27761,	27931,	28108,	28285,	28475,	28665,	28869,	29078,	29295,	29524,	29760,	30002,	30258,	30527,	30808,	31457,	32767,	32767,	32767,	32767,	32767,	32767,	32767,	31457,	30808,	30527,	30258,	30002,	29760,	29524,	29295,	29078,	28869,	28665,	28475,	28285,	28108,	27931,	27761,	27597,	27440,	27283,	27132,	26988,	26844,	26706,	26575,	26444,	26313,	26188,	26070,	25952,	25834,	25723,	25611,	25500,	25395,	25297,	25192,	25094,	24995,	24904,	24805,	24714,	24628,	24537,	24451,	24366,	24288,	24202,	24124,	24045,	23967,	23888,	23816,	23744,	23665,	23600,	23527,	23455,	23390,	23324,	23252,	23193,	23128,	23062,	23003,	22938,	22879,	22820,	22761,	22702,	22643,	22584,	22531,	22472,	22420,	22367,	22315,	22263,	22210,	22158,	22105,	22059,	22007,	21961,	21909,	21863,	21817,	21771,	21725,	21679,	21633,	21588,	21542,	21502,	21456,	21417,	21371,	21332,	21286,	21247,	21207,	21168,	21129,	21089,	21050,	21011,	20972,	20932,	20893,	20860,	20821,	20788,	20749,	20716,	20677,	20644,	20605,	20572,	20539,	20506,	20473,	20434,	20401,	20369,	20336};

int ol_ltp(  pitchOLWghtState *st,  vadState *vadSt,  Mode mode, Word16 wsp[], Word16 *T_op, Word16 old_lags[],  Word16 ol_gain_flg[], Word16 idx,Flag dtx  )
{ 
   if ( mode!= MR102)   {      ol_gain_flg[0] = 0;                                         ol_gain_flg[1] = 0;                                    }       if ((mode == MR475)||(mode == MR515) )   {      *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME, idx, dtx);                                                             }   else   {      if ( mode <=  MR795  )      {           *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, idx, dtx);                                                                   }      else if (  mode ==MR102  )      {            *T_op = Pitch_ol_wgh(st, vadSt, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, old_lags, ol_gain_flg, idx, dtx);                                                               }      else      {                   *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN_MR122, PIT_MAX,L_FRAME_BY2, idx, dtx);                                                                   }   }
   return 0;}


static const struct {    Word16 max_frac_lag;     /* lag up to which fractional lags are used    */    Word16 flag3;                  /* enable 1/3 instead of 1/6 fract. resolution */
    Word16 first_frac;            /* first fractional to check                   */
    Word16 last_frac;             /* last fractional to check                    */
    Word16 delta_int_low;      /* integer lag below TO to start search from   */
    Word16 delta_int_range;   /* integer range around T0                     */
    Word16 delta_frc_low;       /* fractional below T0                         */
    Word16 delta_frc_range;    /* fractional range around T0                  */
    Word16 pit_min;                /* minimum pitch                               */
} mode_dep_parm[N_MODES] = 
{
    /* MR475 */  { 84,  1, -2,  2,  5, 10,  5,  9, PIT_MIN },    /* MR515 */  { 84,  1, -2,  2,  5, 10,  5,  9, PIT_MIN },                     /* MR59  */   { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
    /* MR67  */   { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
    /* MR74  */   { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
    /* MR795 */  { 84,  1, -2,  2,  3,  6, 10, 19, PIT_MIN },    /* MR102 */  { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },                     /* MR122 */  { 94,  0, -3,  3,  3,  6,  5,  9, PIT_MIN_MR122 }};
/************************************************************************* * *  FUNCTION:   Norm_Corr() * *  PURPOSE: Find the normalized correlation between the target vector *           and the filtered past excitation. * *  DESCRIPTION: *     The normalized correlation is given by the correlation between the *     target and filtered past excitation divided by the square root of *     the energy of filtered excitation. *                   corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[]) *     where x[] is the target vector and y_k[] is the filtered past *     excitation at delay k. * *************************************************************************/static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,                       Word16 t_min, Word16 t_max, Word16 corr_norm[]){	Word16 i, j, k;
	Word16 corr_h, corr_l, norm_h, norm_l,temp;
	Word32 s;
	Word16 excf[L_SUBFR];
	Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR];

	Word32 s1,s2,s3,s4,s5,s6,s7,s8;

	Word16*pexc = exc, *pxn = xn, *ph = h, *pcorr_norm = corr_norm;

	k = -t_min;                      

	/* compute the filtered excitation for the first delay t_min */
	Convolve (&pexc[k], ph, excf, L_subfr);

	s = 0;
	for (j = 0; j < 40; j++) 
	{
		s += excf[j]*excf[j] << 1;
		if( s < 0)
		{
			s = MAX_32; break;
		}		
	}
  	if (s <= 67108864L ) 
	{          
		s_excf = excf;                       
		h_fac = 3;                       
		scaling = 0;                         
	}
	else
	{
		s_excf = scaled_excf;                
		h_fac = 1;                 
		scaling = 2;  

		scaled_excf[0] = excf[0]>> 2;      scaled_excf[1] = excf[1]>> 2;       scaled_excf[2] = excf[2]>> 2;      scaled_excf[3] = excf[3]>> 2;       scaled_excf[4] = excf[4]>> 2; 
		scaled_excf[5] = excf[5]>> 2;      scaled_excf[6] = excf[6]>> 2;       scaled_excf[7] = excf[7]>> 2;      scaled_excf[8] = excf[8]>> 2;       scaled_excf[9] = excf[9]>> 2;  
		scaled_excf[10] = excf[10]>> 2;   scaled_excf[11] = excf[11]>> 2;   scaled_excf[12] = excf[12]>> 2;   scaled_excf[13] = excf[13]>> 2;   scaled_excf[14] = excf[14]>> 2;  
		scaled_excf[15] = excf[15]>> 2;   scaled_excf[16] = excf[16]>> 2;   scaled_excf[17] = excf[17]>> 2;   scaled_excf[18] = excf[18]>> 2;   scaled_excf[19] = excf[19]>> 2;  
		scaled_excf[20] = excf[20]>> 2;   scaled_excf[21] = excf[21]>> 2;   scaled_excf[22] = excf[22]>> 2;   scaled_excf[23] = excf[23]>> 2;   scaled_excf[24] = excf[24]>> 2;  
		scaled_excf[25] = excf[25]>> 2;   scaled_excf[26] = excf[26]>> 2;   scaled_excf[27] = excf[27]>> 2;   scaled_excf[28] = excf[28]>> 2;   scaled_excf[29] = excf[29]>> 2;  
		scaled_excf[30] = excf[30]>> 2;   scaled_excf[31] = excf[31]>> 2;   scaled_excf[32] = excf[32]>> 2;   scaled_excf[33] = excf[33]>> 2;   scaled_excf[34] = excf[34]>> 2;  
		scaled_excf[35] = excf[35]>> 2;   scaled_excf[36] = excf[36]>> 2;   scaled_excf[37] = excf[37]>> 2;   scaled_excf[38] = excf[38]>> 2;   scaled_excf[39] = excf[39]>> 2;  

	}
	/* loop for every possible period */
	for (i = t_min; i <= t_max; i++) 
	{
		/* Compute 1/sqrt(energy of excf[]) */
		s1 = s_excf[0]* s_excf[0] + s_excf[1]* s_excf[1] + s_excf[2]* s_excf[2] + s_excf[3]* s_excf[3]+s_excf[4]* s_excf[4];
		s2 = s_excf[5]* s_excf[5] + s_excf[6]* s_excf[6] + s_excf[7]* s_excf[7] + s_excf[8]* s_excf[8]+s_excf[9]* s_excf[9];
		s3 = s_excf[10]* s_excf[10] + s_excf[11]* s_excf[11] + s_excf[12]* s_excf[12] + s_excf[13]* s_excf[13]+s_excf[14]* s_excf[14];
		s4 = s_excf[15]* s_excf[15] + s_excf[16]* s_excf[16] + s_excf[17]* s_excf[17] + s_excf[18]* s_excf[18]+s_excf[19]* s_excf[19];
		s5 = s_excf[20]* s_excf[20] + s_excf[21]* s_excf[21] + s_excf[22]* s_excf[22] + s_excf[23]* s_excf[23]+s_excf[24]* s_excf[24];
		s6 = s_excf[25]* s_excf[25] + s_excf[26]* s_excf[26] + s_excf[27]* s_excf[27] + s_excf[28]* s_excf[28]+s_excf[29]* s_excf[29];
		s7 = s_excf[30]* s_excf[30] + s_excf[31]* s_excf[31] + s_excf[32]* s_excf[32] + s_excf[33]* s_excf[33]+s_excf[34]* s_excf[34];
		s8 = s_excf[35]* s_excf[35] + s_excf[36]* s_excf[36] + s_excf[37]* s_excf[37] + s_excf[38]* s_excf[38]+s_excf[39]* s_excf[39];

		s = (s1+s2+s3+s4+s5+s6+s7+s8)<<1;

		s = Inv_sqrt (s);
		norm_h = (Word16)(s >> 16);
		norm_l  = (s - (norm_h<<16))>>1;


		/* Compute correlation between xn[] and excf[] */      

		s1 = pxn[0]* s_excf[0]     + pxn[1]* s_excf[1]    + pxn[2]* s_excf[2]    + pxn[3]* s_excf[3]     + pxn[4]* s_excf[4];
		s2 = pxn[5]* s_excf[5]     + pxn[6]* s_excf[6]    + pxn[7]* s_excf[7]    + pxn[8]* s_excf[8]     + pxn[9]* s_excf[9];
		s3 = pxn[10]* s_excf[10] + pxn[11]* s_excf[11] + pxn[12]* s_excf[12] + pxn[13]* s_excf[13] + pxn[14]* s_excf[14];
		s4 = pxn[15]* s_excf[15] + pxn[16]* s_excf[16] + pxn[17]* s_excf[17] + pxn[18]* s_excf[18] + pxn[19]* s_excf[19];
		s5 = pxn[20]* s_excf[20] + pxn[21]* s_excf[21] + pxn[22]* s_excf[22] + pxn[23]* s_excf[23] + pxn[24]* s_excf[24];
		s6 = pxn[25]* s_excf[25] + pxn[26]* s_excf[26] + pxn[27]* s_excf[27] + pxn[28]* s_excf[28] + pxn[29]* s_excf[29];
		s7 = pxn[30]* s_excf[30] + pxn[31]* s_excf[31] + pxn[32]* s_excf[32] + pxn[33]* s_excf[33] + pxn[34]* s_excf[34];
		s8 = pxn[35]* s_excf[35] + pxn[36]* s_excf[36] + pxn[37]* s_excf[37] + pxn[38]* s_excf[38] + pxn[39]* s_excf[39];

		s = (s1+s2+s3+s4+s5+s6+s7+s8)<<1;

		corr_h = (Word16)(s >> 16);
		corr_l  = (s - (corr_h<<16))>>1;

		/* Normalize correlation = correlation * (1/sqrt(energy)) */
		s = (corr_h*norm_h <<1) + (((corr_h*norm_l >>15) +(norm_h*corr_l >>15) ) <<1);
		pcorr_norm[i] = (Word16)s;

		/* modify the filtered excitation excf[] for the next iteration */
		if (i != t_max ) 
		{
			k--;
			temp = pexc[k];
			s_excf[39] = (temp*ph[39] >>(15-h_fac)) + s_excf[38] ;  s_excf[38] = (temp*ph[38] >>(15-h_fac)) + s_excf[37] ;
			s_excf[37] = (temp*ph[37] >>(15-h_fac)) + s_excf[36] ;  s_excf[36] = (temp*ph[36] >>(15-h_fac)) + s_excf[35] ;
			s_excf[35] = (temp*ph[35] >>(15-h_fac)) + s_excf[34] ;  s_excf[34] = (temp*ph[34] >>(15-h_fac)) + s_excf[33] ;
			s_excf[33] = (temp*ph[33] >>(15-h_fac)) + s_excf[32] ;  s_excf[32] = (temp*ph[32] >>(15-h_fac)) + s_excf[31] ;

			s_excf[31] = (temp*ph[31] >>(15-h_fac)) + s_excf[30] ;  s_excf[30] = (temp*ph[30] >>(15-h_fac)) + s_excf[29] ;
			s_excf[29] = (temp*ph[29] >>(15-h_fac)) + s_excf[28] ;  s_excf[28] = (temp*ph[28] >>(15-h_fac)) + s_excf[27] ;
			s_excf[27] = (temp*ph[27] >>(15-h_fac)) + s_excf[26] ;  s_excf[26] = (temp*ph[26] >>(15-h_fac)) + s_excf[25] ;
			s_excf[25] = (temp*ph[25] >>(15-h_fac)) + s_excf[24] ;  s_excf[24] = (temp*ph[24] >>(15-h_fac)) + s_excf[23] ;

			s_excf[23] = (temp*ph[23] >>(15-h_fac)) + s_excf[22] ;  s_excf[22] = (temp*ph[22] >>(15-h_fac)) + s_excf[21] ;
			s_excf[21] = (temp*ph[21] >>(15-h_fac)) + s_excf[20] ;  s_excf[20] = (temp*ph[20] >>(15-h_fac)) + s_excf[19] ;
			s_excf[19] = (temp*ph[19] >>(15-h_fac)) + s_excf[18] ;  s_excf[18] = (temp*ph[18] >>(15-h_fac)) + s_excf[17] ;
			s_excf[17] = (temp*ph[17] >>(15-h_fac)) + s_excf[16] ;  s_excf[16] = (temp*ph[16] >>(15-h_fac)) + s_excf[15] ;

			s_excf[15] = (temp*ph[15] >>(15-h_fac)) + s_excf[14] ;  s_excf[14] = (temp*ph[14] >>(15-h_fac)) + s_excf[13] ;
			s_excf[13] = (temp*ph[13] >>(15-h_fac)) + s_excf[12] ;  s_excf[12] = (temp*ph[12] >>(15-h_fac)) + s_excf[11] ;
			s_excf[11] = (temp*ph[11] >>(15-h_fac)) + s_excf[10] ;  s_excf[10] = (temp*ph[10] >>(15-h_fac)) + s_excf[9] ;
			s_excf[9]   = (temp*ph[9 ] >>(15-h_fac)) + s_excf[8] ;    s_excf[8] = (temp*ph[8] >>(15-h_fac)) + s_excf[7] ;

			s_excf[7] = (temp*ph[7] >>(15-h_fac)) + s_excf[6] ;  s_excf[6] = (temp*ph[6] >>(15-h_fac)) + s_excf[5] ;
			s_excf[5] = (temp*ph[5] >>(15-h_fac)) + s_excf[4] ;  s_excf[4] = (temp*ph[4] >>(15-h_fac)) + s_excf[3] ;
			s_excf[3] = (temp*ph[3] >>(15-h_fac)) + s_excf[2] ;  s_excf[2] = (temp*ph[2] >>(15-h_fac)) + s_excf[1] ;
			s_excf[1] = (temp*ph[1] >>(15-h_fac)) + s_excf[0] ;  
		     s_excf[0] =  (pexc[k]>> scaling); 
		}
	}

    return;
	
}/************************************************************************* * *  FUNCTION:   searchFrac() * *  PURPOSE: Find fractional pitch * *  DESCRIPTION: *     The function interpolates the normalized correlation at the *     fractional positions around lag T0. The position at which the *     interpolation function reaches its maximum is the fractional pitch. *     Starting point of the search is frac, end point is last_frac. *     frac is overwritten with the fractional pitch. * *************************************************************************/static void searchFrac ( Word16 *lag, Word16 *frac,  Word16 last_frac, Word16 corr[],  Word16 flag3 )
{
    Word16 i;    Word16 max,fra ;
    Word16 corr_int;

    Word16 *x1, *x2,*x,*fract,*lagg,*pcorr;
    const Word16 *c1, *c2,*pinter_6 = inter_6;    Word32 s;

    fract = frac; lagg= lag; pcorr = corr;
    /* Test the fractions around T0 and choose the one which maximizes   . the interpolated normalized correlation.                          */

    max = MIN_16;
	
    for (i =  (*fract); i <= last_frac; i++) 
   {        //  corr_int = Interpol_3or6 (&corr[*lag], i, flag3);
	x = &pcorr[*lagg];
	fra = i;
	fra  <<= (flag3 != 0);
	x -= (fra < 0);
	fra += UP_SAMP_MAX*(fra < 0);	 
	x1 = &x[0];                        
	x2 = &x[1];                         
	c1 = &pinter_6[fra];               
	c2 = &pinter_6[UP_SAMP_MAX - fra];

	s   =  (x1[0]*c1[0] + x2[0]*c2[0]+  x1[-1]*c1[6] + x2[1]*c2[6]+ x1[-2]*c1[12] + x2[2]*c2[12]+ x1[-3]*c1[18] + x2[3]*c2[18] )<<1;
	corr_int =  ((s + 0x00008000)>> 16 );

	*fract = corr_int > max ? i : *fract;
	max = corr_int > max ? corr_int : max;
	     }
    if (flag3 == 0)     {      
        *lagg -= (*fract== -3);
	  *fract = (*fract== -3)  ?  3 : *fract ;

    }    else     {

	*lagg  -= ( *fract== -2) ;
	*fract   = ( *fract== -2)  ? 1 : *fract ;
	*lagg += ( *fract== 2) ;
	*fract   = ( *fract== 2) ? -1 : *fract;
	
       }

}
/************************************************************************* * *  FUNCTION:   Pitch_fr() * *  PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution *           (closed loop). * *  DESCRIPTION: *        - find the normalized correlation between the target and filtered *          past excitation in the search range. *        - select the delay with maximum normalized correlation. *        - interpolate the normalized correlation at fractions -3/6 to 3/6 *          with step 1/6 around the chosen delay. *        - The fraction which gives the maximum interpolated value is chosen. * *************************************************************************/Word16 Pitch_fr (  Pitch_frState *st,  Mode mode,  Word16 T_op[], Word16 exc[],  Word16 xn[], Word16 h[], 
    Word16 L_subfr,  Word16 i_subfr, Word16 *pit_frac,Word16 *resu3,   Word16 *ana_index )
{
	Word16 i;
	Word16 t_min, t_max;
	Word16 t0_min, t0_max;
	Word16 max, lag, frac;
	Word16 tmp_lag;
	Word16 *corr;
	Word16 corr_v[40];    /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */

	Word16 max_frac_lag;
	Word16 flag3, flag4;
	Word16 last_frac;
	Word16 delta_int_low, delta_int_range;
	Word16 delta_frc_low, delta_frc_range;
	Word16 pit_min;
	Word16 frame_offset;
	Word16 delta_search;

	Word16 index, tmp_ind, uplag;

	Pitch_frState *pst = st;
	Word16 *pT_op = T_op, *pexc = exc, *pxn = xn, *ph = h;
    
	/*-----------------------------------------------------------------------*
	*                      set mode specific variables                      *
	*-----------------------------------------------------------------------*/

	max_frac_lag     = mode_dep_parm[mode].max_frac_lag;         
	flag3                  = mode_dep_parm[mode].flag3;                
	frac                   = mode_dep_parm[mode].first_frac;            
	last_frac             = mode_dep_parm[mode].last_frac;              
	delta_int_low      = mode_dep_parm[mode].delta_int_low;        
	delta_int_range   = mode_dep_parm[mode].delta_int_range;      

	delta_frc_low       = mode_dep_parm[mode].delta_frc_low;      
	delta_frc_range   = mode_dep_parm[mode].delta_frc_range;     
	pit_min               = mode_dep_parm[mode].pit_min;            

	/*-----------------------------------------------------------------------*
	*                 decide upon full or differential search               *
	*-----------------------------------------------------------------------*/

	delta_search = 1;                                         

	if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2))
	{

		/* Subframe 1 and 3 */    
		if ( ((mode != MR475) && (mode != MR515)) ||( i_subfr != L_FRAME_BY2 ) ) 
		{

			/* set t0_min, t0_max for full search  , this is *not* done for mode MR475, MR515 in subframe 3 */

			delta_search = 0;  /* no differential search */       

			/* calculate index into T_op which contains the open-loop  . pitch estimations for the 2 big subframes */

			frame_offset = 1;                        

⌨️ 快捷键说明

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