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


/* 
** 
** File:            "codcng2.c" 
** 
** Description:     Comfort noise generation 
**                  performed at the encoder part 
** 
** Functions:       Init_Cod_Cng() 
**                  Cod_Cng() 
**                  Update_Acf() 
** 
** Local functions: 
**                  ComputePastAvFilter() 
**                  CalcRC() 
**                  LpcDiff() 
** 
** 
*/ 
/* 
    ITU-T G.723.1 Floating Point Speech Coder ANSI C Source Code.  Version 5.1F 
    copyright (c) 1995, AudioCodes, DSP Group, France Telecom, 
    Universite de Sherbrooke.  All rights reserved. 
 
    Floating-point code copyright (c) 1996, 
    Intel Corporation and France Telecom (CNET). 
    All rights reserved. 
*/ 
 
#include  
#include  
 
#include "typedef2.h" 
#include "cst2.h" 
#include "tab2.h" 
#include "util2.h" 
#include "lsp2.h" 
#include "lpc2.h" 
#include "utilcng2.h" 
#include "codcng2.h" 
#include "coder2.h" 
#include "vad2.h" 
 
/* Declaration of local functions */ 
static void ComputePastAvFilter(FLOAT *Coeff); 
static void CalcRC(FLOAT *Coeff, FLOAT *RC); 
static Flag LpcDiff(FLOAT *RC, FLOAT *ptrAcf, FLOAT alpha); 
 
/* Global Variables */ 
CODCNGDEF CodCng; 
 
/* 
** 
** Function:        Init_Cod_Cng() 
** 
** Description:     Initialize Cod_Cng static variables 
** 
** Links to text: 
** 
** Arguments:       None 
** 
** Outputs:         None 
** 
** Return value:    None 
** 
*/ 
void Init_Cod_Cng(void) 
{ 
    int i; 
 
    CodCng.CurGain = (FLOAT)0.0; 
 
    for (i=0; i< SizAcf; i++) 
        CodCng.Acf[i] = (FLOAT)0.0; 
 
    for (i=0; i < LpcOrder; i++) 
        CodCng.SidLpc[i] = (FLOAT)0.0; 
 
    CodCng.PastFtyp = 1; 
 
    CodCng.RandSeed = 12345; 
 
    return; 
} 
 
 
/* 
** 
** Function:           Cod_Cng() 
** 
** Description:        Computes Ftyp for inactive frames 
**                              0  :  for untransmitted frames 
**                              2  :  for SID frames 
**                     Computes current frame excitation 
**                     Computes current frame LSPs 
**                     Computes the coded parameters of SID frames 
** 
** Links to text: 
** 
** Arguments: 
** 
**  FLOAT   *DataExc   Current frame synthetic excitation 
**  Word16  *Ftyp      Characterizes the frame type for CNG 
**  LINEDEF *Line      Quantized parameters (used for SID frames) 
**  FLOAT   *QntLpc    Interpolated frame LPC coefficients 
** 
** Outputs: 
** 
**  FLOAT   *DataExc 
**  Word16  *Ftyp 
**  LINEDEF *Line 
**  FLOAT   *QntLpc 
** 
** Return value:       None 
** 
*/ 
void Cod_Cng(FLOAT *DataExc, Word16 *Ftyp, LINEDEF *Line, FLOAT *QntLpc) 
{ 
    FLOAT   curCoeff[LpcOrder]; 
    Word16  curQGain; 
    FLOAT   temp; 
    int     i; 
 
    /* 
     * Update Ener 
     */ 
    for (i=NbAvGain-1; i>=1; i--) { 
        CodCng.Ener[i] = CodCng.Ener[i-1]; 
    } 
 
    /* 
     * Compute LPC filter of present frame 
     */ 
    CodCng.Ener[0] = Durbin(curCoeff, &CodCng.Acf[1], CodCng.Acf[0], &temp); 
 
    /* 
     * if first frame of silence => SID frame 
     */ 
    if (CodCng.PastFtyp == 1) { 
        *Ftyp = 2; 
        CodCng.NbEner = 1; 
        curQGain = Qua_SidGain(CodCng.Ener, CodCng.NbEner); 
    } 
 
    else { 
        CodCng.NbEner++; 
        if (CodCng.NbEner > NbAvGain) 
            CodCng.NbEner = NbAvGain; 
        curQGain = Qua_SidGain(CodCng.Ener, CodCng.NbEner); 
 
        /* 
         * Compute stationarity of current filter 
         * versus reference filter 
         */ 
        if (LpcDiff(CodCng.RC, CodCng.Acf, *CodCng.Ener) == 0) { 
            *Ftyp = 2;  /* transmit SID frame */ 
        } 
        else { 
            i = abs((int)(curQGain - CodCng.IRef)); 
            if (i > ThreshGain) { 
                *Ftyp = 2; 
            } 
            else { 
                /* no transmission */ 
                *Ftyp = 0; 
            } 
        } 
    } 
 
    /* 
     * If SID frame : Compute SID filter 
     */ 
    if (*Ftyp == 2) { 
 
        /* 
         * Evaluates local stationnarity : 
         * Computes difference between current filter and past average filter 
         * if signal not locally stationary SID filter = current filter 
         * else SID filter = past average filter 
         */ 
 
        /* Compute past average filter */ 
        ComputePastAvFilter(CodCng.SidLpc) ; 
 
        /* If adaptation enabled, fill noise filter */ 
        if ( !VadStat.Aen ) { 
            for (i = 0; i < LpcOrder; i++) 
                VadStat.NLpc[i] = CodCng.SidLpc[i]; 
        } 
 
        /* Compute autocorr. of past average filter coefficients */ 
        CalcRC(CodCng.SidLpc , CodCng.RC); 
 
        if (LpcDiff(CodCng.RC, CodCng.Acf, *CodCng.Ener) == 0) { 
            for (i=0; iLspId = Lsp_Qnt(CodCng.LspSid, CodStat.PrevLsp); 
        Lsp_Inq(CodCng.LspSid, CodStat.PrevLsp, Line->LspId, 0); 
 
        Line->Sfs[0].Mamp = curQGain; 
        CodCng.IRef = curQGain; 
        CodCng.SidGain = Dec_SidGain(CodCng.IRef); 
 
    } /* end of Ftyp=2 case (SID frame) */ 
 
    /* 
     * Compute new excitation 
     */ 
    if (CodCng.PastFtyp == 1) { 
        CodCng.CurGain = CodCng.SidGain; 
    } 
    else { 
        CodCng.CurGain = (FLOAT)0.875 * CodCng.CurGain + (FLOAT)0.125 * CodCng.SidGain; 
    } 
    Calc_Exc_Rand(CodCng.CurGain, CodStat.PrevExc, DataExc, 
                                                &CodCng.RandSeed, Line); 
 
    /* 
     * Interpolate LSPs and update PrevLsp 
     */ 
    Lsp_Int(QntLpc, CodCng.LspSid, CodStat.PrevLsp); 
    for (i=0; i < LpcOrder ; i++) { 
        CodStat.PrevLsp[i] = CodCng.LspSid[i]; 
    } 
 
    /* 
     * Output & save frame type info 
     */ 
    CodCng.PastFtyp = *Ftyp; 
    return; 
} 
 
/* 
** 
** Function:           Update_Acf() 
** 
** Description:        Computes & Stores sums of subframe-acfs 
** 
** Links to text: 
** 
** Arguments: 
** 
**  FLOAT  *Acf_sf     sets of subframes Acfs of current frame 
** 
** Output :            None 
** 
** Return value:       None 
** 
*/ 
void Update_Acf(FLOAT *Acf_sf) 
{ 
    int i, i_subfr; 
    FLOAT *ptr1, *ptr2; 
 
    /* Update Acf */ 
    ptr2 = CodCng.Acf + SizAcf; 
    ptr1 = ptr2 - LpcOrderP1; 
    for (i=LpcOrderP1; i