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