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

📄 exc2.c

📁 symbian 系统下的g.723 g.723_24实现, 本源码在 series60 sdk fp2下调试通过
💻 C
📖 第 1 页 / 共 5 页
字号:
**  Function:  G_code()
**
**  Description: Compute the gain of innovative code.
**
**
**  Links to the text: Section 2.16
**
** Input arguments:
**
**      FLOAT  X[]        Code target.  (in Q0)
**      FLOAT  Y[]        Filtered innovation code. (in Q12)
**
** Output:
**
**      FLOAT  *gain_q    Gain of innovation code.  (in Q0)
**
**  Return value:
**
**      int     index of innovation code gain
**
*/
int G_code(FLOAT X[], FLOAT Y[], FLOAT *gain_q)
{
    int     i;
    FLOAT   xy, yy, gain_nq;
    int     gain;
    FLOAT   dist, dist_min;

    /*  Compute scalar product <X[],Y[]> */

    xy = DotProd(X,Y,SubFrLen);

    if (xy <= 0)
    {
        gain = 0;
        *gain_q =FcbkGainTable[gain];
        return(gain);
    }

    /*  Compute scalar product <Y[],Y[]>  */

    yy = DotProd(Y,Y,SubFrLen);

    if (yy > (FLOAT) FLT_MIN)
        gain_nq = xy/yy;
    else
        gain_nq = (FLOAT)0.0;

    gain = 0;
    dist_min = (FLOAT)fabs(gain_nq - FcbkGainTable[0]);

    for (i=1; i <NumOfGainLev; i++)
    {
        dist = (FLOAT)fabs(gain_nq - FcbkGainTable[i]);
        if (dist < dist_min)
        {
            dist_min = dist;
            gain = i;
        }
    }
    *gain_q = FcbkGainTable[gain];
    return(gain);
}


/*
**
**  Function:       search_T0()
**
**  Description:          Gets parameters of pitch synchronous filter
**
**  Links to the text:    Section 2.16
**
**  Arguments:
**
**      int    T0         Decoded pitch lag
**      int    Gid        Gain vector index in adaptive gain vector codebook
**      FLOAT  *gain_T0   Pitch synchronous gain
**
**  Outputs:
**
**      FLOAT  *gain_T0   Pitch synchronous filter gain
**
**  Return Value:
**
**      int    T0_mod     Pitch synchronous filter lag
*/
int search_T0 (int T0, int Gid, FLOAT *gain_T0)
{
    int T0_mod;

    T0_mod = T0+epsi170[Gid];
    *gain_T0 = gain170[Gid];

    return(T0_mod);
}

/*
**
** Function:    Update_Err()
**
** Description:   Estimation of the excitation error associated
**          to the excitation signal when it is disturbed at
**          the decoder, the disturbing signal being filtered
**          by the long term synthesis filters
**          one value for (SubFrLen/2) samples
**          Updates the table CodStat.Err
**
** Links to text:   Section
**
** Arguments:
**
**  int Olp    Center value for pitch delay
**  int AcLg   Offset value for pitch delay
**  int AcGn   Index of Gain LT filter
**
** Outputs: None
**
** Return value:  None
**
*/
void Update_Err(int Olp, int AcLg, int AcGn)
{
    int     i, iz, temp2;
    int     Lag;
    FLOAT   Worst1, Worst0, wtemp;
    FLOAT   beta,*ptr_tab;

    Lag = Olp - Pstep + AcLg;

    /* Select Quantization tables */
    i = 0 ;
    ptr_tab = tabgain85;
    if ( WrkRate == Rate63 ) {
        if ( Olp >= (SubFrLen-2) )
            ptr_tab = tabgain170;
    }
    else {
        ptr_tab = tabgain170;
    }
    beta = ptr_tab[(int)AcGn];


    if (Lag <= (SubFrLen/2))
    {
        Worst0 = CodStat.Err[0]*beta + Err0;
        Worst1 = Worst0;
    }
    else
    {
        iz = (int)(((Word32)Lag*1092L) >> 15);
        temp2 = 30*(iz+1);

        if (temp2 != Lag)
        {
            if (iz == 1)
            {
                Worst0 = CodStat.Err[0]*beta + Err0;
                Worst1 = CodStat.Err[1]*beta + Err0;

                if (Worst0 > Worst1)
                    Worst1 = Worst0;
                else
                    Worst0 = Worst1;
            }
            else
            {
                wtemp = CodStat.Err[iz-1]*beta + Err0;
                Worst0 = CodStat.Err[iz-2]*beta + Err0;
                if (wtemp > Worst0)
                    Worst0 = wtemp;
                Worst1 = CodStat.Err[iz]*beta + Err0;
                if (wtemp > Worst1)
                    Worst1 = wtemp;
            }
        }
        else
        {
            Worst0 = CodStat.Err[iz-1]*beta + Err0;
            Worst1 = CodStat.Err[iz]*beta + Err0;
        }
    }

    if (Worst0 > MAXV)
        Worst0 = MAXV;
    if (Worst1 > MAXV)
        Worst1 = MAXV;

    for (i=4; i>=2; i--)
        CodStat.Err[i] = CodStat.Err[i-2];

    CodStat.Err[0] = Worst0;
    CodStat.Err[1] = Worst1;

    return;
}

/*
**
** Function:    Test_Err()
**
** Description:   Check the error excitation maximum for
**          the subframe and computes an index iTest used to
**          calculate the maximum nb of filters (in Find_Acbk) :
**          Bound = Min(Nmin + iTest x pas, Nmax) , with
**          AcbkGainTable085 : pas = 2, Nmin = 51, Nmax = 85
**          AcbkGainTable170 : pas = 4, Nmin = 93, Nmax = 170
**          iTest depends on the relative difference between
**          errmax and a fixed threshold
**
** Links to text:   Section
**
** Arguments:
**
**  Word16 Lag1    1st long term Lag of the tested zone
**  Word16 Lag2    2nd long term Lag of the tested zone
**
** Outputs: None
**
** Return value:
**  Word16      index iTest used to compute Acbk number of filters
*/
int Test_Err(int Lag1, int Lag2)
{
    int     i, i1, i2;
    int     zone1, zone2, iTest;
    FLOAT   Err_max;

    i2 = Lag2 + ClPitchOrd/2;
    zone2 = i2/30;

    i1 = - SubFrLen + 1 + Lag1 - ClPitchOrd/2;
    if (i1 <= 0)
        i1 = 1;
    zone1 = i1/30;

    Err_max = (FLOAT)-1.0;
    for (i=zone2; i>=zone1; i--)
    {
        if (CodStat.Err[i] > Err_max)
            Err_max = CodStat.Err[i];
    }
    if ((Err_max > ThreshErr) || (CodStat.SinDet < 0 ) )
    {
        iTest = 0;
    }
    else
    {
        iTest = (Word16)(ThreshErr - Err_max);
    }

    return(iTest);
}

/*
**
** Function:        Find_Acbk()
**
** Description:     Computation of adaptive codebook contribution in
**                  closed-loop around open-loop pitch lag (subframes 0 & 2)
**                  around the previous subframe closed-loop pitch lag
**                  (subframes 1 & 3).  For subframes 0 & 2, the pitch lag is
**                  encoded whereas for subframes 1 & 3, only the difference
**                  with the previous value is encoded (-1, 0, +1 or +2).
**                  The pitch predictor gains are quantized using one of two
**                  codebooks (85 entries or 170 entries) depending on the
**                  rate and on the pitch lag value.
**                  Finally, the contribution of the pitch predictor is decoded
**                  and subtracted to obtain the residual signal.
**
** Links to text:   Section 2.14
**
** Arguments:
**
**  FLOAT  *Tv      Target vector
**  FLOAT  *ImpResp Impulse response of the combined filter
**  FLOAT  *PrevExc Previous excitation vector
**  LINEDEF *Line   Contains pitch parameters (open/closed loop lag, gain)
**  int    Sfc      Subframe index
**
** Outputs:
**
**  FLOAT  *Tv     Residual vector
**  LINEDEF *Line  Contains pitch related parameters (closed loop lag, gain)
**
** Return value:    None
**
*/
void  Find_Acbk(FLOAT *Tv, FLOAT *ImpResp, FLOAT *PrevExc,
                LINEDEF *Line, int Sfc)
{
    int i,j,k,l;

    FLOAT Acc0,Max;

    FLOAT RezBuf[SubFrLen+ClPitchOrd-1];
    FLOAT FltBuf[ClPitchOrd][SubFrLen];
    FLOAT CorVct[4*(2*ClPitchOrd + ClPitchOrd*(ClPitchOrd-1)/2)];
    FLOAT *lPnt;
    FLOAT *sPnt;

    int   Olp,Lid,Gid,Hb;
    int   Bound[2];
    int   Lag1, Lag2;
    int   off_filt;

    Olp = (*Line).Olp[Sfc>>1];
    Lid = Pstep;
    Gid = 0;
    Hb  = 3 + (Sfc & 1);

    /*  For even frames only */

    if ((Sfc & 1) == 0)
    {
        if (Olp == PitchMin)
            Olp++;
        if (Olp > (PitchMax-5))
            Olp = PitchMax-5;
    }

    lPnt = CorVct;
    for (k=0; k < Hb; k++)
    {

        /*  Get residual from the exitation buffer */

        Get_Rez(RezBuf, PrevExc, Olp-Pstep+k);

        /*  Filter the last one (ClPitchOrd-1) using the impulse responce */

        for (i=0; i < SubFrLen; i++)
        {
            Acc0 = (FLOAT)0.0;
            for (j=0; j <= i; j++)
                Acc0 += RezBuf[ClPitchOrd-1+j]*ImpResp[i-j];

            FltBuf[ClPitchOrd-1][i] = Acc0;
        }

        /*  Update the others (ClPitchOrd-2 down to 0) */

        for (i=ClPitchOrd-2; i >= 0; i --)
        {
            FltBuf[i][0] = RezBuf[i];
            for (j = 1; j < SubFrLen; j++)
                FltBuf[i][j] = RezBuf[i]*ImpResp[j] + FltBuf[i+1][j-1];
        }

        /*  Compute the cross products with the signal */

        for (i=0; i < ClPitchOrd; i++)
            *lPnt++ = DotProd(Tv, FltBuf[i], SubFrLen);

        /*  Compute the energies */

        for (i=0; i < ClPitchOrd; i++)
            *lPnt++ = ((FLOAT)0.5)*DotProd(FltBuf[i], FltBuf[i], SubFrLen);

        /*  Compute the between crosses */

        for (i=1; i < ClPitchOrd; i++)
            for (j = 0; j < i; j++)
                *lPnt++ = DotProd(FltBuf[i], FltBuf[j], SubFrLen);
    }

    /* Test potential error */
    Lag1 = Olp - Pstep;
    Lag2 = Olp - Pstep + Hb - 1;

    off_filt = Test_Err(Lag1, Lag2);

    Bound[0] =  NbFilt085_min + (off_filt << 2);
    if (Bound[0] > NbFilt085)
        Bound[0] = NbFilt085;
    Bound[1] =  NbFilt170_min + (off_filt << 3);
    if (Bound[1] > NbFilt170)
        Bound[1] = NbFilt170;

    Max = (FLOAT)0.0;
    for (k=0; k < Hb; k++)
    {

        /*  Select Quantization table */
        l = 0;
        if (WrkRate == Rate63)
        {
            if ((Sfc & 1) == 0)
            {
                if (Olp-Pstep+k >= SubFrLen-2)
                    l = 1;
            }
            else
            {
                if (Olp >= SubFrLen-2)
                    l = 1;
            }
        }
        else
            l = 1;

        /*  Search for maximum */

        sPnt = AcbkGainTablePtr[l];

        for (i=0; i < Bound[l]; i++)
        {
            Acc0 = DotProd(&CorVct[k*20],sPnt,20);
            sPnt += 20;

            if (Acc0 > Max)
            {
                Max = Acc0;
                Gid = i;
                Lid = k;
            }
        }
    }

    /*  Modify Olp for even sub frames */

    if ((Sfc & 1) == 0)
    {
        Olp = Olp - Pstep + Lid;
        Lid = Pstep;
    }


    /*  Save Lag, Gain and Olp */

    (*Line).Sfs[Sfc].AcLg = Lid;
    (*Line).Sfs[Sfc].AcGn = Gid;
    (*Line).Olp[Sfc>>1] = Olp;

    /*  Decode the Acbk contribution and subtract it */

    Decod_Acbk(RezBuf, PrevExc, Olp, Lid, Gid);

    for (i=0; i < SubFrLen; i++)
    {
        Acc0 = Tv[i];

        for (j=0; j <= i; j++)
            Acc0 -= RezBuf[j]*ImpResp[i-j];

        Tv[i] = Acc0;
    }
}


/*
**
** Function:        Get_Rez()
**
** Description:     Gets delayed contribution from the previous excitation
**                  vector.
**
** Links to text:   Sections 2.14, 2.18 & 3.4
**
** Arguments:
**
**  FLOAT  *Tv      delayed excitation
**  FLOAT  *PrevExc Previous excitation vector
**  int    Lag      Closed loop pitch lag
**
** Outputs:
**
**  FLOAT  *Tv      delayed excitation
**
** Return value:    None
**
*/
void  Get_Rez(FLOAT *Tv, FLOAT *PrevExc, int Lag)
{
    int i;

    for (i=0; i < ClPitchOrd/2; i++)
        Tv[i] = PrevExc[PitchMax - Lag - ClPitchOrd/2 + i];

    for (i=0; i < SubFrLen+ClPitchOrd/2; i++)
        Tv[ClPitchOrd/2+i] = PrevExc[PitchMax - Lag + i%Lag];
}


/*
**
** 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.
**

⌨️ 快捷键说明

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