www.pudn.com > p_voice.rar > CALCEXC.C


/* 
   ITU-T G.729 Annex C+ - Reference C code for floating point 
                         implementation of G.729 Annex C+ 
                         (integration of Annexes B, D and E) 
                          Version 2.1 of October 1999 
*/ 
 
/* 
File : CALCEXC.C 
*/ 
 
/* Computation of Comfort Noise excitation             */ 
 
#include  
#include  
#include  
 
#include "typedef.h" 
#include "ld8k.h" 
#include "ld8cp.h" 
#include "dtx.h" 
 
/* Local functions */ 
static FLOAT gauss(INT16 *seed); 
 
/*-----------------------------------------------------------* 
* procedure calc_exc_rand                                   * 
*           ~~~~~~~~~~~~~                                   * 
*   Computes comfort noise excitation                       * 
*   for SID and not-transmitted frames                      * 
*-----------------------------------------------------------*/ 
void calc_exc_rand( 
    FLOAT cur_gain,      /* (i)   :   target sample gain                 */ 
    FLOAT *exc,          /* (i/o) :   excitation array                   */ 
    INT16 *seed,         /* (i)   :   current Vad decision               */ 
    int flag_cod         /* (i)   :   encoder/decoder flag               */ 
) 
{ 
    FLOAT excg[L_SUBFR]; 
    int   pos[4]; 
    FLOAT sign[4]; 
    FLOAT *cur_exc; 
    FLOAT gp, ener, fact, inter_exc, k, delta, x1, x2, g; 
    int   i, i_subfr, t0, frac; 
    INT16 Gp, temp1, temp2; 
 
    if(cur_gain == (F)0.) { 
 
        for(i=0; i>= 2; 
        t0      = (int)(temp1 & (INT16)0x003F) + 40; 
        temp1 >>= 6; 
        temp2   = (INT16)(temp1 & (INT16)0x0007); 
        pos[0]  = 5 * (int)temp2; 
        temp1 >>= 3; 
        temp2   = (INT16)(temp1 & (INT16)0x0001); 
        sign[0] = (F)2. * (FLOAT)temp2 - (F)1.; 
        temp1 >>= 1; 
        temp2   = (INT16)(temp1 & (INT16)0x0007); 
        pos[1]  = 5 * (int)temp2 + 1; 
        temp1 >>= 3; 
        temp2   = (INT16)(temp1 & (INT16)0x0001); 
        sign[1] = (F)2. * (FLOAT)temp2 - (F)1.; 
        temp1   = random_g729c(seed); 
        temp2   = (INT16)(temp1 & (INT16)0x0007); 
        pos[2]  = 5 * (int)temp2 + 1; 
        temp1 >>= 3; 
        temp2   = (INT16)(temp1 & (INT16)0x0001); 
        sign[2] = (F)2. * (FLOAT)temp2 - (F)1.; 
        temp1 >>= 1; 
        temp2   = (INT16)(temp1 & (INT16)0x000F); 
        pos[3]  = (int)(temp2 & (INT16)0x0001) + 3; /* j+3*/ 
        temp2 >>= 1; 
        temp2  &= (INT16)0x0007; 
        pos[3] += 5 * (int)temp2; 
        temp1 >>= 4; 
        temp2   = (INT16)(temp1 & (INT16)0x0001); 
        sign[3] = (F)2. * (FLOAT)temp2 - (F)1.; 
        Gp      = (INT16)(random_g729c(seed) & (INT16)0x1FFF); /* < 0.5  */ 
        gp      = (FLOAT)Gp / (F)16384.; 
 
        /* Generate gaussian excitation */ 
        /********************************/ 
        ener = (F)0.; 
        for(i=0; i cur_exc */ 
        /**********************************************/ 
        ener = (F)0.; 
        for(i=0; i= (F)0.) { 
            if(g > G_MAX) g = G_MAX; 
        } 
        else { 
            if(g < (-G_MAX)) g = -G_MAX; 
        } 
 
        /* Update cur_exc with ACELP excitation */ 
        for(i=0; i<4; i++) { 
            cur_exc[pos[i]] += g * sign[i]; 
        } 
 
        if(flag_cod != FLAG_DEC) update_exc_err(gp, t0); 
        else { 
            if(g >= (F)0.) Update_PhDisp(gp,g); 
            else Update_PhDisp(gp,-g); 
        } 
        cur_exc += L_SUBFR; 
  } /* end of loop on subframes */ 
   
  return; 
} 
 
/*-----------------------------------------------------------* 
*         Local procedures                                  * 
*         ~~~~~~~~~~~~~~~~                                  * 
*-----------------------------------------------------------*/ 
 
/* Gaussian generation */ 
/***********************/ 
static FLOAT gauss(INT16 *seed) 
{ 
         
    /****  Xi = uniform v.a. in [-32768, 32767]       ****/ 
    /****  Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1)  ****/ 
    /****  output : Z                                 ****/ 
         
    int i; 
    INT16 temp; 
    INT32 L_acc, L_temp; 
     
    L_acc = 0L; 
    for(i=0; i<12; i++) { 
        L_temp = (INT32)random_g729c(seed); 
        L_acc += L_temp; 
    } 
    L_acc >>= 7; 
    temp = (INT16)L_acc;  /* Z x 512 */ 
    return((FLOAT)temp * (F)0.001953125);  /* Z */ 
}