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);
    }
Ejemplo n.º 3
0
void phase_dispersion(
    int16 gain_code,             /* (i) Q0  : gain of code             */
    int16 gain_pit,              /* (i) Q14 : gain of pitch            */
    int16 code[],                /* (i/o)   : code vector              */
    int16 mode,                  /* (i)     : level, 0=hi, 1=lo, 2=off */
    int16 disp_mem[],            /* (i/o)   : static memory (size = 8) */
    int16 ScratchMem[]
)
{
    int16 i, j, state;
    int16 *prev_gain_pit, *prev_gain_code, *prev_state;
    int16 *code2 = ScratchMem;

    prev_state = disp_mem;
    prev_gain_code = disp_mem + 1;
    prev_gain_pit = disp_mem + 2;

    pv_memset((void *)code2, 0, (2*L_SUBFR)*sizeof(*code2));


    if (gain_pit < pitch_0_6)
    {
        state = 0;
    }
    else if (gain_pit < pitch_0_9)
    {
        state = 1;
    }
    else
    {
        state = 2;
    }

    for (i = 5; i > 0; i--)
    {
        prev_gain_pit[i] = prev_gain_pit[i - 1];
    }
    prev_gain_pit[0] = gain_pit;

    if (sub_int16(gain_code, *prev_gain_code) > shl_int16(*prev_gain_code, 1))
    {
        /* onset */
        if (state < 2)
        {
            state++;
        }
    }
    else
    {
        j = 0;
        for (i = 0; i < 6; i++)
        {
            if (prev_gain_pit[i] < pitch_0_6)
            {
                j++;
            }
        }

        if (j > 2)
        {
            state = 0;
        }
        if (state > *prev_state + 1)
        {
            state--;
        }
    }

    *prev_gain_code = gain_code;
    *prev_state = state;

    /* circular convolution */

    state += mode;              /* level of dispersion */

    if (state == 0)
    {
        for (i = 0; i < L_SUBFR; i++)
        {
            if (code[i] != 0)
            {
                for (j = 0; j < L_SUBFR; j++)
                {
                    code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_low[j]));
                }
            }
        }
    }
    else if (state == 1)
    {
        for (i = 0; i < L_SUBFR; i++)
        {
            if (code[i] != 0)
            {
                for (j = 0; j < L_SUBFR; j++)
                {
                    code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_mid[j]));
                }
            }
        }
    }
    if (state < 2)
    {
        for (i = 0; i < L_SUBFR; i++)
        {
            code[i] = add_int16(code2[i], code2[i + L_SUBFR]);
        }
    }
    return;
}