?? decoder.cpp
字號:
Lsp_Int( QntLpc, DecCng.LspSid, DecStat.PrevLsp );
/* Copy the LSP vector for the next frame */
for ( i = 0 ; i < LpcOrder ; i ++ )
DecStat.PrevLsp[i] = DecCng.LspSid[i];
return;
}
/*
**
** Function: Line_Unpk()
**
** Description: unpacking of bitstream, gets coding parameters for a frame
**
** Links to text: Section 4
**
** Arguments:
**
** char *Vinp bitstream chars
** short *Ftyp
** short Crc
**
** Outputs:
**
** short *Ftyp
**
** Return value:
**
** LINEDEF coded parameters
** short Crc
** int LspId
** short Olp[SubFrames/2]
** SFSDEF Sfs[SubFrames]
**
*/
LINEDEF CLanAudioDecoder::Line_Unpk(char *Vinp, short *Ftyp, short Crc)
{
int i ;
short BitStream[192] ;
short *Bsp = BitStream ;
LINEDEF Line ;
int Temp ;
short Info ;
short Bound_AcGn ;
Line.Crc = Crc;
if (Crc != 0)
return Line;
/* Unpack the byte info to BitStream vector */
for ( i = 0 ; i < 192 ; i ++ )
BitStream[i] = (short) (( Vinp[i>>3] >> (i & (short)0x0007) ) & 1);
/* Decode the first two bits */
Info = (short)Ser2Par( &Bsp, 2 ) ;
if (Info == 3) {
*Ftyp = 0;
Line.LspId = 0L; /* Dummy : to avoid Borland C3.1 warning */
return Line;
}
/* Decode the LspId */
Line.LspId = Ser2Par( &Bsp, 24 ) ;
if (Info == 2) {
/* Decode the Noise Gain */
Line.Sfs[0].Mamp = (short)Ser2Par( &Bsp, 6);
*Ftyp = 2;
return Line ;
}
/*
* Decode the common information to both rates
*/
*Ftyp = 1;
/* Decode the bit-rate */
WrkRate = (Info == 0) ? Rate63 : Rate53;
/* Decode the adaptive codebook lags */
Temp = Ser2Par( &Bsp, 7 ) ;
/* Test if forbidden code */
if (Temp <= 123) {
Line.Olp[0] = (short) Temp + (short)PitchMin ;
}
else {
/* transmission error */
Line.Crc = 1;
return Line;
}
Line.Sfs[1].AcLg = (short) Ser2Par( &Bsp, 2 ) ;
Temp = Ser2Par( &Bsp, 7 ) ;
/* Test if forbidden code */
if (Temp <= 123) {
Line.Olp[1] = (short) Temp + (short)PitchMin ;
}
else {
/* transmission error */
Line.Crc = 1;
return Line ;
}
Line.Sfs[3].AcLg = (short) Ser2Par( &Bsp, 2 ) ;
Line.Sfs[0].AcLg = 1 ;
Line.Sfs[2].AcLg = 1 ;
/* Decode the combined gains accordingly to the rate */
for ( i = 0 ; i < SubFrames ; i ++ ) {
Temp = Ser2Par( &Bsp, 12 ) ;
Line.Sfs[i].Tran = 0 ;
Bound_AcGn = NbFilt170 ;
if ( (WrkRate == Rate63) && (Line.Olp[i>>1] < (SubFrLen-2) ) ) {
Line.Sfs[i].Tran = (short)(Temp >> 11) ;
Temp &= 0x000007ffL ;
Bound_AcGn = NbFilt085 ;
}
Line.Sfs[i].AcGn = (short)(Temp / (short)NumOfGainLev) ;
if (Line.Sfs[i].AcGn < Bound_AcGn ) {
Line.Sfs[i].Mamp = (short)(Temp % (short)NumOfGainLev) ;
}
else {
/* error detected */
Line.Crc = 1;
return Line ;
}
}
/* Decode the grids */
for ( i = 0 ; i < SubFrames ; i ++ )
Line.Sfs[i].Grid = *Bsp ++ ;
if (Info == 0) {
/* Skip the reserved bit */
Bsp ++ ;
/* Decode 13 bit combined position index */
Temp = Ser2Par( &Bsp, 13 ) ;
Line.Sfs[0].Ppos = ( Temp/90 ) / 9 ;
Line.Sfs[1].Ppos = ( Temp/90 ) % 9 ;
Line.Sfs[2].Ppos = ( Temp%90 ) / 9 ;
Line.Sfs[3].Ppos = ( Temp%90 ) % 9 ;
/* Decode all the pulse positions */
Line.Sfs[0].Ppos = ( Line.Sfs[0].Ppos << 16 ) + Ser2Par( &Bsp, 16 ) ;
Line.Sfs[1].Ppos = ( Line.Sfs[1].Ppos << 14 ) + Ser2Par( &Bsp, 14 ) ;
Line.Sfs[2].Ppos = ( Line.Sfs[2].Ppos << 16 ) + Ser2Par( &Bsp, 16 ) ;
Line.Sfs[3].Ppos = ( Line.Sfs[3].Ppos << 14 ) + Ser2Par( &Bsp, 14 ) ;
/* Decode pulse amplitudes */
Line.Sfs[0].Pamp = (short)Ser2Par( &Bsp, 6 ) ;
Line.Sfs[1].Pamp = (short)Ser2Par( &Bsp, 5 ) ;
Line.Sfs[2].Pamp = (short)Ser2Par( &Bsp, 6 ) ;
Line.Sfs[3].Pamp = (short)Ser2Par( &Bsp, 5 ) ;
}
else {
/* Decode the positions */
for ( i = 0 ; i < SubFrames ; i ++ )
Line.Sfs[i].Ppos = Ser2Par( &Bsp, 12 ) ;
/* Decode the amplitudes */
for ( i = 0 ; i < SubFrames ; i ++ )
Line.Sfs[i].Pamp = (short)Ser2Par( &Bsp, 4 ) ;
}
return Line;
}
/*
**
** Function: Scale()
**
** Description: Postfilter gain scaling
**
** Links to text: Section 3.9
**
** Arguments:
**
** float *Tv
** float Sen
**
** Inputs:
**
** float DecStat.Gain
**
** Outputs:
**
** float *Tv
**
** Return value: None
**
*/
void CLanAudioDecoder::Scale(float *Tv, float Sen)
{
int i;
float Acc1;
float SfGain;
// Acc1 = DotProd(Tv,Tv,SubFrLen);
Acc1 = DotProd10(Tv,Tv,SubFrLen);
if (Acc1 > (float) FLT_MIN)
SfGain = (float) ::sqrt(Sen/Acc1) * (float)0.0625;
else
SfGain = (float)0.0625;
/*
* Update gain and scale the Postfiltered Signal
*/
for (i=0; i < SubFrLen; i++)
{
DecStat.Gain = (float)0.9375*DecStat.Gain + SfGain;
Tv[i] = (float)1.0625*Tv[i]*DecStat.Gain;
}
}
/*
**
** Function: Fcbk_Unpk()
**
** Description: Decoding of the fixed codebook excitation for both rates.
** Gains, pulse positions, grid position (odd or even), signs
** are decoded and used to reconstruct the excitation.
**
** Links to text: Section 2.17 & 3.5
**
** Arguments:
**
** float *Tv Decoded excitation vector
** SFSDEF Sfs Encoded parameters of the excitation (for one subframe)
** int Olp Closed loop adaptive pitch lag
** int Sfc Subframe index
**
** Outputs:
**
** float *Tv Decoded excitation vector
**
** Return value: None
**
*/
void CLanAudioDecoder::Fcbk_Unpk(float *Tv, SFSDEF Sfs, int Olp, int Sfc)
{
int i,j,Np;
float Tv_tmp[SubFrLen+4];
float acelp_gain,gain_T0;
int acelp_sign, acelp_shift, acelp_pos;
int offset, ipos, T0_acelp;
int Acc0;
switch(WrkRate)
{
case Rate63:
{
Np = Nb_puls[Sfc];
for (i=0; i < SubFrLen; i++)
Tv[i] = (float)0.0;
if (Sfs.Ppos >= MaxPosTable[Sfc])
return;
/* Decode the amplitudes and positions */
j = MaxPulseNum - Np;
Acc0 = Sfs.Ppos;
for (i = 0; i < SubFrLen/Sgrid; i++)
{
Acc0 -= CombinatorialTable[j][i];
if (Acc0 < (int) 0)
{
Acc0 += CombinatorialTable[j][i];
j++;
if ((Sfs.Pamp & (1 << (MaxPulseNum-j))) != 0)
Tv[Sfs.Grid + Sgrid*i] = -FcbkGainTable[Sfs.Mamp];
else
Tv[Sfs.Grid + Sgrid*i] = FcbkGainTable[Sfs.Mamp];
if (j == MaxPulseNum)
break;
}
}
if (Sfs.Tran == 1)
Gen_Trn(Tv, Tv, Olp);
break;
}
case Rate53:
{
for (i = 0; i < SubFrLen+4; i++)
Tv_tmp[i] = (float)0.0;
acelp_gain = FcbkGainTable[Sfs.Mamp];
acelp_shift = Sfs.Grid;
acelp_sign = Sfs.Pamp;
acelp_pos = (int)Sfs.Ppos;
offset = 0;
for (i=0; i<4; i++)
{
ipos = (acelp_pos & 7);
ipos = (ipos << 3) + acelp_shift + offset;
if ((acelp_sign & 1)== 1)
Tv_tmp[ipos] = acelp_gain;
Tv_tmp[ipos] = -acelp_gain;
offset += 2;
acelp_pos = acelp_pos >> 3;
acelp_sign = acelp_sign >> 1;
}
for (i = 0; i < SubFrLen; i++)
Tv[i] = Tv_tmp[i];
T0_acelp = search_T0( (Olp-1+Sfs.AcLg), Sfs.AcGn, &gain_T0);
if (T0_acelp < SubFrLen-2)
{
for (i = T0_acelp; i < SubFrLen; i++)
Tv[i] += Tv[i-T0_acelp]*gain_T0;
}
break;
}
}
return;
}
/*
**
** 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.
**
** 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 CLanAudioDecoder::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++)
//DotProd5s Tv[i] = DotProd(&RezBuf[i], sPnt, ClPitchOrd);
Tv[i] = DotProd5s(&RezBuf[i], sPnt);
}
/*
**
** 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:
**
** float curGain current average gain to match
** float *PrevExc previous/current excitation (updated)
** float *DataExc current frame excitation
** short *nRandom random generator status (input/output)
** LINEDEF *Line
**
** Outputs:
**
** float *PrevExc
** float *DataExc
** short *nRandom
** LINEDEF *Line
**
** Return value: None
**
*/
void CLanAudioDecoder::Calc_Exc_Rand(float curGain, float *PrevExc, float *DataExc,
short *nRandom, LINEDEF *Line)
{
int i, i_subfr, iblk;
short temp16;
short j;
short TabPos[2*NbPulsBlk], *ptr_TabPos;
float TabSign[2*NbPulsBlk], *ptr_TabSign;
short *ptr1;
float *curExc;
float x1, x2, ener_ltp, inter_exc, delta, b0, c;
short tmp[SubFrLen/Sgrid];
short offset[SubFrames];
/*
* generate LTP codes
*/
Line->Olp[0] = random_number(21, nRandom) + 123;
Line->Olp[1] = random_number(21, nRandom) + 123;
for (i_subfr=0; i_subfr<SubFrames; i_subfr++) { /* in [1, NbFilt] */
Line->Sfs[i_subfr].AcGn = random_number(NbFilt, nRandom) + (short)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; iblk<SubFrames/2; iblk++) {
temp16 = random_number((short) (1 << (NbPulsBlk+2)), nRandom);
*ptr1++ = (short) (temp16 & 0x0001);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -