void interpolate_isp(
    int16 isp_old[],       /* input : isps from past frame              */
    int16 isp_new[],       /* input : isps from present frame           */
    const int16 frac[],    /* input : fraction for 3 first subfr (Q15)  */
    int16 Az[]             /* output: LP coefficients in 4 subframes    */
)
{
    int16 i, k, fac_old, fac_new;
    int16 isp[M];
    int32 L_tmp;

    for (k = 0; k < 3; k++)
    {
        fac_new = frac[k];
        fac_old = add_int16(sub_int16(32767, fac_new), 1);  /* 1.0 - fac_new */

        for (i = 0; i < M; i++)
        {
            L_tmp = mul_16by16_to_int32(isp_old[i], fac_old);
            L_tmp = mac_16by16_to_int32(L_tmp, isp_new[i], fac_new);
            isp[i] = amr_wb_round(L_tmp);
        }
        Isp_Az(isp, Az, M, 0);
        Az += MP1;
    }

    /* 4th subframe: isp_new (frac=1.0) */

    Isp_Az(isp_new, Az, M, 0);

    return;
}
//============================================================================
//函数功能:找到语音因子
//函数参数:"exc[]"表示因子,作为输入参数;"Q_exc"表示激励,表示输入参数;"gain_pit"
//         表示增益音高,作为输入参数;"code[]"表示固定码本激励,作为输入参数;
//         "gain_code"表示编码增益,作为输入参数;"L_subfr"表示子帧长度
//============================================================================
int16 voice_factor(    /* (o) Q15   : factor (-1=unvoiced to 1=voiced) */
    int16 exc[],      /* (i) Q_exc : pitch excitation                 */
    int16 Q_exc,      /* (i)       : exc format                       */
    int16 gain_pit,   /* (i) Q14   : gain of pitch                    */
    int16 code[],     /* (i) Q9    : Fixed codebook excitation        */
    int16 gain_code,  /* (i) Q0    : gain of code                     */
    int16 L_subfr     /* (i)       : subframe length                  */
)
{
    int16 i, tmp, exp, ener1, exp1, ener2, exp2;
    int32 L_tmp;

    ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1));
    exp1 = sub_int16(exp1, Q_exc << 1);
    L_tmp = mul_16by16_to_int32(gain_pit, gain_pit);
    exp = normalize_amr_wb(L_tmp);

    tmp = (int16)((L_tmp << exp) >> 16);
    ener1 = mult_int16(ener1, tmp);
    exp1 -= (exp + 10);        /* 10 -> gain_pit Q14 to Q9 */

    ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2));

    exp = norm_s(gain_code);
    tmp = shl_int16(gain_code, exp);
    tmp = mult_int16(tmp, tmp);
    ener2 = mult_int16(ener2, tmp);
    exp2 -= (exp << 1);

    i = exp1 - exp2;


    if (i >= 0)
    {
        ener1 >>=  1;
        ener2 >>= (i + 1);
    }
Example #3
0
        {
            for (i = 0; i < M; i++)
            {
                for (j = (L_MEANBUF - 1); j > 0; j--)
                {
                    isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];
                }
                isf_buf[i] = isf_q[i];
            }
        }
    }
    else
    {                                      /* bad frame */
        for (i = 0; i < M; i++)
        {
            L_tmp = mul_16by16_to_int32(mean_isf[i], 8192);
            for (j = 0; j < L_MEANBUF; j++)
            {
                L_tmp = mac_16by16_to_int32(L_tmp, isf_buf[j * M + i], 8192);
            }
            ref_isf[i] = amr_wb_round(L_tmp);
        }

        /* use the past ISFs slightly shifted towards their mean */
        for (i = 0; i < ORDER; i++)
        {
            isf_q[i] = add_int16(mult_int16(ALPHA, isfold[i]), mult_int16(ONE_ALPHA, ref_isf[i]));
        }

        /* estimate past quantized residual to be used in next frame */
//============================================================================
//函数功能:设置存储器
//函数参数:"index"表示指标量化,作为输入参数;"nbits"表示位数,作为输入参数;"
//         code[]"表示创新载体,作为输入参数;"L_subfr"表示子帧长度,作为输入参
//         数;"gain_pit"表示基音增益,作为输出参数;"gain_cod"表示编码增益,作
//         为输出参数;"bfi"表示坏帧指示,作为输入参数;"prev_bfi"表示先前BF指
//         示器,作为输入参数;"state"表示BFH的状态,作为输入参数;"unusable_frame"
//         表示UF指示器,作为输入参数;"vad_hist"表示非语音帧的数目,作为输入参
//         数;"mem"表示静态存储器,既作为输入参数又作为输出参数
//============================================================================
void dec_gain2_amr_wb(
    int16 index,               /* (i)     : index of quantization.      */
    int16 nbits,               /* (i)     : number of bits (6 or 7)     */
    int16 code[],              /* (i) Q9  : Innovative vector.          */
    int16 L_subfr,             /* (i)     : Subframe lenght.            */
    int16 * gain_pit,          /* (o) Q14 : Pitch gain.                 */
    int32 * gain_cod,          /* (o) Q16 : Code gain.                  */
    int16 bfi,                 /* (i)     : bad frame indicator         */
    int16 prev_bfi,            /* (i)     : Previous BF indicator       */
    int16 state,               /* (i)     : State of BFH                */
    int16 unusable_frame,      /* (i)     : UF indicator                */
    int16 vad_hist,            /* (i)     : number of non-speech frames */
    int16 * mem                /* (i/o)   : static memory (4 words)     */
)
{
    const int16 *p;
    int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc;
    int16 *pbuf2;
    int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov;
    int16 tmp1, g_code;
    int16 tmp2;
    int32 L_tmp;

    past_qua_en = mem;
    past_gain_pit = mem + 4;
    past_gain_code = mem + 5;
    prev_gc = mem + 6;
    pbuf = mem + 7;
    gbuf = mem + 12;
    pbuf2 = mem + 17;

    /*
     *  Find energy of code and compute:
     *
     *    L_tmp = 1.0 / sqrt(energy of code/ L_subfr)
     */

    L_tmp = Dot_product12(code, code, L_subfr, &exp);
    exp -= 24;                /* exp: -18 (code in Q9), -6 (/L_subfr) */

    one_ov_sqrt_norm(&L_tmp, &exp);

    gcode_inov = extract_h(shl_int32(L_tmp, exp - 3));  /* g_code_inov in Q12 */

    /*
     * Case of erasure.
     */

    if (bfi != 0)
    {
        tmp = median5(&pbuf[2]);
        *past_gain_pit = tmp;

        if (*past_gain_pit > 15565)
        {
            *past_gain_pit = 15565;        /* 0.95 in Q14 */

        }

        if (unusable_frame != 0)
        {
            *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit);
        }
        else
        {
            *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit);
        }
        tmp = median5(&gbuf[2]);

        if (vad_hist > 2)
        {
            *past_gain_code = tmp;
        }
        else
        {

            if (unusable_frame != 0)
            {
                *past_gain_code = mult_int16(cdown_unusable[state], tmp);
            }
            else
            {
                *past_gain_code = mult_int16(cdown_usable[state], tmp);
            }
        }

        /* update table of past quantized energies */

        //更新过去的量子化的能量表
        tmp  = past_qua_en[3];
        tmp1 = past_qua_en[2];
        L_tmp  = tmp;
        L_tmp += tmp1;
        past_qua_en[3] = tmp;
        tmp  = past_qua_en[1];
        tmp1 = past_qua_en[0];
        L_tmp += tmp;
        L_tmp += tmp1;
        past_qua_en[2] = tmp;
        qua_ener = (int16)(L_tmp >> 3);
        past_qua_en[1] = tmp1;


        qua_ener -= 3072;    /* -3 in Q10 */

        if (qua_ener < -14336)
        {
            qua_ener = -14336;                /* -14 in Q10 */
        }

        past_qua_en[0] = qua_ener;


        for (i = 1; i < 5; i++)
        {
            gbuf[i - 1] = gbuf[i];
            pbuf[i - 1] = pbuf[i];
        }
        gbuf[4] = *past_gain_code;
        pbuf[4] = *past_gain_pit;


        /* adjust gain according to energy of code */
        /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */
	 //调整增益根据能量代码
        *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov);

        return;
    }
Example #5
0
void agc2_amr_wb(
    int16 * sig_in,          /* (i)     : postfilter input signal  */
    int16 * sig_out,         /* (i/o)   : postfilter output signal */
    int16 l_trm              /* (i)     : subframe size            */
)
{

    int16 i, exp;
    int16 gain_in, gain_out, g0;
    int32 s;

    int16 temp;

    /* calculate gain_out with exponent */

    temp = sig_out[0] >> 2;
    s = fxp_mul_16by16(temp, temp) << 1;
    for (i = 1; i < l_trm; i++)
    {
        temp = sig_out[i] >> 2;
        s = mac_16by16_to_int32(s, temp, temp);
    }


    if (s == 0)
    {
        return;
    }
    exp = normalize_amr_wb(s) - 1;
    gain_out = amr_wb_round(s << exp);

    /* calculate gain_in with exponent */

    temp = sig_in[0] >> 2;
    s = mul_16by16_to_int32(temp, temp);
    for (i = 1; i < l_trm; i++)
    {
        temp = sig_in[i] >> 2;
        s = mac_16by16_to_int32(s, temp, temp);
    }


    if (s == 0)
    {
        g0 = 0;
    }
    else
    {
        i = normalize_amr_wb(s);
        gain_in = amr_wb_round(s << i);
        exp -= i;

        /*
         *  g0 = sqrt(gain_in/gain_out)
         */

        s = div_16by16(gain_out, gain_in);
        s = shl_int32(s, 7);                   /* s = gain_out / gain_in */
        s = shr_int32(s, exp);                 /* add exponent */

        s = one_ov_sqrt(s);
        g0 = amr_wb_round(shl_int32(s, 9));
    }
    /* sig_out(n) = gain(n) sig_out(n) */

    for (i = 0; i < l_trm; i++)
    {
        sig_out[i] = extract_h(shl_int32(fxp_mul_16by16(sig_out[i], g0), 3));

    }

    return;
}