?? encoder.cpp
字號(hào):
/* third pulse loop */
for (i2 = 4; i2 < SubFrLen2; i2 +=STEP)
{
ps2 = ps1 + Dn[i2];
ps2a = ps1a + Dn[i2+1];
alp2 = alp1 + *ptr_ri2i2++ + *ptr_ri0i2++ + *ptr_ri1i2++;
/* Decide the shift */
shift = 0;
if (ps2a > ps2)
{
shift = 1;
ps2 = ps2a;
}
/* Test threshold */
if (ps2 > thres)
{
/* Init. pointers that depend on 4th loop */
ptr_ri3i3 = rri3i3;
/* 4th pulse loop */
for (i3 = 6; i3 < SubFrLen2; i3 +=STEP)
{
ps3 = ps2 + Dn[i3+shift];
alp3 = alp2 + *ptr_ri3i3++ +
*ptr_ri0i3++ + *ptr_ri1i3++ + *ptr_ri2i3++;
ps3c = ps3 * ps3;
if ((ps3c * alpha) > (psc * alp3))
{
psc = ps3c;
alpha = alp3;
ip0 = i0;
ip1 = i1;
ip2 = i2;
ip3 = i3;
shif = shift;
}
}
time--;
/* Maximum time finish */
if (time <= 0)
goto end_search;
ptr_ri0i3 -= NB_POS;
ptr_ri1i3 -= NB_POS;
}
else
ptr_ri2i3 += NB_POS;
}
ptr_ri0i2 -= NB_POS;
ptr_ri1i3 += NB_POS;
}
ptr_ri0i2 += NB_POS;
ptr_ri0i3 += NB_POS;
}
end_search:
extra = time;
/* Set the sign of impulses */
i0 = p_sign[(ip0 >> 1)];
i1 = p_sign[(ip1 >> 1)];
i2 = p_sign[(ip2 >> 1)];
i3 = p_sign[(ip3 >> 1)];
/* Find the codeword corresponding to the selected positions */
for (i=0; i<SubFrLen; i++)
cod[i] = (float)0.0;
if (shif > 0)
{
ip0++;
ip1++;
ip2++;
ip3++;
}
cod[ip0] = (float)i0;
cod[ip1] = (float)i1;
if (ip2<SubFrLen)
cod[ip2] = (float)i2;
if (ip3<SubFrLen)
cod[ip3] = (float)i3;
/* find the filtered codeword */
for (i=0; i < SubFrLen; i++)
y[i] = (float)0.0;
if (i0 > 0)
for (i=ip0, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] + h[j];
else
for (i=ip0, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] - h[j];
if (i1 > 0)
for (i=ip1, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] + h[j];
else
for (i=ip1, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] - h[j];
if (ip2<SubFrLen)
{
if (i2 > 0)
for (i=ip2, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] + h[j];
else
for (i=ip2, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] - h[j];
}
if (ip3<SubFrLen)
{
if (i3 > 0)
for (i=ip3, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] + h[j];
else
for (i=ip3, j=0; i<SubFrLen; i++, j++)
y[i] = y[i] - h[j];
}
*code_shift = shif;
*sign = 0;
if (i0 > 0)
*sign += 1;
if (i1 > 0)
*sign += 2;
if (i2 > 0)
*sign += 4;
if (i3 > 0)
*sign += 8;
i = ((ip3 >> 3) << 9) + ((ip2 >> 3) << 6) + ((ip1 >> 3) << 3) + (ip0 >> 3);
return i;
}
/*
**
** Function: ACELP_LBC_code()
**
** Description: Find Algebraic codebook for low bit rate LBC encoder
**
** Links to text: Section 2.16
**
** Arguments:
**
** float X[] Target vector. (in Q0)
** float h[] Impulse response. (in Q12)
** int T0 Pitch period.
** float code[] Innovative vector. (in Q12)
** int gain Innovative vector gain. (in Q0)
** int sign Signs of the 4 pulses.
** int shift Shift of the innovative vector
** float gain_T0 Gain for pitch synchronous fiter
**
** Inputs :
**
** float X[] Target vector. (in Q0)
** float h[] Impulse response. (in Q12)
** int T0 Pitch period.
** float gain_T0 Gain for pitch synchronous fiter
**
** Outputs:
**
** float code[] Innovative vector. (in Q12)
** int gain Innovative vector gain. (in Q0)
** int sign Signs of the 4 pulses.
** int shift Shift of the innovative vector.
**
** Return value:
**
** int index Innovative codebook index
**
*/
int CLanAudioEncoder::ACELP_LBC_code(float X[], float h[], int T0, float code[],
int *ind_gain, int *shift, int *sign, float gain_T0)
{
int i, index;
float gain_q;
float Dn[SubFrLen2], tmp_code[SubFrLen2];
float rr[DIM_RR];
/* Include fixed-gain pitch contribution into impulse resp. h[] */
if (T0 < SubFrLen-2)
for (i = T0; i < SubFrLen; i++)
h[i] += gain_T0*h[i-T0];
/* Compute correlations of h[] needed for the codebook search */
Cor_h(h, rr);
/* Compute correlation of target vector with impulse response. */
Cor_h_X(h, X, Dn);
/* Find codebook index */
index = D4i64_LBC(Dn, rr, h, tmp_code, rr, shift, sign);
/* Compute innovation vector gain. */
/* Include fixed-gain pitch contribution into code[]. */
*ind_gain = G_code(X, rr, &gain_q);
for (i=0; i < SubFrLen; i++)
code[i] = tmp_code[i]*gain_q;
if (T0 < SubFrLen-2)
for (i=T0; i < SubFrLen; i++)
code[i] += code[i-T0]*gain_T0;
return index;
}
/*
**
** 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 CLanAudioEncoder::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)(((int)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:
**
** short Lag1 1st long term Lag of the tested zone
** short Lag2 2nd long term Lag of the tested zone
**
** Outputs: None
**
** Return value:
** short index iTest used to compute Acbk number of filters
*/
int CLanAudioEncoder::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 = (short)(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 CLanAudioEncoder::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 = 2; ;// + (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 = RezBuf[ClPitchOrd-1+i];
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++)
//DotProd10 *lPnt++ = DotProd(Tv, FltBuf[i], SubFrLen);
*lPnt++ = DotProd10(Tv, FltBuf[i], SubFrLen);
/* Compute the energies */
for (i=0; i < ClPitchOrd; i++)
//DotProd10 *lPnt++ = ((float)0.5)*DotProd(FltBuf[i], FltBuf[i], SubFrLen);
*lPnt++ = ((float)0.5)*DotProd10(FltBuf[i], FltBuf[i], SubFrLen);
/* Compute the between crosses */
for (i=1; i < ClPitchOrd; i++)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -