📄 exc2.c
字号:
** Links to text: Sections 2.14, 2.18 & 3.4
**
** Arguments:
**
** FLOAT *Tv Reconstructed excitation vector
** FLOAT *PrevExc Previous excitation vector
** int Olp closed-loop pitch period
** int Lid Jitter around pitch period
** int Gid Gain vector index in 5- dimensional
** adaptive gain vector codebook
**
** Outputs:
**
** FLOAT *Tv Reconstructed excitation vector
**
** Return value: None
**
*/
void Decod_Acbk(FLOAT *Tv, FLOAT *PrevExc, int Olp, int Lid, int Gid)
{
int i;
FLOAT RezBuf[SubFrLen+ClPitchOrd-1];
FLOAT *sPnt;
Get_Rez(RezBuf, PrevExc, (Olp + Lid) - Pstep);
i = 0;
if (WrkRate == Rate63)
{
if (Olp >= (SubFrLen-2))
i++;
}
else
i=1;
sPnt = AcbkGainTablePtr[i] + Gid*20;
/* Compute output vector */
for (i=0; i < SubFrLen; i++)
Tv[i] = DotProd(&RezBuf[i], sPnt, ClPitchOrd);
}
/*
**
** Function: Comp_Lpf()
**
** Description: Computes pitch postfilter parameters.
** The pitch postfilter lag is first derived (Find_B
** and Find_F). Then, the one that gives the largest
** contribution is used to calculate the gains (Get_Ind).
**
**
** Links to text: Section 3.6
**
** Arguments:
**
** FLOAT *Buff decoded excitation
** int Olp Decoded pitch lag
** int Sfc Subframe index
**
** Outputs:
**
**
** Return value:
**
** PFDEF Pitch postfilter parameters: PF.Gain Pitch Postfilter gain
** PF.ScGn Pitch Postfilter scaling gain
** PF.Indx Pitch postfilter lag
*/
PFDEF Comp_Lpf(FLOAT *Buff, int Olp, int Sfc)
{
PFDEF Pf;
FLOAT Lcr[5];
int Bindx, Findx;
FLOAT Acc0,Acc1;
/* Initialize */
Pf.Indx = 0;
Pf.Gain = (FLOAT)0.0;
Pf.ScGn = (FLOAT)1.0;
/* Find both indices */
Bindx = Find_B(Buff, Olp, Sfc);
Findx = Find_F(Buff, Olp, Sfc);
/* Combine the results */
if ((Bindx==0) && (Findx==0))
return Pf;
/* Compute target energy */
Lcr[0] = DotProd(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen],SubFrLen);
if (Bindx != 0)
{
Lcr[1] = DotProd(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen+Bindx],SubFrLen);
Lcr[2] = DotProd(&Buff[PitchMax+Sfc*SubFrLen+Bindx],
&Buff[PitchMax+Sfc*SubFrLen+Bindx],SubFrLen);
}
if (Findx != 0)
{
Lcr[3] = DotProd(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen+Findx],SubFrLen);
Lcr[4] = DotProd(&Buff[PitchMax+Sfc*SubFrLen+Findx],
&Buff[PitchMax+Sfc*SubFrLen+Findx],SubFrLen);
}
/* Select the best pair */
if ((Bindx != 0) && (Findx == 0))
Pf = Get_Ind(Bindx, Lcr[0], Lcr[1], Lcr[2]);
if ((Bindx == 0) && (Findx != 0))
Pf = Get_Ind(Findx, Lcr[0], Lcr[3], Lcr[4]);
if ((Bindx != 0) && (Findx != 0))
{
Acc0 = Lcr[4] * Lcr[1] * Lcr[1];
Acc1 = Lcr[2] * Lcr[3] * Lcr[3];
if (Acc0 > Acc1)
Pf = Get_Ind(Bindx, Lcr[0], Lcr[1], Lcr[2]);
else
Pf = Get_Ind(Findx, Lcr[0], Lcr[3], Lcr[4]);
}
return Pf;
}
/*
**
** Function: Find_B()
**
** Description: Computes best pitch postfilter backward lag by
** backward cross correlation maximization around the
** decoded pitch lag
** of the subframe 0 (for subrames 0 & 1)
** of the subframe 2 (for subrames 2 & 3)
**
** Links to text: Section 3.6
**
** Arguments:
**
** FLOAT *Buff decoded excitation
** int Olp Decoded pitch lag
** int Sfc Subframe index
**
** Outputs: None
**
** Return value:
**
** Word16 Pitch postfilter backward lag
*/
int Find_B(FLOAT *Buff, int Olp, int Sfc)
{
int i;
int Indx = 0;
FLOAT Acc0,Acc1;
if (Olp > (PitchMax-3))
Olp = (PitchMax-3);
Acc1 = (FLOAT)0.0;
for (i=Olp-3; i<=Olp+3; i++)
{
Acc0 = DotProd(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen-i],SubFrLen);
/* return index of largest cross correlation */
if (Acc0 > Acc1)
{
Acc1 = Acc0;
Indx = i;
}
}
return -Indx;
}
/*
**
** Function: Find_F()
**
** Description: Computes best pitch postfilter forward lag by
** forward cross correlation maximization around the
** decoded pitch lag
** of the subframe 0 (for subrames 0 & 1)
** of the subframe 2 (for subrames 2 & 3)
**
** Links to text: Section 3.6
**
** Arguments:
**
** FLOAT *Buff decoded excitation
** int Olp Decoded pitch lag
** int Sfc Subframe index
**
** Outputs: None
**
** Return value:
**
** int Pitch postfilter forward lag
*/
int Find_F(FLOAT *Buff, int Olp, int Sfc)
{
int i;
int Indx = 0;
FLOAT Acc0,Acc1;
if (Olp > (PitchMax-3))
Olp = (PitchMax-3);
Acc1 = (FLOAT)0.0;
for (i=Olp-3; i<=Olp+3; i++)
{
if (!((Sfc*SubFrLen+SubFrLen+i) > Frame))
{
Acc0 = DotProd(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen+i],SubFrLen);
/* return index of largest cross correlation */
if (Acc0 > Acc1)
{
Acc1 = Acc0;
Indx = i;
}
}
}
return Indx;
}
/*
**
** Function: Filt_Lpf()
**
** Description: Applies the pitch postfilter for each subframe.
**
** Links to text: Section 3.6
**
** Arguments:
**
** FLOAT *Tv Pitch postfiltered excitation
** FLOAT *Buff decoded excitation
** PFDEF Pf Pitch postfilter parameters
** int Sfc Subframe index
**
** Outputs:
**
** FLOAT *Tv Pitch postfiltered excitation
**
** Return value: None
**
*/
void Filt_Lpf(FLOAT *Tv, FLOAT *Buff, PFDEF Pf, int Sfc)
{
int i;
for (i = 0; i < SubFrLen; i++)
Tv[Sfc*SubFrLen+i]= Buff[PitchMax+Sfc*SubFrLen+i]*Pf.ScGn +
Buff[PitchMax+Sfc*SubFrLen+Pf.Indx+i]*Pf.Gain;
}
/*
**
** Function: Get_Ind()
**
** Description: Computes gains of the pitch postfilter.
** The gains are calculated using the cross correlation
** (forward or backward, the one with the greatest contribution)
** and the energy of the signal. Also, a test is performed on
** the prediction gain to see whether the pitch postfilter
** should be used or not.
**
**
**
** Links to text: Section 3.6
**
** Arguments:
**
** int Ind Pitch postfilter lag
** FLOAT Ten energy of the current subframe excitation vector
** FLOAT Ccr Crosscorrelation of the excitation
** FLOAT Enr Energy of the (backward or forward) "delayed" excitation
**
** Outputs: None
**
** Return value:
**
** PFDEF
** int Indx Pitch postfilter lag
** FLOAT Gain Pitch postfilter gain
** FLOAT ScGn Pitch postfilter scaling gain
**
*/
PFDEF Get_Ind(int Ind, FLOAT Ten, FLOAT Ccr, FLOAT Enr)
{
FLOAT Acc0,Acc1;
FLOAT Exp;
PFDEF Pf;
Pf.Indx = Ind;
/* Check valid gain > 2db */
Acc0 = (Ten * Enr)/(FLOAT)4.0;
Acc1 = Ccr * Ccr;
if (Acc1 > Acc0)
{
if (Ccr >= Enr)
Pf.Gain = LpfConstTable[WrkRate];
else
Pf.Gain = (Ccr/Enr) * LpfConstTable[WrkRate];
/* Compute scaling gain */
Exp = Ten + 2*Ccr*Pf.Gain + Pf.Gain*Pf.Gain*Enr;
if (fabs(Exp) < (FLOAT) FLT_MIN)
Pf.ScGn = (FLOAT)0.0;
else
Pf.ScGn = (FLOAT)sqrt(Ten/Exp);
}
else
{
Pf.Gain = (FLOAT)0.0;
Pf.ScGn = (FLOAT)1.0;
}
Pf.Gain = Pf.Gain * Pf.ScGn;
return Pf;
}
/*
**
** Function: Comp_Info()
**
** Description: Voiced/unvoiced classifier.
** It is based on a cross correlation maximization over the
** last 120 samples of the frame and with an index varying
** around the decoded pitch lag (from L-3 to L+3). Then the
** prediction gain is tested to declare the frame voiced or
** unvoiced.
**
** Links to text: Section 3.10.2
**
** Arguments:
**
** FLOAT *Buff decoded excitation
** int Olp Decoded pitch lag
** FLOAT *Gain
**
** Outputs: None
**
** Return value:
**
** Word16 Estimated pitch value
*/
Word16 Comp_Info(FLOAT *Buff, int Olp, FLOAT *Gain)
{
int i;
FLOAT Acc0;
FLOAT Tenr;
FLOAT Ccr,Enr;
int Indx;
if (Olp > (PitchMax-3))
Olp = (PitchMax-3);
Indx = Olp;
Ccr = (FLOAT)0.0;
for (i=Olp-3; i <= Olp+3; i++)
{
Acc0 = DotProd(&Buff[PitchMax+Frame-2*SubFrLen],
&Buff[PitchMax+Frame-2*SubFrLen-i],2*SubFrLen);
if (Acc0 > Ccr)
{
Ccr = Acc0;
Indx = i;
}
}
/* Compute target energy */
Tenr = DotProd(&Buff[PitchMax+Frame-2*SubFrLen],
&Buff[PitchMax+Frame-2*SubFrLen],2*SubFrLen);
*Gain = Tenr;
/* Compute best energy */
Enr = DotProd(&Buff[PitchMax+Frame-2*SubFrLen-Indx],
&Buff[PitchMax+Frame-2*SubFrLen-Indx],2*SubFrLen);
if (Ccr <= (FLOAT)0.0)
return 0;
if (((((FLOAT)0.125)*Enr*Tenr) - (Ccr*Ccr)) < (FLOAT)0.0)
return (Word16) Indx;
return 0;
}
/*
**
** Function: Regen()
**
** Description: Performs residual interpolation depending of the frame
** classification.
** If the frame is previously declared unvoiced, the excitation
** is regenerated using a random number generator. Otherwise
** a periodic excitation is generated with the period previously
** found.
**
** Links to text: Section 3.10.2
**
** Arguments:
**
** FLOAT *DataBuff current subframe decoded excitation
** FLOAT *Buff past decoded excitation
** Word16 Lag Decoded pitch lag from previous frame
** FLOAT Gain Interpolated gain from previous frames
** int Ecount Number of erased frames
** Word16 *Sd Random number used in unvoiced cases
**
** Outputs:
**
** Word16 *DataBuff current subframe decoded excitation
** Word16 *Buff updated past excitation
**
** Return value: None
**
*/
void Regen(FLOAT *DataBuff, FLOAT *Buff, Word16 Lag, FLOAT Gain,
int Ecount, Word16 *Sd)
{
int i;
/* Test for clearing */
if (Ecount >= ErrMaxNum)
{
for (i = 0; i < Frame; i++)
DataBuff[i] = (FLOAT)0.0;
for (i = 0; i < Frame+PitchMax; i++)
Buff[i] = (FLOAT)0.0;
}
else
{
/* Interpolate accordingly to the voicing estimation */
if (Lag != 0)
{
/* Voiced case */
for (i = 0; i < Frame; i++)
Buff[PitchMax+i] = Buff[PitchMax-Lag+i];
for (i = 0; i < Frame; i++)
DataBuff[i] = Buff[PitchMax+i] = Buff[PitchMax+i] * (FLOAT)0.75;
}
else
{
/* Unvoiced case */
for (i = 0; i < Frame; i++)
DataBuff[i] = Gain*(FLOAT)Rand_lbc(Sd)*((FLOAT)1.0/(FLOAT)32768.0);
/* Clear buffer to reset memory */
for (i = 0; i < Frame+PitchMax; i++)
Buff[i] = (FLOAT)0.0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -