www.pudn.com > G711-729.rar > COD_CNG.C
/*
**
** File: "cod_cng.c"
**
** Description: Comfort noise generation
** performed at the encoder part
**
** Functions: Init_Cod_Cng()
** Cod_Cng()
** Update_Cng()
**
** Local functions:
** ComputePastAvFilter()
** CalcRC()
** LpcDiff()
**
**
*/
/*
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 "basop.h"
#include "lsp.h"
#include "lpc.h"
#include "util_cng.h"
#include "cod_cng.h"
#include "vad.h"
#include "coder.h"
/* Declaration of local functions */
static void ComputePastAvFilter(Word16 *Coeff);
static void CalcRC(Word16 *Coeff, Word16 *RC, Word16 *shRC);
static Flag LpcDiff(Word16 *RC, Word16 shRC, Word16 *Acf, Word16 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 = 0;
for(i=0; i< SizAcf; i++) CodCng.Acf[i] = 0;
for(i=0; i <= NbAvAcf; i++) CodCng.ShAcf[i] = 40;
for(i=0; i < LpcOrder; i++) CodCng.SidLpc[i] = 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:
**
** Word16 *DataExc Current frame synthetic excitation
** Word16 *Ftyp Characterizes the frame type for CNG
** LINEDEF *Line Quantized parameters (used for SID frames)
** Word16 *QntLpc Interpolated frame LPC coefficients
**
** Outputs:
**
** Word16 *DataExc
** Word16 *Ftyp
** LINEDEF *Line
** Word16 *QntLpc
**
** Return value: None
**
*/
void Cod_Cng(Word16 *DataExc, Word16 *Ftyp, LINEDEF *Line, Word16 *QntLpc)
{
Word16 curCoeff[LpcOrder];
Word16 curQGain;
Word16 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.ShAcf, CodCng.NbEner);
}
else {
CodCng.NbEner++;
if(CodCng.NbEner > NbAvGain) CodCng.NbEner = NbAvGain;
curQGain = Qua_SidGain(CodCng.Ener, CodCng.ShAcf, CodCng.NbEner);
/*
* Compute stationarity of current filter
* versus reference filter
*/
if(LpcDiff(CodCng.RC, CodCng.ShRC, CodCng.Acf, *CodCng.Ener) == 0) {
/* transmit SID frame */
*Ftyp = 2;
}
else {
temp = abs_s(sub(curQGain, CodCng.IRef));
if(temp > 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; 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 = extract_h(L_add( L_mult(CodCng.CurGain,0x7000),
L_mult(CodCng.SidGain,0x1000) ) ) ;
}
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:
**
** Word16 *Acf_sf sets of subframes Acfs of current frame
** Word16 *ShAcf_sf corresponding scaling factors
**
** Output : None
**
** Return value: None
**
*/
void Update_Acf(Word16 *Acf_sf, Word16 *ShAcf_sf)
{
int i, i_subfr;
Word16 *ptr1, *ptr2;
Word32 L_temp[LpcOrderP1];
Word16 sh1, temp;
Word32 L_acc0;
/* Update Acf and ShAcf */
ptr2 = CodCng.Acf + SizAcf;
ptr1 = ptr2 - LpcOrderP1;
for(i=LpcOrderP1; i=1; i--) CodCng.ShAcf[i] = CodCng.ShAcf[i-1];
/* Search ShAcf_sf min for current frame */
sh1 = ShAcf_sf[0];
for(i_subfr=1; i_subfr 0*/
/* & 1 bit margin for Itakura distance */
L_acc = L_shl(L_acc, sh1); /* shift right if < 0 */
RC[0] = round(L_acc);
for(i=1; i<=LpcOrder; i++) {
L_acc = L_mult( (Word16) 0xE000, Coeff[i-1]); /* - (1 << Lpc_justif.) */
for(j=0; j