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

📄 pstcp.c

📁 语音压缩编码中的g729p编码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            if(den0 > den_max) {
                den_max = den0;
            }
        }
        else {
            if(den1 > den_max) {
                den_max = den1;
            }
        }
        ptr_y_up += L_SUBFRP1;
        ptr_h += LH2_S;
    }
    if(den_max < (F)0.1 ) {
        *num_gltp = (F)0.;
        *den_gltp = (F)1.;
        *ltpdel   = 0;
        *phase    = 0;
        return;
    }
    /* Computation of the numerators                */
    /* and selection of best num*num/den            */
    /* for non null phases                          */

    /* Initialize with null phase */
    num_max      = num_int;
    den_max      = den_int;
    numsq_max   =  num_max * num_max;
    phi_max      = 0;
    ioff         = 1;

    ptr_den0   = tab_den0;
    ptr_den1   = tab_den1;
    ptr_y_up     = y_up;

    /* if den_max = 0 : will be selected and declared unvoiced */
    /* if num!=0 & den=0 : will be selected and declared unvoiced */
    /* degenerated seldom cases, switch off LT is OK */

    /* Loop on phase */
    for(phi=1; phi<F_UP_PST; phi++) {

        /* computes num for lambda_max+1 - phi/F_UP_PST */
        num = (F)0.;
        for(n = 0; n<L_SUBFR; n++) {
            num += ptr_sig_in[n]  * ptr_y_up[n];
        }
        if(num < (F)0.) num = (F)0.;
        numsq = num * num;

        /* selection if num/sqrt(den0) max */
        den0 = *ptr_den0++;
        temp0 = numsq * den_max;
        temp1 = numsq_max * den0;
        if(temp0 > temp1) {
            num_max     = num;
            numsq_max   = numsq;
            den_max     = den0;
            ioff        = 0;
            phi_max     = phi;
        }

        /* computes num for lambda_max - phi/F_UP_PST */
        ptr_y_up++;
        num = (F)0.;
        for(n = 0; n<L_SUBFR; n++) {
            num += ptr_sig_in[n]  * ptr_y_up[n];
        }
        if(num < (F)0.) num = (F)0.;
        numsq = num * num;

        /* selection if num/sqrt(den1) max */
        den1 = *ptr_den1++;
        temp0 = numsq * den_max;
        temp1 = numsq_max * den1;
        if(temp0 > temp1) {
            num_max     = num;
            numsq_max   = numsq;
            den_max     = den1;
            ioff        = 1;
            phi_max     = phi;
        }
        ptr_y_up += L_SUBFR;
    }

    /***************************************************/
    /*** test if normalised crit0[iopt] > THRESCRIT  ***/
    /***************************************************/

    if((num_max == (F)0.) || (den_max <= (F)0.1)) {
        *num_gltp = (F)0.;
        *den_gltp = (F)1.;
        *ltpdel = 0;
        *phase = 0;
        return;
    }

    /* comparison num * num            */
    /* with ener * den x THRESCRIT      */
    temp1 = den_max * ener * THRESCRIT;
    if(numsq_max >= temp1) {
        *ltpdel   = lambda + 1 - ioff;
        *off_yup  = ioff;
        *phase    = phi_max;
        *num_gltp = num_max;
        *den_gltp = den_max;
    }
    else {
        *num_gltp = (F)0.;
        *den_gltp = (F)1.;
        *ltpdel   = 0;
        *phase    = 0;
    }
    return;
}

/*----------------------------------------------------------------------------
 *  filt_plt -  ltp  postfilter
 *----------------------------------------------------------------------------
 */
static void filt_plt(
    FLOAT *s_in,       /* input : input signal with past*/
    FLOAT *s_ltp,      /* input : filtered signal with gain 1 */
    FLOAT *s_out,      /* output: output signal */
    FLOAT gain_plt     /* input : filter gain  */
)
{
    /* Local variables */
    int n;
    FLOAT gain_plt_1;

    gain_plt_1 = (F)1. - gain_plt;

    for(n=0;  n<L_SUBFR; n++) {
        s_out[n] = gain_plt * s_in[n] + gain_plt_1 * s_ltp[n];
    }

    return;
}

/*----------------------------------------------------------------------------
 *  compute_ltp_l : compute delayed signal,
                    num & den of gain for fractional delay
 *                  with long interpolation filter
 *----------------------------------------------------------------------------
 */
static void compute_ltp_l(
    FLOAT *s_in,       /* input signal with past*/
    int ltpdel,      /* delay factor */
    int phase,       /* phase factor */
    FLOAT *y_up,       /* delayed signal */
    FLOAT *num,        /* numerator of LTP gain */
    FLOAT *den        /* denominator of LTP gain */
)
{
    /* Pointer on table of constants */
    FLOAT *ptr_h;

    /* Local variables */
    int n, i;
    FLOAT *ptr2, temp;

    /* Filtering with long filter */
    ptr_h = tab_hup_l + (phase-1) * LH2_L;
    ptr2 = s_in - ltpdel + LH_UP_L;

    /* Compute y_up */
    for(n = 0; n<L_SUBFR; n++) {
        temp = (F)0.;
        for(i=0; i<LH2_L; i++) {
            temp += ptr_h[i] * *ptr2--;
        }
        y_up[n] = temp;
        ptr2 += LH2_L_P1;
    }

    /* Compute num */
    *num = (F)0.;
    for(n = 0; n<L_SUBFR; n++) {
        *num += y_up[n]* s_in[n];
    }
    if(*num < (F)0.0) *num = (F)0.0;

    *den = (F)0.;
    /* Compute den */
    for(n = 0; n<L_SUBFR; n++) {
        *den += y_up[n]* y_up[n];
    }

    return;
}

/*----------------------------------------------------------------------------
 *  select_ltp : selects best of (gain1, gain2)
 *  with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
 *  and  gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
 *----------------------------------------------------------------------------
 */
static int select_ltp(  /* output : 1 = 1st gain, 2 = 2nd gain */
    FLOAT num1,       /* input : numerator of gain1 */
    FLOAT den1,       /* input : denominator of gain1 */
    FLOAT num2,       /* input : numerator of gain2 */
    FLOAT den2        /* input : denominator of gain2 */
)
{
    if(den2 == (F)0.) {
        return(1);
    }
    if(num2 * num2 * den1> num1 * num1 * den2) {
        return(2);
    }
    else {
        return(1);
    }
}

/*----------------------------------------------------------------------------
 *   calc_st_filt -  computes impulse response of A(gamma2) / A(gamma1)
 *   controls gain : computation of energy impulse response as
 *                    SUMn  (abs (h[n])) and computes parcor0
 *----------------------------------------------------------------------------
 */
static void calc_st_filte(
    FLOAT *apond2,     /* input : coefficients of numerator */
    FLOAT *apond1,     /* input : coefficients of denominator */
    FLOAT *parcor0,    /* output: 1st parcor calcul. on composed filter */
    FLOAT *sig_ltp_ptr,    /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */
    int  long_h_st,     /* input : impulse response length                   */
    int m_pst               /* input : LPC order    */
)
{
    FLOAT h[LONG_H_ST_E];
    FLOAT g0, temp;
    int i;

    /* compute i.r. of composed filter apond2 / apond1 */
    syn_filte(m_pst, apond1, apond2, h, long_h_st, mem_zero, 0);

    /* compute 1st parcor */
    calc_rc0_he(h, parcor0, long_h_st);

    /* compute g0 */
    g0 = (F)0.;
    for(i=0; i<long_h_st; i++) {
        g0 += (FLOAT)fabs(h[i]);
    }

    /* Scale signal input of 1/A(gamma1) */
    if(g0 > (F)1.) {
        temp = (F)1./g0;
        for(i=0; i<L_SUBFR; i++) {
            sig_ltp_ptr[i] = sig_ltp_ptr[i] * temp;
        }
    }
    return;
}

/*----------------------------------------------------------------------------
 * calc_rc0_h - computes 1st parcor from composed filter impulse response
 *----------------------------------------------------------------------------
 */
static void calc_rc0_he(
    FLOAT *h,      /* input : impulse response of composed filter */
    FLOAT *rc0,     /* output: 1st parcor */
    int  long_h_st  /*input : impulse response length */
)
{
    FLOAT acf0, acf1;
    FLOAT temp, temp2;
    FLOAT *ptrs;
    int i;

    /* computation of the autocorrelation function acf */
    temp = (F)0.;
    for(i=0; i<long_h_st; i++) {
        temp += h[i] * h[i];
    }
    acf0 = temp;

    temp = (F)0.;
    ptrs = h;
    for(i=0;i<long_h_st-1;i++){
        temp2 = *ptrs++;
        temp += temp2 * (*ptrs);
    }
    acf1 = temp;

    /* Initialisation of the calculation */
    if( acf0 == (F)0.) {
        *rc0 = (F)0.;
        return;
    }

    /* Compute 1st parcor */
    /**********************/
    if(acf0 < (FLOAT)fabs(acf1) ) {
        *rc0 = (F)0.0;
        return;
    }
    *rc0 = - acf1 / acf0;

    return;
}

/*----------------------------------------------------------------------------
 * filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
 *   computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
 *----------------------------------------------------------------------------
 */
static void filt_mu(
    FLOAT *sig_in,     /* input : input signal (beginning at sample -1) */
    FLOAT *sig_out,    /* output: output signal */
    FLOAT parcor0      /* input : parcor0 (mu = parcor0 * gamma3) */
)
{
    int n;
    FLOAT mu, ga, temp;
    FLOAT *ptrs;

    if(parcor0 > (F)0.) {
        mu = parcor0 * GAMMA3_PLUS;
    }
    else {
        mu = parcor0 * GAMMA3_MINUS;
    }
    ga = (F)1. / ((F)1. - (FLOAT)fabs(mu));

    ptrs = sig_in;      /* points on sig_in(-1) */
    for(n=0; n<L_SUBFR; n++) {
        temp = mu * (*ptrs++);
        temp += (*ptrs);
        sig_out[n] = ga * temp;
    }
    return;
}

/*----------------------------------------------------------------------------
 *   scale_st  - control of the subframe gain
 *   gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out
 *----------------------------------------------------------------------------
 */
void scale_st(
    FLOAT *sig_in,     /* input : postfilter input signal */
    FLOAT *sig_out,    /* in/out: postfilter output signal */
    FLOAT *gain_prec   /* in/out: last value of gain for subframe */
)
{
    int i;
    FLOAT gain_in, gain_out;
    FLOAT g0, gain;

    /* compute input gain */
    gain_in = (F)0.;
    for(i=0; i<L_SUBFR; i++) {
        gain_in += (FLOAT)fabs(sig_in[i]);
    }
    if(gain_in == (F)0.) {
        g0 = (F)0.;
    }
    else {
        /* Compute output gain */
        gain_out = (F)0.;
        for(i=0; i<L_SUBFR; i++) {
            gain_out += (FLOAT)fabs(sig_out[i]);
        }
        if(gain_out == (F)0.) {
            *gain_prec = (F)0.;
            return;
        }

        g0 = gain_in/ gain_out;
        g0 *= AGC_FAC1;
    }

    /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
    /* sig_out(n) = gain(n) sig_out(n)                                   */
    gain = *gain_prec;
    for(i=0; i<L_SUBFR; i++) {
        gain *= AGC_FAC;
        gain += g0;
        sig_out[i] *= gain;
    }
    *gain_prec = gain;
    return;
}

⌨️ 快捷键说明

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