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);
}