www.pudn.com > G711-729.rar > UTIL_CNG.C


/* 
** 
** File:        "util_cng.c" 
** 
** Description:     General Comfort Noise Generation functions 
** 
** 
** Functions:       Calc_Exc_Rand() Computes random excitation 
**                                  used both by coder & decoder 
**                  Qua_SidGain()   Quantization of SID gain 
**                                  used by coder 
**                  Dec_SidGain()   Decoding of SID gain 
**                                  used both by coder & decoder 
** 
** Local functions : 
**                  distG() 
**                  random_number() 
 
*/ 
/* 
    ITU-T G.723 Speech Coder   ANSI-C Source Code     Version 5.00 
    copyright (c) 1995, AudioCodes, DSP Group, France Telecom, 
    Universite de Sherbrooke.  All rights reserved. 
*/ 
 
#include  
#include  
 
#include "typedef.h" 
#include "cst_lbc.h" 
#include "tab_lbc.h" 
#include "util_lbc.h" 
#include "exc_lbc.h" 
#include "basop.h" 
#include "util_cng.h" 
 
/* Declaration of local functions */ 
static Word16 random_number(Word16 number_max_p1, Word16 *nRandom); 
 
/* 
** 
** Function:           Calc_Exc_Rand() 
** 
** Description:        Computation of random excitation for inactive frames: 
**                     Adaptive codebook entry selected randomly 
**                     Higher rate innovation pattern selected randomly 
**                     Computes innovation gain to match curGain 
** 
** Links to text: 
** 
** Arguments: 
** 
**  Word16 curGain     current average gain to match 
**  Word16 *PrevExc    previous/current excitation (updated) 
**  Word16 *DataEXc    current frame excitation 
**  Word16 *nRandom    random generator status (input/output) 
** 
** Outputs: 
** 
**  Word16 *PrevExc 
**  Word16 *DataExc 
**  Word16 *nRandom 
** 
** Return value:       None 
** 
*/ 
void Calc_Exc_Rand(Word16 curGain, Word16 *PrevExc, Word16 *DataExc, 
                                      Word16 *nRandom, LINEDEF *Line) 
{ 
    int i, i_subfr, iblk; 
    Word16 temp, temp2; 
    Word16 j; 
    Word16 TabPos[2*NbPulsBlk], TabSign[2*NbPulsBlk]; 
    Word16 *ptr_TabPos, *ptr_TabSign; 
    Word16 *ptr1, *curExc; 
    Word16 sh1, x1, x2, inter_exc, delta, b0; 
    Word32 L_acc, L_c, L_temp; 
    Word16 tmp[SubFrLen/Sgrid]; 
    Word16 offset[SubFrames]; 
    Word16 tempExc[SubFrLenD]; 
 
 /* 
  * generate LTP codes 
  */ 
    Line->Olp[0] = random_number(21, nRandom) + (Word16)123; 
    Line->Olp[1] = random_number(21, nRandom) + (Word16)123; 
    for(i_subfr=0; i_subfrSfs[i_subfr].AcGn = random_number(NbFilt, nRandom) + (Word16)1; 
    } 
    Line->Sfs[0].AcLg = 1; 
    Line->Sfs[1].AcLg = 0; 
    Line->Sfs[2].AcLg = 1; 
    Line->Sfs[3].AcLg = 3; 
 
 
 /* 
  * Random innovation : 
  * Selection of the grids, signs and pulse positions 
  */ 
 
    /* Signs and Grids */ 
    ptr_TabSign = TabSign; 
    ptr1 = offset; 
    for(iblk=0; iblkOlp[iblk], 
                    Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn); 
        Decod_Acbk(&curExc[SubFrLen], &PrevExc[SubFrLen], Line->Olp[iblk], 
            Line->Sfs[i_subfr+1].AcLg, Line->Sfs[i_subfr+1].AcGn); 
 
        temp2 = 0; 
        for(i=0; i temp2) temp2 = temp; 
        } 
        if(temp2 == 0) sh1 = 0; 
        else { 
            sh1 = sub(4,norm_s(temp2)); /* 4 bits of margin  */ 
            if(sh1 < -2) sh1 = -2; 
        } 
 
        L_temp = 0L; 
        for(i=0; i> 2sh1-1                                */ 
        L_acc = L_sub(L_temp, L_acc); 
        /* x 1/nb_pulses_blk */ 
        L_c  = L_mls(L_acc, InvNbPulsBlk); 
 
/* 
 * Solve EQ(X) = X**2 + 2 b0 X + c 
 */ 
        /* delta = b0 x b0 - c */ 
        b0 = mult_r(inter_exc, InvNbPulsBlk);   /* b0 >> sh1 */ 
        L_acc = L_msu(L_c, b0, b0);             /* (c - b0**2) >> 2sh1-1 */ 
        L_acc = L_negate(L_acc);                /* delta x 2**(-2sh1+1) */ 
 
        /* Case delta <= 0 */ 
        if(L_acc <= 0) {  /* delta <= 0 */ 
            x1 = negate(b0);        /* sh1 */ 
        } 
 
        /* Case delta > 0 */ 
        else { 
            delta = Sqrt_lbc(L_acc);  /* >> sh1 */ 
            x1 = sub(delta, b0);      /* x1 >> sh1 */ 
            x2 = add(b0, delta);      /* (-x2) >> sh1 */ 
            if(abs_s(x2) < abs_s(x1)) { 
                x1 = negate(x2); 
            } 
        } 
 
        /* Update DataExc */ 
        sh1 = add(sh1, 1); 
        temp = shl(x1, sh1); 
        if(temp > (2*Gexc_Max)) temp = (2*Gexc_Max); 
        if(temp < -(2*Gexc_Max)) temp = -(2*Gexc_Max); 
        for(i=0; i= 1 : quantization of nq energies 
**                      for SID gain calculation in function Cod_Cng() 
**                      if nq = 0 : in function Comp_Info(), 
**                      quantization of saved estimated excitation energy 
** 
** Outputs:             None 
** 
** 
** Return value:       index of quantized energy 
** 
*/ 
Word16 Qua_SidGain(Word16 *Ener, Word16 *shEner, Word16 nq) 
{ 
    Word16 temp, iseg, iseg_p1; 
    Word16 j, j2, k, exp; 
    Word32 L_x, L_y; 
    Word16 sh1; 
    Word32 L_acc; 
    int i; 
 
    if(nq == 0) { 
         /* Quantize energy saved for frame erasure case                */ 
         /* L_x = 2 x average_ener                                      */ 
         temp = shl(*shEner, 1); 
         temp = sub(16, temp); 
         L_acc = L_deposit_l(*Ener); 
         L_acc = L_shl(L_acc, temp); /* may overflow, and >> if temp < 0 */ 
         L_x = L_mls(L_acc, fact[0]); 
    } 
 
    else { 
 
 /* 
  * Compute weighted average of energies 
  * Ener[i] = enerR[i] x 2**(shEner[i]-14) 
  * L_x = k[nq] x SUM(i=0->nq-1) enerR[i] 
  * with k[nq] =  2 x fact_mul x fact_mul / nq x Frame 
  */ 
         sh1 = shEner[0]; 
         for(i=1; i= L_bseg[2]) return(63); 
 
    /* Compute segment number iseg */ 
    if(L_x >= L_bseg[1]) { 
        iseg = 2; 
        exp = 4; 
    } 
    else { 
        exp  = 3; 
        if(L_x >= L_bseg[0]) iseg = 1; 
        else iseg = 0; 
    } 
 
    iseg_p1 = add(iseg,1); 
    j = shl(1, exp); 
    k = shr(j,1); 
 
    /* Binary search in segment iseg */ 
    for(i=0; i= L_y) j = add(j, k); 
        else j = sub(j, k); 
        k = shr(k, 1); 
    } 
 
    temp = add(base[iseg], shl(j, iseg_p1)); 
    L_y = L_mult(temp, temp); 
    L_y = L_sub(L_y, L_x); 
    if(L_y <= 0L) { 
        j2    = add(j, 1); 
        temp  = add(base[iseg], shl(j2, iseg_p1)); 
        L_acc = L_mult(temp, temp); 
        L_acc = L_sub(L_x, L_acc); 
        if(L_y > L_acc) temp = add(shl(iseg,4), j); 
        else temp = add(shl(iseg,4), j2); 
    } 
    else { 
        j2    = sub(j, 1); 
        temp  = add(base[iseg], shl(j2, iseg_p1)); 
        L_acc = L_mult(temp, temp); 
        L_acc = L_sub(L_x, L_acc); 
        if(L_y < L_acc) temp = add(shl(iseg,4), j); 
        else temp = add(shl(iseg,4), j2); 
    } 
    return(temp); 
} 
 
/* 
** 
** Function:           Dec_SidGain() 
** 
** Description:        Decoding of quantized Sid gain 
**                     (corresponding to sqrt of average energy) 
** 
** Links to text: 
** 
** Arguments: 
** 
**  Word16 iGain        index of quantized Sid Gain 
** 
** Outputs:             None 
** 
** Return value:        decoded gain value << 5 
** 
*/ 
Word16 Dec_SidGain(Word16 iGain) 
{ 
    Word16 i, iseg; 
    Word16 temp; 
 
    iseg = shr(iGain, 4); 
    if(iseg == 3) iseg = 2; 
    i = sub(iGain, shl(iseg, 4)); 
    temp = add(iseg, 1); 
    temp = shl(i, temp); 
    temp = add(temp, base[iseg]);  /* SidGain */ 
    temp = shl(temp, 5); /* << 5 */ 
    return(temp); 
}