📄 exc2.c
字号:
** Function: G_code()
**
** Description: Compute the gain of innovative code.
**
**
** Links to the text: Section 2.16
**
** Input arguments:
**
** FLOAT X[] Code target. (in Q0)
** FLOAT Y[] Filtered innovation code. (in Q12)
**
** Output:
**
** FLOAT *gain_q Gain of innovation code. (in Q0)
**
** Return value:
**
** int index of innovation code gain
**
*/
int G_code(FLOAT X[], FLOAT Y[], FLOAT *gain_q)
{
int i;
FLOAT xy, yy, gain_nq;
int gain;
FLOAT dist, dist_min;
/* Compute scalar product <X[],Y[]> */
xy = DotProd(X,Y,SubFrLen);
if (xy <= 0)
{
gain = 0;
*gain_q =FcbkGainTable[gain];
return(gain);
}
/* Compute scalar product <Y[],Y[]> */
yy = DotProd(Y,Y,SubFrLen);
if (yy > (FLOAT) FLT_MIN)
gain_nq = xy/yy;
else
gain_nq = (FLOAT)0.0;
gain = 0;
dist_min = (FLOAT)fabs(gain_nq - FcbkGainTable[0]);
for (i=1; i <NumOfGainLev; i++)
{
dist = (FLOAT)fabs(gain_nq - FcbkGainTable[i]);
if (dist < dist_min)
{
dist_min = dist;
gain = i;
}
}
*gain_q = FcbkGainTable[gain];
return(gain);
}
/*
**
** Function: search_T0()
**
** Description: Gets parameters of pitch synchronous filter
**
** Links to the text: Section 2.16
**
** Arguments:
**
** int T0 Decoded pitch lag
** int Gid Gain vector index in adaptive gain vector codebook
** FLOAT *gain_T0 Pitch synchronous gain
**
** Outputs:
**
** FLOAT *gain_T0 Pitch synchronous filter gain
**
** Return Value:
**
** int T0_mod Pitch synchronous filter lag
*/
int search_T0 (int T0, int Gid, FLOAT *gain_T0)
{
int T0_mod;
T0_mod = T0+epsi170[Gid];
*gain_T0 = gain170[Gid];
return(T0_mod);
}
/*
**
** Function: Update_Err()
**
** Description: Estimation of the excitation error associated
** to the excitation signal when it is disturbed at
** the decoder, the disturbing signal being filtered
** by the long term synthesis filters
** one value for (SubFrLen/2) samples
** Updates the table CodStat.Err
**
** Links to text: Section
**
** Arguments:
**
** int Olp Center value for pitch delay
** int AcLg Offset value for pitch delay
** int AcGn Index of Gain LT filter
**
** Outputs: None
**
** Return value: None
**
*/
void Update_Err(int Olp, int AcLg, int AcGn)
{
int i, iz, temp2;
int Lag;
FLOAT Worst1, Worst0, wtemp;
FLOAT beta,*ptr_tab;
Lag = Olp - Pstep + AcLg;
/* Select Quantization tables */
i = 0 ;
ptr_tab = tabgain85;
if ( WrkRate == Rate63 ) {
if ( Olp >= (SubFrLen-2) )
ptr_tab = tabgain170;
}
else {
ptr_tab = tabgain170;
}
beta = ptr_tab[(int)AcGn];
if (Lag <= (SubFrLen/2))
{
Worst0 = CodStat.Err[0]*beta + Err0;
Worst1 = Worst0;
}
else
{
iz = (int)(((Word32)Lag*1092L) >> 15);
temp2 = 30*(iz+1);
if (temp2 != Lag)
{
if (iz == 1)
{
Worst0 = CodStat.Err[0]*beta + Err0;
Worst1 = CodStat.Err[1]*beta + Err0;
if (Worst0 > Worst1)
Worst1 = Worst0;
else
Worst0 = Worst1;
}
else
{
wtemp = CodStat.Err[iz-1]*beta + Err0;
Worst0 = CodStat.Err[iz-2]*beta + Err0;
if (wtemp > Worst0)
Worst0 = wtemp;
Worst1 = CodStat.Err[iz]*beta + Err0;
if (wtemp > Worst1)
Worst1 = wtemp;
}
}
else
{
Worst0 = CodStat.Err[iz-1]*beta + Err0;
Worst1 = CodStat.Err[iz]*beta + Err0;
}
}
if (Worst0 > MAXV)
Worst0 = MAXV;
if (Worst1 > MAXV)
Worst1 = MAXV;
for (i=4; i>=2; i--)
CodStat.Err[i] = CodStat.Err[i-2];
CodStat.Err[0] = Worst0;
CodStat.Err[1] = Worst1;
return;
}
/*
**
** Function: Test_Err()
**
** Description: Check the error excitation maximum for
** the subframe and computes an index iTest used to
** calculate the maximum nb of filters (in Find_Acbk) :
** Bound = Min(Nmin + iTest x pas, Nmax) , with
** AcbkGainTable085 : pas = 2, Nmin = 51, Nmax = 85
** AcbkGainTable170 : pas = 4, Nmin = 93, Nmax = 170
** iTest depends on the relative difference between
** errmax and a fixed threshold
**
** Links to text: Section
**
** Arguments:
**
** Word16 Lag1 1st long term Lag of the tested zone
** Word16 Lag2 2nd long term Lag of the tested zone
**
** Outputs: None
**
** Return value:
** Word16 index iTest used to compute Acbk number of filters
*/
int Test_Err(int Lag1, int Lag2)
{
int i, i1, i2;
int zone1, zone2, iTest;
FLOAT Err_max;
i2 = Lag2 + ClPitchOrd/2;
zone2 = i2/30;
i1 = - SubFrLen + 1 + Lag1 - ClPitchOrd/2;
if (i1 <= 0)
i1 = 1;
zone1 = i1/30;
Err_max = (FLOAT)-1.0;
for (i=zone2; i>=zone1; i--)
{
if (CodStat.Err[i] > Err_max)
Err_max = CodStat.Err[i];
}
if ((Err_max > ThreshErr) || (CodStat.SinDet < 0 ) )
{
iTest = 0;
}
else
{
iTest = (Word16)(ThreshErr - Err_max);
}
return(iTest);
}
/*
**
** Function: Find_Acbk()
**
** Description: Computation of adaptive codebook contribution in
** closed-loop around open-loop pitch lag (subframes 0 & 2)
** around the previous subframe closed-loop pitch lag
** (subframes 1 & 3). For subframes 0 & 2, the pitch lag is
** encoded whereas for subframes 1 & 3, only the difference
** with the previous value is encoded (-1, 0, +1 or +2).
** The pitch predictor gains are quantized using one of two
** codebooks (85 entries or 170 entries) depending on the
** rate and on the pitch lag value.
** Finally, the contribution of the pitch predictor is decoded
** and subtracted to obtain the residual signal.
**
** Links to text: Section 2.14
**
** Arguments:
**
** FLOAT *Tv Target vector
** FLOAT *ImpResp Impulse response of the combined filter
** FLOAT *PrevExc Previous excitation vector
** LINEDEF *Line Contains pitch parameters (open/closed loop lag, gain)
** int Sfc Subframe index
**
** Outputs:
**
** FLOAT *Tv Residual vector
** LINEDEF *Line Contains pitch related parameters (closed loop lag, gain)
**
** Return value: None
**
*/
void Find_Acbk(FLOAT *Tv, FLOAT *ImpResp, FLOAT *PrevExc,
LINEDEF *Line, int Sfc)
{
int i,j,k,l;
FLOAT Acc0,Max;
FLOAT RezBuf[SubFrLen+ClPitchOrd-1];
FLOAT FltBuf[ClPitchOrd][SubFrLen];
FLOAT CorVct[4*(2*ClPitchOrd + ClPitchOrd*(ClPitchOrd-1)/2)];
FLOAT *lPnt;
FLOAT *sPnt;
int Olp,Lid,Gid,Hb;
int Bound[2];
int Lag1, Lag2;
int off_filt;
Olp = (*Line).Olp[Sfc>>1];
Lid = Pstep;
Gid = 0;
Hb = 3 + (Sfc & 1);
/* For even frames only */
if ((Sfc & 1) == 0)
{
if (Olp == PitchMin)
Olp++;
if (Olp > (PitchMax-5))
Olp = PitchMax-5;
}
lPnt = CorVct;
for (k=0; k < Hb; k++)
{
/* Get residual from the exitation buffer */
Get_Rez(RezBuf, PrevExc, Olp-Pstep+k);
/* Filter the last one (ClPitchOrd-1) using the impulse responce */
for (i=0; i < SubFrLen; i++)
{
Acc0 = (FLOAT)0.0;
for (j=0; j <= i; j++)
Acc0 += RezBuf[ClPitchOrd-1+j]*ImpResp[i-j];
FltBuf[ClPitchOrd-1][i] = Acc0;
}
/* Update the others (ClPitchOrd-2 down to 0) */
for (i=ClPitchOrd-2; i >= 0; i --)
{
FltBuf[i][0] = RezBuf[i];
for (j = 1; j < SubFrLen; j++)
FltBuf[i][j] = RezBuf[i]*ImpResp[j] + FltBuf[i+1][j-1];
}
/* Compute the cross products with the signal */
for (i=0; i < ClPitchOrd; i++)
*lPnt++ = DotProd(Tv, FltBuf[i], SubFrLen);
/* Compute the energies */
for (i=0; i < ClPitchOrd; i++)
*lPnt++ = ((FLOAT)0.5)*DotProd(FltBuf[i], FltBuf[i], SubFrLen);
/* Compute the between crosses */
for (i=1; i < ClPitchOrd; i++)
for (j = 0; j < i; j++)
*lPnt++ = DotProd(FltBuf[i], FltBuf[j], SubFrLen);
}
/* Test potential error */
Lag1 = Olp - Pstep;
Lag2 = Olp - Pstep + Hb - 1;
off_filt = Test_Err(Lag1, Lag2);
Bound[0] = NbFilt085_min + (off_filt << 2);
if (Bound[0] > NbFilt085)
Bound[0] = NbFilt085;
Bound[1] = NbFilt170_min + (off_filt << 3);
if (Bound[1] > NbFilt170)
Bound[1] = NbFilt170;
Max = (FLOAT)0.0;
for (k=0; k < Hb; k++)
{
/* Select Quantization table */
l = 0;
if (WrkRate == Rate63)
{
if ((Sfc & 1) == 0)
{
if (Olp-Pstep+k >= SubFrLen-2)
l = 1;
}
else
{
if (Olp >= SubFrLen-2)
l = 1;
}
}
else
l = 1;
/* Search for maximum */
sPnt = AcbkGainTablePtr[l];
for (i=0; i < Bound[l]; i++)
{
Acc0 = DotProd(&CorVct[k*20],sPnt,20);
sPnt += 20;
if (Acc0 > Max)
{
Max = Acc0;
Gid = i;
Lid = k;
}
}
}
/* Modify Olp for even sub frames */
if ((Sfc & 1) == 0)
{
Olp = Olp - Pstep + Lid;
Lid = Pstep;
}
/* Save Lag, Gain and Olp */
(*Line).Sfs[Sfc].AcLg = Lid;
(*Line).Sfs[Sfc].AcGn = Gid;
(*Line).Olp[Sfc>>1] = Olp;
/* Decode the Acbk contribution and subtract it */
Decod_Acbk(RezBuf, PrevExc, Olp, Lid, Gid);
for (i=0; i < SubFrLen; i++)
{
Acc0 = Tv[i];
for (j=0; j <= i; j++)
Acc0 -= RezBuf[j]*ImpResp[i-j];
Tv[i] = Acc0;
}
}
/*
**
** Function: Get_Rez()
**
** Description: Gets delayed contribution from the previous excitation
** vector.
**
** Links to text: Sections 2.14, 2.18 & 3.4
**
** Arguments:
**
** FLOAT *Tv delayed excitation
** FLOAT *PrevExc Previous excitation vector
** int Lag Closed loop pitch lag
**
** Outputs:
**
** FLOAT *Tv delayed excitation
**
** Return value: None
**
*/
void Get_Rez(FLOAT *Tv, FLOAT *PrevExc, int Lag)
{
int i;
for (i=0; i < ClPitchOrd/2; i++)
Tv[i] = PrevExc[PitchMax - Lag - ClPitchOrd/2 + i];
for (i=0; i < SubFrLen+ClPitchOrd/2; i++)
Tv[ClPitchOrd/2+i] = PrevExc[PitchMax - Lag + i%Lag];
}
/*
**
** Function: Decod_Acbk()
**
** Description: Computes the adaptive codebook contribution from the previous
** excitation vector.
** With the gain index, the closed loop pitch lag, the jitter
** which when added to this pitch lag gives the actual closed
** loop value, and after having selected the proper codebook,
** the pitch contribution is reconstructed using the previous
** excitation buffer.
**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -