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

📄 cbsearch.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 5 页
字号:
*                         PUBLIC PROGRAM CODE******************************************************************************//************************************************************************* * *  FUNCTION:  code_2i40_11bits() * *  PURPOSE:  Searches a 11 bit algebraic codebook containing 2 pulses *            in a frame of 40 samples. * *  DESCRIPTION: *    The code length is 40, containing 2 nonzero pulses: i0...i1. *    All pulses can have two possible amplitudes: +1 or -1. *    Pulse i0 can have 2x8=16 possible positions, pulse i1 can have *    4x8=32 positions. * *       i0 :  1, 6, 11, 16, 21, 26, 31, 36. *             3, 8, 13, 18, 23, 28, 33, 38. *       i1 :  0, 5, 10, 15, 20, 25, 30, 35. *             1, 6, 11, 16, 21, 26, 31, 36.  *             2, 7, 12, 17, 22, 27, 32, 37. *             4, 9, 14, 19, 24, 29, 34, 39. * *************************************************************************/Word16 code_2i40_11bits(    Word16 x[],         /* i : target vector                                 */    Word16 h[],         /* i : impulse response of weighted synthesis filter */                        /*     h[-L_subfr..-1] must be set to zero.          */    Word16 T0,          /* i : Pitch lag                                     */    Word16 pitch_sharp, /* i : Last quantized pitch gain                     */    Word16 code[],      /* o : Innovative codebook                           */    Word16 y[],         /* o : filtered fixed codebook excitation            */    Word16 * sign       /* o : Signs of 2 pulses                             */){
    Word16 codvec[NB_PULSE_2i40_11BITS ];
    Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];    Word16 rr[L_CODE][L_CODE];    Word16 i, index, sharp;    Word16 *px =x, *ph = h, *py = y, *pcode = code,*psign = sign;
	
    sharp = pitch_sharp<< 1;	    if ( T0 < L_CODE)    {       for (i = T0; i < L_CODE; i++) 	  {          ph[i] +=  (ph[i - T0]*sharp >> 15);  
       }    }        cor_h_x2(ph, px, dn, 1, NB_TRACK, STEP);
    set_sign(dn, dn_sign, dn2, 8); /* dn2[] not used in this codebook search */    cor_h(ph, dn_sign, rr);
    search_2i40_11BITS (dn, rr, codvec);
                                    index = build_code_2i40_11BITS (codvec, dn_sign, pcode, ph, py, psign);
  /*-----------------------------------------------------------------*  * Compute innovation vector gain.                                 *  * Include fixed-gain pitch contribution into code[].              *  *-----------------------------------------------------------------*/      if ( T0 <  L_CODE)    {       for (i = T0; i < L_CODE; i++)       {          pcode[i] +=  (pcode[i - T0]*sharp >> 15 ); 
       }    }    return index;
	

}/*******************************************************************************                         PRIVATE PROGRAM CODE******************************************************************************//************************************************************************* * *  FUNCTION  search_2i40() * *  PURPOSE: Search the best codevector; determine positions of the 2 pulses *           in the 40-sample frame. * *************************************************************************/
static void search_2i40_11BITS (
    Word16 dn[],         /* i : correlation between target and h[] */    Word16 rr[][L_CODE], /* i : matrix of autocorrelation          */    Word16 codvec[]      /* o : algebraic codebook vector          */){
    Word16 i0, i1;    Word16 ix = 0; /* initialization only needed to keep gcc silent */    Word16 track1, track2, ipos[NB_PULSE_2i40_11BITS ];
    Word16 psk, ps0, ps1, sq, sq1;    Word16 alpk, alp, alp_16;    Word32 alp0, alp1,temp;

    Word16 *pdn = dn, *pcodvec = codvec;
	const Word16 *pstartPos1 = startPos1, *pstartPos2 = startPos2;
    psk = -1;                            alpk = 1;      
    

	pcodvec[0] = 0;     
	pcodvec[1] = 1;   

    /*------------------------------------------------------------------*     * main loop: try 2x4  tracks.                                      *     *------------------------------------------------------------------*/    for (track1 = 0; track1 < 2; track1++)    {       for (track2 = 0; track2 < 4; track2++)       {		          /* fix starting position */                    ipos[0] = pstartPos1[track1]; 
          ipos[1] = pstartPos2[track2];
                    /*----------------------------------------------------------------*           * i0 loop: try 8 positions.                                      *           *----------------------------------------------------------------*/                 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)          {             ps0 = pdn[i0];        
             alp0 = (rr[i0][i0]<<14);                          /*-------------------------------------------------------------*              * i1 loop: 8 positions.                                       *              *-------------------------------------------------------------*/                          sq = -1;                       alp = 1;                          ix = ipos[1];                                /*---------------------------------------------------------------*              * These index have low complexity address computation because   *              * they are, in fact, pointers with fixed increment. For example,*              * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]"   *              * and incremented by "STEP".                                    *              *---------------------------------------------------------------*/                for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) 		 {		     temp = (Word32)ps0 + (Word32)pdn[i1];
                   ps1 =  ( temp > 0x00007fffL) ? 0x7fff : ( temp < (Word32)0xffff8000L ? 0x8000 : (Word16)temp);           
		     alp1 = alp0 + (rr[i1][i1]<<14) + (rr[i0][i1]<<15);
				                   sq1 =  ( ps1*ps1>> 15);
                                   alp_16 =  (alp1 + 0x00008000)>>16 ;
                	               if (alp*sq1 > sq*alp_16)
	                {
	                   sq = sq1;       
	                   alp = alp_16;   
	                   ix = i1;        
	                }
             }                          /*---------------------------------------------------------------*              * memorise codevector if this one is better than the last one.  *              *---------------------------------------------------------------*/          if (alpk*sq > psk*alp)
             {                psk = sq;                           alpk = alp;                       pcodvec[0] = i0;   
                pcodvec[1] = ix;   
             }          }       }    }
    return;}/************************************************************************* * *  FUNCTION:  build_code() * *  PURPOSE: Builds the codeword, the filtered codeword and index of the *           codevector, based on the signs and positions of 2 pulses. * *************************************************************************/static Word16 build_code_2i40_11BITS(
    Word16 codvec[],  /* i : position of pulses                            */    Word16 dn_sign[], /* i : sign of pulses                                */    Word16 cod[],     /* o : innovative code vector                        */    Word16 h[],       /* i : impulse response of weighted synthesis filter */    Word16 y[],       /* o : filtered innovative code                      */    Word16 sign[]     /* o : sign of 2 pulses                              */){
    Word16 i, j, k, track, index, _sign[NB_PULSE_2i40_11BITS ], indx, rsign;
    Word16 *p0, *p1;
   Word16 *pcodvec = codvec, *pdn_sign = dn_sign, *pcod = cod, *ph = h,*py= y, *psign =sign;

    memset(pcod, 0 ,80);
	
 
    indx = 0;                                              rsign = 0;                                              for (k = 0; k < NB_PULSE_2i40_11BITS ; k++)
    {        i = pcodvec[k];      /* read pulse position */  
        j = pdn_sign[i];      /* read sign           */   
        index = ( i*6554 >> 15);     /* index = pos/5 */                                                 /* track = pos%5 */
        track = i - (Word16)(index*5);            
        if (track == 0 )        {                                  track = 1;                                         	    index <<= 6;  
        }        else if ( track == 1)        {                            if ( k ==0)           {                                    track = 0;                                             index <<= 1 ;           }           else           {              track = 1;                                             index = (index<< 6) + 16;                         }        }        else if ( track ==  2)        {                 track = 1;                                             index = (index << 6) +32;                   }        else if ( track == 3)        {           track = 0;                                               index = (index<< 1) + 1;                   }        else if(track == 4)        {                 track = 1;                                              index = (index <<6) + 48;        }        if (j > 0)
        {           pcod[i] = 8191;                             
           _sign[k] = 32767;              rsign = rsign+ (1<< track);
        }        else        {           pcod[i] = -8192;                              
           _sign[k] = (Word16) - 32768L;                       }                indx +=  index;    }    *psign = rsign;                                     
        p0 = ph - pcodvec[0];                                 
    p1 = ph - pcodvec[1];                                
    for (i = 0; i < L_CODE; i+=4)
    {	py[i] = ((((*p0++)* _sign[0] +  (*p1++)* _sign[1] ) << 1) +0x00008000) >> 16; 
	py[i+1] = ((((*p0++)* _sign[0] +  (*p1++)* _sign[1] ) << 1) +0x00008000) >> 16;    
	py[i+2] = ((((*p0++)* _sign[0] +  (*p1++)* _sign[1] ) << 1) +0x00008000) >> 16;    
	py[i+3] = ((((*p0++)* _sign[0] +  (*p1++)* _sign[1] ) << 1) +0x00008000) >> 16;    
		 
    }    return indx;
}

/*******************************************************************************                         DECLARATION OF PROTOTYPES******************************************************************************/static void search_2i40_9BITS(
    Word16 subNr,       /* i : subframe number                               */    Word16 dn[],        /* i : correlation between target and h[]            */    Word16 rr[][L_CODE],/* i : matrix of autocorrelation                     */    Word16 codvec[]     /* o : algebraic codebook vector                     */);static Word16 build_code_2i40_9BITS(
    Word16 subNr,       /* i : subframe number                               */    Word16 codvec[],    /* i : algebraic codebook vector                     */    Word16 dn_sign[],   /* i : sign of dn[]                                  */    Word16 cod[],       /* o : algebraic (fixed) codebook excitation         */    Word16 h[],         /* i : impulse response of weighted synthesis filter */    Word16 y[],         /* o : filtered fixed codebook excitation            */    Word16 sign[]       /* o : sign of 2 pulses                              */);/*******************************************************************************                         PUBLIC PROGRAM CODE******************************************************************************//************************************************************************* * *  FUNCTION:  code_2i40_9bits() * *  PURPOSE:  Searches a 9 bit algebraic codebook containing 2 pulses *            in a frame of 40 samples. * *  DESCRIPTION: *    The code length is 40, containing 2 nonzero pulses: i0...i1. *    All pulses can have two possible amplitudes: +1 or -1. *    Pulse i0 can have 8 possible positions, pulse i1 can have *    8 positions. Also coded is which track pair should be used, *    i.e. first or second pair. Where each pair contains 2 tracks. * *     First subframe: *     first   i0 :  0, 5, 10, 15, 20, 25, 30, 35. *             i1 :  2, 7, 12, 17, 22, 27, 32, 37. *     second  i0 :  1, 6, 11, 16, 21, 26, 31, 36. *             i1 :  3, 8, 13, 18, 23, 28, 33, 38. * *     Second subframe: *     first   i0 :  0, 5, 10, 15, 20, 25, 30, 35. *             i1 :  3, 8, 13, 18, 23, 28, 33, 38. *     second  i0 :  2, 7, 12, 17, 22, 27, 32, 37. *             i1 :  4, 9, 14, 19, 24, 29, 34, 39. * *     Third subframe: *     first   i0 :  0, 5, 10, 15, 20, 25, 30, 35. *             i1 :  2, 7, 12, 17, 22, 27, 32, 37. *     second  i0 :  1, 6, 11, 16, 21, 26, 31, 36. *             i1 :  4, 9, 14, 19, 24, 29, 34, 39. * *     Fourth subframe: *     first   i0 :  0, 5, 10, 15, 20, 25, 30, 35. *             i1 :  3, 8, 13, 18, 23, 28, 33, 38. *     second  i0 :  1, 6, 11, 16, 21, 26, 31, 36. *             i1 :  4, 9, 14, 19, 24, 29, 34, 39. *

⌨️ 快捷键说明

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