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

📄 decoder.cpp

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