⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder.cpp

📁 G711语音压缩源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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;
                else
                    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 + -