?? decoder.cpp
字號:
temp16 >>= 1;
*ptr1++ = (short) (SubFrLen + (temp16 & 0x0001));
for (i=0; i<NbPulsBlk; i++) {
temp16 >>= 1;
*ptr_TabSign++= (float) 2. * (float)(temp16 & 0x0001) - (float) 1.;
}
}
/* Positions */
ptr_TabPos = TabPos;
for (i_subfr=0; i_subfr<SubFrames; i_subfr++) {
for (i=0; i<(SubFrLen/Sgrid); i++)
tmp[i] = (short) i;
temp16 = (SubFrLen/Sgrid);
for (i=0; i<Nb_puls[i_subfr]; i++) {
j = random_number(temp16, nRandom);
*ptr_TabPos++ = (short) (2 * tmp[(int)j] + offset[i_subfr]);
temp16--;
tmp[(int)j] = tmp[(int)temp16];
}
}
/*
* Compute fixed codebook gains
*/
ptr_TabPos = TabPos;
ptr_TabSign = TabSign;
curExc = DataExc;
i_subfr = 0;
for (iblk=0; iblk<SubFrames/2; iblk++) {
/* decode LTP only */
Decod_Acbk(curExc, &PrevExc[0], Line->Olp[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);
// ener_ltp = DotProd(curExc, curExc, SubFrLenD);
ener_ltp = DotProd10(curExc, curExc, SubFrLenD);
inter_exc = (float) 0.;
for (i=0; i<NbPulsBlk; i++) {
inter_exc += curExc[(int)ptr_TabPos[i]] * ptr_TabSign[i];
}
c = (ener_ltp - curGain * curGain * (float)SubFrLenD) * InvNbPulsBlk;
/*
* Solve EQ(X) = X**2 + 2 b0 X + c
*/
b0 = inter_exc * InvNbPulsBlk;
delta = b0 * b0 - c;
/* Case delta <= 0 */
if (delta <= (float) 0.) {
x1 = - b0;
}
/* Case delta > 0 */
else {
delta = (float) sqrt(delta);
x1 = - b0 + delta;
x2 = b0 + delta;
if (::fabs(x2) < fabs(x1))
x1 = - x2;
}
/* Update DataExc */
if (x1 > Gexc_Max)
x1 = Gexc_Max;
if (x1 < -Gexc_Max)
x1 = -Gexc_Max;
for (i=0; i<NbPulsBlk; i++) {
j = *ptr_TabPos++;
curExc[(int)j] += (x1 * (*ptr_TabSign++));
}
for (i=0; i<SubFrLenD; i++) {
if (curExc[i] > (float) 32766.5)
curExc[i] = (float) 32767.0;
else if (curExc[i] < (float) -32767.5)
curExc[i] = (float) -32768.0;
}
/* update PrevExc */
for (i=SubFrLenD; i<PitchMax; i++)
PrevExc[i-SubFrLenD] = PrevExc[i];
for (i=0; i<SubFrLenD; i++)
PrevExc[i+PitchMax-SubFrLenD] = curExc[i];
curExc += SubFrLenD;
i_subfr += 2;
} /* end of loop on LTP blocks */
return;
}
/*
**
** 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 CLanAudioDecoder::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_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 CLanAudioDecoder::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);
Lcr[0] = DotProd10(&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);
Lcr[1] = DotProd10(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen+Bindx],SubFrLen);
Lcr[2] = DotProd10(&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);
Lcr[3] = DotProd10(&Buff[PitchMax+Sfc*SubFrLen],
&Buff[PitchMax+Sfc*SubFrLen+Findx],SubFrLen);
Lcr[4] = DotProd10(&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: Synt()
**
** Description: Implements the decoder synthesis filter for a
** subframe. This is a tenth-order IIR filter.
**
** Links to text: Section 3.7
**
** Arguments:
**
** float Dpnt[] Pitch-postfiltered excitation for the current
** subframe ppf[n] (60 words)
** float Lpc[] Quantized LPC coefficients (10 words)
**
** Inputs:
**
** DecStat.SyntIirDl[] Synthesis filter memory from previous
** subframe (10 words)
**
** Outputs:
**
** float Dpnt[] Synthesized speech vector sy[n]
** DecStat.SyntIirDl[] Updated synthesis filter memory
**
** Return value: None
**
*/
void CLanAudioDecoder::Synt(float *Dpnt, float *Lpc)
{
int i,j;
float Acc0;
for (i=0 ; i < SubFrLen ; i++)
{
// Acc0 = Dpnt[i] + DotProd(Lpc,DecStat.SyntIirDl,LpcOrder);
Acc0 = Dpnt[i] + DotProd10s(Lpc,DecStat.SyntIirDl);
for (j=LpcOrder-1 ; j > 0 ; j--)
DecStat.SyntIirDl[j] = DecStat.SyntIirDl[j-1];
Dpnt[i] = DecStat.SyntIirDl[0] = Acc0;
}
}
/*
**
** Function: Spf()
**
** Description: Implements the formant postfilter for a
** subframe. The formant postfilter is a
** 10-pole, 10-zero ARMA filter followed by a
** single-tap tilt compensation filter.
**
** Links to text: Section 3.8
**
** Arguments:
**
** float Tv[] Synthesized speech vector sy[n] (60 words)
** float Lpc[] Quantized LPC coefficients (10 words)
** float Sen Input speech vector energy
**
** Inputs:
**
** DecStat.PostIirDl[] Postfilter IIR memory from previous subframe (10 words)
** DecStat.PostFirDl[] Postfilter FIR memory from previous subframe (10 words)
** DecStat.Park Previous value of compensation filter parameter
**
** Outputs:
**
** float Tv[] Postfiltered speech vector pf[n] (60 words)
** DecStat.PostIirDl[] Updated postfilter IIR memory
** DecStat.PostFirDl[] Updated postfilter FIR memory
** DecStat.Park Updated compensation filter parameter
**
** Return value: None
**
*/
float CLanAudioDecoder::Spf(float *Tv, float *Lpc)
{
int i,j;
float Acc0, Acc1;
float Sen;
float Tmp;
float FirCoef[LpcOrder];
float IirCoef[LpcOrder];
/*
* Compute ARMA coefficients. Compute the jth FIR coefficient by
* multiplying the jth quantized LPC coefficient by (0.65)^j.
* Compute the jth IIR coefficient by multiplying the jth quantized
* LPC coefficient by (0.75)^j. This emphasizes the formants in
* the frequency response.
*/
for (i=0; i < LpcOrder; i++)
{
FirCoef[i] = Lpc[i]*PostFiltZeroTable[i];
IirCoef[i] = Lpc[i]*PostFiltPoleTable[i];
}
/* Compute the first two autocorrelation coefficients R[0] and R[1] */
Acc0 = DotProd(Tv,&Tv[1],SubFrLen-1);
// Acc1 = DotProd(Tv,Tv,SubFrLen);
Acc1 = DotProd10(Tv,Tv,SubFrLen);
/* energy */
Sen = Acc1;
/*
* Compute the first-order partial correlation coefficient of the
* input speech vector.
*/
if (Acc1 > (float) FLT_MIN)
Tmp = Acc0/Acc1;
else
Tmp = (float)0.0;
/* Update the parkor memory */
DecStat.Park = (((float)0.75)*DecStat.Park + ((float)0.25)*Tmp);
Tmp = DecStat.Park*PreCoef;
/* Do the formant post filter */
for (i=0; i<SubFrLen; i++)
{
/* FIR Filter */
// Acc0 = Tv[i] - DotProd(FirCoef,DecStat.PostFirDl,LpcOrder);
Acc0 = Tv[i] - DotProd10s(FirCoef,DecStat.PostFirDl);
for (j=LpcOrder-1; j > 0; j--)
DecStat.PostFirDl[j] = DecStat.PostFirDl[j-1];
DecStat.PostFirDl[0] = Tv[i];
/* IIR Filter */
// Acc0 += DotProd(IirCoef,DecStat.PostIirDl,LpcOrder);
Acc0 += DotProd10s(IirCoef,DecStat.PostIirDl);
for (j=LpcOrder-1; j > 0; j--)
DecStat.PostIirDl[j] = DecStat.PostIirDl[j-1];
DecStat.PostIirDl[0] = Acc0;
/* Preemphasis */
Tv[i] = Acc0 + DecStat.PostIirDl[1] * Tmp;
}
return Sen;
}
/*
**
** Function: random_number()
**
** Description: returns a number randomly taken in [0, n]
** with np1 = n+1 at input
**
** Links to text:
**
** Arguments:
**
** short np1
** short *nRandom random generator status (input/output)
**
** Outputs:
**
** short *nRandom
**
** Return value: random number in [0, (np1-1)]
**
*/
short CLanAudioDecoder::random_number(short np1, short *nRandom)
{
short temp;
temp = (short) (Rand_lbc(nRandom) & 0x7FFF);
temp = (short) (((int)temp * (int)np1) >> 15);
return(temp);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -