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

📄 encoder.cpp

📁 G711语音压缩源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         * versus reference filter
         */
        if (!LpcDiff(CodCng.RC, CodCng.Acf, *CodCng.Ener)) {
            *Ftyp = 2;  /* transmit SID frame */
        }
        else {
            i = ::abs((int)(curQGain - CodCng.IRef));
            if (i > ThreshGain) {
                *Ftyp = 2;
            }
            else {
                /* no transmission */
                *Ftyp = 0;
            }
        }
    }

    /*
     * If SID frame : Compute SID filter
     */
    if (*Ftyp == 2) {

        /*
         * Evaluates local stationnarity :
         * Computes difference between current filter and past average filter
         * if signal not locally stationary SID filter = current filter
         * else SID filter = past average filter
         */

        /* Compute past average filter */
        ComputePastAvFilter(CodCng.SidLpc) ;

        /* If adaptation enabled, fill noise filter */
        if ( !VadStat.Aen ) {
            for (i = 0; i < LpcOrder; i++)
                VadStat.NLpc[i] = CodCng.SidLpc[i];
        }

        /* Compute autocorr. of past average filter coefficients */
        CalcRC(CodCng.SidLpc , CodCng.RC);

        if (!LpcDiff(CodCng.RC, CodCng.Acf, *CodCng.Ener)) {
            for (i=0; i<LpcOrder; i++) {
                CodCng.SidLpc[i] = curCoeff[i];
            }
            CalcRC(curCoeff, CodCng.RC);
        }

        /*
         * Compute SID frame codes
         */

        /* Compute LspSid */
        AtoLsp(CodCng.LspSid, CodCng.SidLpc, CodStat.PrevLsp);
        Line->LspId = Lsp_Qnt(CodCng.LspSid, CodStat.PrevLsp);
        Lsp_Inq(CodCng.LspSid, CodStat.PrevLsp, Line->LspId, 0);

        Line->Sfs[0].Mamp = curQGain;
        CodCng.IRef = curQGain;
        CodCng.SidGain = Dec_SidGain(CodCng.IRef);

    } /* end of Ftyp=2 case (SID frame) */

    /*
     * Compute new excitation
     */
    if (CodCng.PastFtyp == 1) {
        CodCng.CurGain = CodCng.SidGain;
    }
    else {
        CodCng.CurGain = (float)0.875 * CodCng.CurGain + (float)0.125 * CodCng.SidGain;
    }
    Calc_Exc_Rand(CodCng.CurGain, CodStat.PrevExc, DataExc,
                                                &CodCng.RandSeed, Line);

    /*
     * Interpolate LSPs and update PrevLsp
     */
    Lsp_Int(QntLpc, CodCng.LspSid, CodStat.PrevLsp);
    for (i=0; i < LpcOrder ; i++) {
        CodStat.PrevLsp[i] = CodCng.LspSid[i];
    }

    /*
     * Output & save frame type info
     */
    CodCng.PastFtyp = *Ftyp;
    return;
}

BOOL CLanAudioEncoder::Comp_Vad(float *Dpnt)
{
    int     i, j, bexp;

    float   Acc0, Frac, Thresh, Enr;
    float   Temp;
    int  Tm1, Tm2;
    short  Minp;

    BOOL    VadState = TRUE;

    static  float  ScfTab[11] = {
        (float)  9170.0,
        (float)  9170.0,
        (float)  9170.0,
        (float)  9170.0,
        (float) 10289.0,
        (float) 11544.0,
        (float) 12953.0,
        (float) 14533.0,
        (float) 16306.0,
        (float) 18296.0,
        (float) 20529.0
    };

    if ( !UseVx )
        return VadState ;

    /* Find Minimum pitch period */
    Minp = (short) PitchMax ;
    for ( i = 0 ; i < 4 ; i ++ ) {
        if ( Minp > VadStat.Polp[i] )
            Minp = VadStat.Polp[i] ;
    }

    /* Check that all are multiplies of the minimum */
    Tm2 = 0 ;
    for ( i = 0 ; i < 4 ; i ++ ) {
        Tm1 = Minp ;
        for ( j = 0 ; j < 8 ; j ++ ) {
            if (abs((int)(Tm1 - VadStat.Polp[i])) <= 3)
                Tm2++ ;
            Tm1 += Minp;
        }
    }

    /* Update adaptation enable counter if not periodic and not sine */
    if ( (Tm2 == 4) || (CodStat.SinDet < 0) )
        VadStat.Aen += 2 ;
    else
        VadStat.Aen -- ;

    /* Clip it */
    if ( VadStat.Aen > 6 )
        VadStat.Aen = 6 ;
    if ( VadStat.Aen < 0 )
        VadStat.Aen = 0 ;

    /* Inverse filter the data */
    Enr = (float) 0.0;
    for ( i = SubFrLen ; i < Frame ; i ++ ) {
        Acc0 = Dpnt[i];
        for ( j = 0 ; j < LpcOrder ; j ++ )
            Acc0 -= Dpnt[i-j-1] * VadStat.NLpc[j];
        Enr += Acc0 * Acc0;
    }

    /* Scale the rezidual energy.
     * Multiplication by 0.5 yields a value approximately equal
     * to the corresponding computation in the fixed point code.
     * Thus the same bounds, computations and thresholds as in the
     * fixed point code can be used below.
     */
    Enr = (float)0.5 * (Enr / (float)180.0);

    /* Clip noise level in any case */
    if ( VadStat.Nlev > VadStat.Penr ) {
        VadStat.Nlev = (float)0.25 * VadStat.Nlev + (float)0.75 * VadStat.Penr;
    }

    /* Update the noise level, if adaptation is enabled */
    if ( !VadStat.Aen ) {
        VadStat.Nlev *= (float)33.0 / (float)32.0;
    }
    /* Decay Nlev by small amount */
    else {
        VadStat.Nlev *= (float)2047.0 / (float)2048.0;
    }

    /* Update previous energy */
    VadStat.Penr = Enr;

    /* CLip Noise Level */
    if (VadStat.Nlev < (float) 128.0)
        VadStat.Nlev = (float) 128.0;
    if (VadStat.Nlev > (float) 131071.0)
        VadStat.Nlev = (float) 131071.0;

    /* Compute the threshold */
    Frac = (float) frexp(VadStat.Nlev, &bexp);
    /* VadStat.Nlev = Frac x 2**bexp, where Frac = 0.1bbbbbb...., binary.
     * Isolate the 6 fractional bits 'b', Temp = 0.bbbbbb.
     */
    Temp = ((float)floor(Frac * (float)128.0) / (float)64.0) - (float)1.0;
    Temp = ((float)1.0 - Temp) * ScfTab[18 - bexp] + Temp * ScfTab[17 - bexp];
    Thresh = (Temp * VadStat.Nlev) / (float)4096.0;

    /* Compare with the threshold */
    if (Thresh > Enr)
        VadState = FALSE ;

    /* Do the various counters */
    if ( VadState ) {
        VadStat.Vcnt ++ ;
        VadStat.Hcnt ++ ;
    }
    else {
        VadStat.Vcnt -- ;
        if ( VadStat.Vcnt < 0 )
            VadStat.Vcnt = 0 ;
    }

    if ( VadStat.Vcnt >= 2 ) {
        VadStat.Hcnt = 6 ;
        if (VadStat.Vcnt >= 3)
            VadStat.Vcnt = 3;
    }

    if ( VadStat.Hcnt ) {
        VadState = TRUE ;
        if ( VadStat.Vcnt == 0 )
            VadStat.Hcnt -- ;
    }

    /* Update Periodicy detector */
    VadStat.Polp[0] = VadStat.Polp[2] ;
    VadStat.Polp[1] = VadStat.Polp[3] ;

    return VadState ;
}

/*
**
** Function:           Update_Acf()
**
** Description:        Computes & Stores sums of subframe-acfs
**
** Links to text:
**
** Arguments:
**
**  float  *Acf_sf     sets of subframes Acfs of current frame
**
** Output :            None
**
** Return value:       None
**
*/
void CLanAudioEncoder::Update_Acf(float *Acf_sf)
{
    int i, i_subfr;
    float *ptr1, *ptr2;

    /* Update Acf */
    ptr2 = CodCng.Acf + SizAcf;
    ptr1 = ptr2 - LpcOrderP1;
    for (i=LpcOrderP1; i<SizAcf; i++)
        *(--ptr2) = *(--ptr1);

    /* Compute current sum of acfs */
    for (i=0; i<= LpcOrder; i++)
        CodCng.Acf[i] = (float) 0.0;

    ptr2 = Acf_sf;
    for (i_subfr=0; i_subfr<SubFrames; i_subfr++) {
        for (i=0; i <= LpcOrder; i++) {
            CodCng.Acf[i] += *ptr2++;
        }
    }
}

/*
**
** Function:           ComputePastAvFilter()
**
** Description:        Computes past average filter
**
** Links to text:
**
** Argument:
**
**   float *Coeff      set of LPC coefficients
**
** Output:
**
**   float *Coeff
**
** Return value:       None
**
*/
void CLanAudioEncoder::ComputePastAvFilter(float *Coeff)
{
    int i, j;
    float *ptr_Acf;
    float sumAcf[LpcOrderP1];
    float temp;

    /* Compute sum of NbAvAcf frame-Acfs  */
    for (j=0; j <= LpcOrder; j++)
        sumAcf[j] = (float) 0.0;

    ptr_Acf = CodCng.Acf + LpcOrderP1;
    for (i=1; i <= NbAvAcf; i++) {
        for (j=0; j <= LpcOrder; j++) {
            sumAcf[j] += *ptr_Acf++;
        }
    }

    Durbin(Coeff, &sumAcf[1], sumAcf[0], &temp);

    return;
}

/*
**
** Function:           CalcRC()
**
** Description:        Computes function derived from
**                     the autocorrelation of LPC coefficients
**                     used for Itakura distance
**
** Links to text:
**
** Arguments :
**
**   float *Coeff      set of LPC coefficients
**   float *RC         derived from LPC coefficients autocorrelation
**
** Outputs :
**
**   float *RC
**
** Return value:       None
**
*/
void CLanAudioEncoder::CalcRC(float *Coeff, float *RC)
{
    int i, j;
    float temp;

//    temp = (float) 1.0 + DotProd(Coeff, Coeff, LpcOrder);
    temp = (float) 1.0 + DotProd10s(Coeff, Coeff);
    RC[0] = temp;

    for (i=1; i<=LpcOrder; i++) {
        temp = -Coeff[i-1];
        for (j=0; j<LpcOrder-i; j++) {
            temp += Coeff[j] * Coeff[j+i];
        }
        RC[i] = (float)2.0 * temp;
    }
    return;
}

/*
**
** Function:           LpcDiff()
**
** Description:        Comparison of two filters
**                     using Itakura distance
**                     1st filter : defined by *ptrAcf
**                     2nd filter : defined by *RC
**                     the autocorrelation of LPC coefficients
**                     used for Itakura distance
**
** Links to text:
**
** Arguments :
**
**   float *RC         derived from LPC coefficients autocorrelation
**   float *ptrAcf     pointer on signal autocorrelation function
**   float alpha       residual energy in LPC analysis using *ptrAcf
**
** Output:             None
**
** Return value:       flag = 1 if similar filters
**                     flag = 0 if different filters
**
*/
BOOL CLanAudioEncoder::LpcDiff(float *RC, float *ptrAcf, float alpha)
{
    float temp0, temp1;
    BOOL diff;

    temp0 = DotProd(RC, ptrAcf, LpcOrderP1);
    temp1 = alpha * FracThreshP1;

    if (temp0 < temp1)
        diff = TRUE;
    else
        diff = FALSE;
    return diff;
}

/*
**
** Function:        Rem_Dc()
**
** Description:     High-pass filtering
**
** Links to text:   Section 2.3
**
** Arguments:
**
**  float  *Dpnt
**
** Inputs:
**
**  CodStat.HpfZdl  FIR filter memory from previous frame (1 word)
**  CodStat.HpfPdl  IIR filter memory from previous frame (1 word)
**
** Outputs:
**
**  float  *Dpnt
**
** Return value:    None
**
*/

void  CLanAudioEncoder::Rem_Dc(float *Dpnt)
{
    int   i;
    float acc0;

    if (UseHp)
    {
        for (i=0; i < Frame; i++)
        {
            acc0 = Dpnt[i] - CodStat.HpfZdl;
            CodStat.HpfZdl = Dpnt[i];

            Dpnt[i] = CodStat.HpfPdl =
                            acc0 + CodStat.HpfPdl*((float)127.0/(float)128.0);
        }
    }
}


/*
**
** Function:        Line_Pack()
**
** Description:     Packing coded parameters in bitstream of 16-bit words
**
** Links to text:   Section 4
**
** Arguments:
**
**  LINEDEF *Line     Coded parameters for a frame
**  char    *Vout     bitstream chars
**  short   Ftyp     Voice Activity Indicator
**
** Outputs:
**
**  short *Vout
**
** Return value:    None
**
*/
void    CLanAudioEncoder::Line_Pack(LINEDEF *Line, char *Vout, short Ftyp)
{
    int       i;
    int       BitCount;

    short    BitStream[192];
    short    *Bsp = BitStream;
    int    Temp;

    /* Clear the output vector */
    for ( i = 0 ; i < 24 ; i ++ )
        Vout[i] = 0 ;

 /*
  * Add the coder rate info and frame type info to the 2 msb
  * of the first word of the frame.
  * The signaling is as follows:
  *     Ftyp  WrkRate => X1X0
  *       1     Rate63     00  :   High Rate
  *       1     Rate53     01  :   Low  Rate
  *       2       x        10  :   Silence Insertion Descriptor frame
  *       0       x        11  :   Used only for simulation of
  *                                 untransmitted silence frames
  */
    switch (Ftyp) {

        case 0 : {
            Temp = 0x00000003L;
            break;
        }

        case 2 : {
            Temp = 0x00000002L;
            break;
        }

        default : {
            if ( WrkRate == Rate63 )
                Temp = 0x00000000L;
            else
                Temp = 0x00000001L;
            break;
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -