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

📄 cbsearch.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 5 页
字号:
//OPTIMIZE
/********************************************************************************      GSM AMR-NB speech codec   R98   Version 7.6.0   December 12, 2001*                                R99   Version 3.3.0                *                                REL-4 Version 4.1.0                ********************************************************************************      File             : cbsearch.c*      Purpose          : Inovative codebook search (find index and gain)*******************************************************************************/ /*******************************************************************************                         MODULE INCLUDE FILE AND VERSION ID******************************************************************************/#include "cbsearch.h" /*******************************************************************************                         INCLUDE FILES******************************************************************************/#include "basic_op.h"
 #include "autocorr.h"
 

static const Word16 gray[8]  = {0, 1, 3, 2, 6, 4, 5, 7};static const Word16 dgray[8] = {0, 1, 3, 2, 5, 6, 4, 7};


static const Word16 startPos[2*4*2] = {0, 2, 0, 3,                                       0, 2, 0, 3,                                       1, 3, 2, 4,                                       1, 4, 1, 4};

static const Word16 startPos1[2] = {1, 3};static const Word16 startPos2[4] = {0, 1, 2, 4};


 
/**********************************************************************************                         LOCAL VARIABLES AND TABLES*********************************************************************************/



/**********************************************************************************                         LOCAL VARIABLES AND TABLES*********************************************************************************/

/**********************************************************************************                         LOCAL VARIABLES AND TABLES*********************************************************************************/#define NB_PULSE_10i40_35BITS  10
#define NB_PULSE_2i40_11BITS  2
#define NB_PULSE_2i40_9BITS  2
#define NB_PULSE_3i40_14BITS  3
#define NB_PULSE_4i40_17BITS  4
#define NB_PULSE_8i40_31BITS 8



#define _1_2    (Word16)(32768L/2)#define _1_4    (Word16)(32768L/4)#define _1_8    (Word16)(32768L/8)#define _1_16   (Word16)(32768L/16)#define _1_32   (Word16)(32768L/32)#define _1_64   (Word16)(32768L/64)#define _1_128  (Word16)(32768L/128)
/* define values/representation for output codevector and sign */#define POS_CODE  8191 #define NEG_CODE  8191 #define POS_SIGN  32767#define NEG_SIGN  (Word16) (-32768L) 
/*
******************************************************************************                         LOCAL VARIABLES AND TABLES******************************************************************************/



/*******************************************************************************                         LOCAL VARIABLES AND TABLES******************************************************************************/


/**********************************************************************************                         LOCAL PROGRAM CODE*********************************************************************************/void q_p (    Word16 *ind,        /* Pulse position */    Word16 n             /* Pulse number   */){
    if ( n < 5)    {        *ind = (*ind & 0x8) | gray[*ind & 0x7];                                                
    }    else    {        *ind = gray[*ind& 0x7];              ; 
    }
}/************************************************************************* * *  FUNCTION:  build_code() * *  PURPOSE: Builds the codeword, the filtered codeword and index of the *           codevector, based on the signs and positions of 10 pulses. * *************************************************************************/static void build_code_10i40_35BITS (
    Word16 codvec[], /* (i)  : position of pulses                           */    Word16 sign[],      /* (i)  : sign of d[n]                                 */
    Word16 cod[],       /* (o)  : innovative code vector                       */
    Word16 h[],           /* (i)  : impulse response of weighted synthesis filter*/
    Word16 y[],            /* (o)  : filtered innovative code                     */
    Word16 indx[]        /* (o)  : index of 10 pulses (sign+position)           */
){    Word16 i, j, k, track, index, _sign[NB_PULSE_10i40_35BITS ];
    Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;    Word32 s,s1,s2,s3,s4,s5;

     Word16 *pcodvec = codvec, *psign = sign, *pcod = cod, *ph = h,*py= y, *pindx =indx;

    memset(pcod, 0 ,80);
    pindx[0] = pindx[1] = pindx[2] = pindx[3] = pindx[4] = -1;                          
        for (k = 0; k < NB_PULSE_10i40_35BITS ; k++)
    {        /* read pulse position */                    i = pcodvec[k];                        
        /* read sign           */                j = psign[i];                        
                index = (i* 6554 >> 15);                  /* index = pos/5       */        /* track = pos%5 */        track = i - (Word16)(index*5);              if (j > 0)        {            pcod[i] += 4096;      
            _sign[k] = 8192;                         }        else        {            pcod[i] -= 4096;     
            _sign[k] = -8192;                             index += 8;        }                      if (pindx[track] < 0)
        {            pindx[track] = index;                
        }        else        {                      if (((index ^ pindx[track]) & 8) == 0)
            {                /* sign of 1st pulse == sign of 2nd pulse */                                              if (pindx[track] <= index)
                {                    pindx[track + 5] = index;   
                }                else                {                    pindx[track + 5] = pindx[track];
                                                                   pindx[track] = index;        
                }            }            else            {                /* sign of 1st pulse != sign of 2nd pulse */                                              if ( (pindx[track] & 7) <=  (index & 7))
                {                    pindx[track + 5] = pindx[track];
                                                                  pindx[track] = index;        
                }                else                {                    pindx[track + 5] = index;    
                }            }        }    }        p0 = ph - pcodvec[0];                        
    p1 = ph - pcodvec[1];                         
    p2 = ph - pcodvec[2];                        
    p3 = ph - pcodvec[3];                         
    p4 = ph - pcodvec[4];                         
    p5 = ph - pcodvec[5];                        
    p6 = ph - pcodvec[6];                       
    p7 = ph - pcodvec[7];                         
    p8 = ph - pcodvec[8];                        
    p9 = ph - pcodvec[9];                        
         for (i = 0; i < L_CODE; i++)    {	s1 = ((*p0++)*_sign[0]+ (*p1++)*_sign[1])<<1;	s2 = ((*p2++)*_sign[2]+ (*p3++)*_sign[3])<<1 ;	s3 = ((*p4++)*_sign[4]+ (*p5++)*_sign[5])<<1;	s4 = ((*p6++)*_sign[6]+ (*p7++)*_sign[7])<<1;	s5 = ((*p8++)*_sign[8]+ (*p9++)*_sign[9])<<1;	s1 = (s1>0)&&(s2>0)&&((s1+s2)<0) ? MAX_32 : ( (s1<0)&&(s2<0)&&((s1+s2)>0) ? MIN_32: s1+s2);	s3 = (s3>0)&&(s4>0)&&((s3+s4)<0) ? MAX_32 : ( (s3<0)&&(s4<0)&&((s3+s4)>0) ? MIN_32: s3+s4);		s1 = (s1>0)&&(s5>0)&&((s1+s5)<0) ? MAX_32 : ( (s1<0)&&(s5<0)&&((s1+s5)>0) ? MIN_32: s1+s5);	s  = (s1>0) & (s3>0) & ((s1+s3)<0) ? MAX_32 :( (s1<0) & (s3<0) & ((s1+s3)>0) ? MIN_32: s1+s3);	y[i] = ( s > 0 )&&( s+ 0x00008000) < 0 ? 0x7fff : (s + 0x00008000)>>16 ;      	    }

}/**********************************************************************************                         PUBLIC PROGRAM CODE*********************************************************************************//************************************************************************* * *  FUNCTION:  code_10i40_35bits() * *  PURPOSE:  Searches a 35 bit algebraic codebook containing 10 pulses *            in a frame of 40 samples. * *  DESCRIPTION: *    The code contains 10 nonzero pulses: i0...i9. *    All pulses can have two possible amplitudes: +1 or -1. *    The 40 positions in a subframe are divided into 5 tracks of *    interleaved positions. Each track contains two pulses. *    The pulses can have the following possible positions: * *       i0, i5 :  0, 5, 10, 15, 20, 25, 30, 35. *       i1, i6 :  1, 6, 11, 16, 21, 26, 31, 36. *       i2, i7 :  2, 7, 12, 17, 22, 27, 32, 37. *       i3, i8 :  3, 8, 13, 18, 23, 28, 33, 38. *       i4, i9 :  4, 9, 14, 19, 24, 29, 34, 39. * *    Each pair of pulses require 1 bit for their signs and 6 bits for their *    positions (3 bits + 3 bits). This results in a 35 bit codebook. *    The function determines the optimal pulse signs and positions, builds *    the codevector, and computes the filtered codevector. * *************************************************************************/void code_10i40_35bits (    Word16 x[],   /* (i)   : target vector                                 */    Word16 cn[],  /* (i)   : residual after long term prediction           */    Word16 h[],   /* (i)   : impulse response of weighted synthesis filter                             h[-L_subfr..-1] must be set to zero           */    Word16 cod[], /* (o)   : algebraic (fixed) codebook excitation         */    Word16 y[],   /* (o)   : filtered fixed codebook excitation            */    Word16 indx[] /* (o)   : index of 10 pulses (sign + position)          */){

    Word16 ipos[NB_PULSE_10i40_35BITS ], pos_max[NB_TRACK], codvec[NB_PULSE_10i40_35BITS ];
    Word16 dn[L_CODE], sign[L_CODE];    Word16 rr[L_CODE][L_CODE];

    Word16* pindx = indx;
    const Word16* pgray = gray;
	
    //cor_h_x (h, x, dn, 2);
    cor_h_x2(h, x, dn, 2, NB_TRACK, STEP);
	  
     set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK, ipos, STEP);
     cor_h (h, sign, rr);
     search_10and8i40 (NB_PULSE_10i40_35BITS, STEP, NB_TRACK, dn, rr, ipos, pos_max, codvec);

      build_code_10i40_35BITS  (codvec, sign, cod, h, y, pindx);

	pindx[0] = (pindx[0]  & 0x8) | pgray[pindx[0]  & 0x7]; 
	pindx[1] = (pindx[1]  & 0x8) | pgray[pindx[1]  & 0x7]; 
	pindx[2] = (pindx[2]  & 0x8) | pgray[pindx[2]  & 0x7]; 
	pindx[3] = (pindx[3]  & 0x8) | pgray[pindx[3]  & 0x7]; 
	pindx[4] = (pindx[4]  & 0x8) | pgray[pindx[4]  & 0x7]; 
	
	pindx[5] =  pgray[pindx[5]& 0x7];  
	pindx[6] =  pgray[pindx[6]& 0x7];  
	pindx[7] =  pgray[pindx[7]& 0x7];  
	pindx[8] =  pgray[pindx[8]& 0x7];  
	pindx[9] =  pgray[pindx[9]& 0x7];  
	



    return;}


/*******************************************************************************                         DECLARATION OF PROTOTYPES******************************************************************************/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                     */);static Word16 build_code_2i40_11BITS (
    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                              */);/******************************************************************************

⌨️ 快捷键说明

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