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

📄 dtx_dec.cpp

📁 实现3GPP的GSM中AMR语音的CODECS。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            else            {                lsf[j] = (Word16)(L_lsf[j] >> 3);            }        }        Lsf_lsp(lsf, st->lsp, M, pOverflow);        /* make log_en speech coder mode independent */        /* added again later before synthesis        */        st->log_en = sub(st->log_en, st->log_en_adjust, pOverflow);        /* compute lsf variability vector */        Copy(st->lsf_hist, st->lsf_hist_mean, 80);        for (i = M - 1; i >= 0; i--)        {            L_lsf_mean = 0;            /* compute mean lsf */            for (j = 8 - 1; j >= 0; j--)            {                L_lsf_mean = L_add(L_lsf_mean,                                   L_deposit_l(st->lsf_hist_mean[i+j*M]), pOverflow);            }            if (L_lsf_mean < 0)            {                lsf_mean = (Word16)(~((~L_lsf_mean) >> 3));            }            else            {                lsf_mean = (Word16)(L_lsf_mean >> 3);            }            /* subtract mean and limit to within reasonable limits  *            * moreover the upper lsf's are attenuated              */            for (j = 8 - 1; j >= 0; j--)            {                /* subtract mean */                st->lsf_hist_mean[i+j*M] =                    sub(st->lsf_hist_mean[i+j*M], lsf_mean, pOverflow);                /* attenuate deviation from mean, especially for upper lsf's */                st->lsf_hist_mean[i+j*M] =                    mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i], pOverflow);                /* limit the deviation */                if (st->lsf_hist_mean[i+j*M] < 0)                {                    negative = 1;                }                else                {                    negative = 0;                }                st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]);                /* apply soft limit */                if (st->lsf_hist_mean[i+j*M] > 655)                {                    st->lsf_hist_mean[i+j*M] = 655 + ((st->lsf_hist_mean[i+j*M]                                                       - 655) >> 2);                }                /* apply hard limit */                if (st->lsf_hist_mean[i+j*M] > 1310)                {                    st->lsf_hist_mean[i+j*M] = 1310;                }                if (negative != 0)                {                    st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M];                }            }        }    }    if (st->sid_frame != 0)    {        /* Set old SID parameters, always shift */        /* even if there is no new valid_data   */        Copy(st->lsp, st->lsp_old, M);        st->old_log_en = st->log_en;        if (st->valid_data != 0)   /* new data available (no CRC) */        {            /* Compute interpolation factor, since the division only works *             * for values of since_last_sid < 32 we have to limit the      *             * interpolation to 32 frames                                  */            tmp_int_length = st->since_last_sid;            st->since_last_sid = 0;            if (tmp_int_length >= 32)            {                tmp_int_length = 32;            }            L_temp = ((Word32) tmp_int_length) << 10;            if (L_temp != (Word32)((Word16) L_temp))            {                *pOverflow = 1;                L_temp = (Word32)((tmp_int_length > 0) ? MAX_16 : MIN_16);            }            temp = (Word16) L_temp;            if (tmp_int_length >= 2)            {                st->true_sid_period_inv = div_s(1 << 10, temp);            }            else            {                st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */            }            Init_D_plsf_3(lsfState, parm[0]);            D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp, pOverflow);            Set_zero(lsfState->past_r_q, M);   /* reset for next speech frame */            log_en_index = parm[4];            /* Q11 and divide by 4 */            if ((log_en_index > 63) || (log_en_index < -64))            {                st->log_en = (log_en_index > 0) ? MAX_16 : MIN_16;            }            else            {                st->log_en = (log_en_index) << (11 - 2);            }            /* Subtract 2.5 in Q11 */            st->log_en = sub(st->log_en, (2560 * 2), pOverflow);            /* Index 0 is reserved for silence */            if (log_en_index == 0)            {                st->log_en = MIN_16;            }            /* no interpolation at startup after coder reset        */            /* or when SID_UPD has been received right after SPEECH */            if ((st->data_updated == 0) ||                    (st->dtxGlobalState == SPEECH))            {                Copy(st->lsp, st->lsp_old, M);                st->old_log_en = st->log_en;            }        } /* endif valid_data */        /* initialize gain predictor memory of other modes */        if (st->log_en < 0)        {            temp = ~((~st->log_en) >> 1);        }        else        {            temp = st->log_en >> 1;        }        ma_pred_init = sub(temp, 9000, pOverflow);        if (ma_pred_init > 0)        {            ma_pred_init = 0;        }        else if (ma_pred_init < -14436)        {            ma_pred_init = -14436;        }        predState->past_qua_en[0] = ma_pred_init;        predState->past_qua_en[1] = ma_pred_init;        predState->past_qua_en[2] = ma_pred_init;        predState->past_qua_en[3] = ma_pred_init;        /* past_qua_en for other modes than MR122 */        ma_pred_init = mult(5443, ma_pred_init, pOverflow);        /* scale down by factor 20*log10(2) in Q15 */        predState->past_qua_en_MR122[0] = ma_pred_init;        predState->past_qua_en_MR122[1] = ma_pred_init;        predState->past_qua_en_MR122[2] = ma_pred_init;        predState->past_qua_en_MR122[3] = ma_pred_init;    } /* endif sid_frame */    /* CN generation */    /* recompute level adjustment factor Q11             *     * st->log_en_adjust = 0.9*st->log_en_adjust +       *     *                     0.1*dtx_log_en_adjust[mode]); */    if (dtx_log_en_adjust[mode] > 1023)    {        temp = MAX_16;    }    else if (dtx_log_en_adjust[mode] < -1024)    {        temp = MIN_16;    }    else    {        temp = mult((Word16)((Word32)dtx_log_en_adjust[mode] << 5), 3277, pOverflow);    }    if (temp < 0)    {        temp = ~((~temp) >> 5);    }    else    {        temp >>= 5;    }    st->log_en_adjust = add(mult(st->log_en_adjust, 29491, pOverflow), temp, pOverflow);    /* Interpolate SID info */    int_fac = shl(add(1, st->since_last_sid, pOverflow), 10, pOverflow); /* Q10 */    int_fac = mult(int_fac, st->true_sid_period_inv, pOverflow); /* Q10 * Q15 -> Q10 */    /* Maximize to 1.0 in Q10 */    if (int_fac > 1024)    {        int_fac = 16384;    }    else if (int_fac < -2048)    {        int_fac = MIN_16;    }    else    {        int_fac <<= 4;      /* Q10 -> Q14 */    }    L_log_en_int = L_mult(int_fac, st->log_en, pOverflow); /* Q14 * Q11->Q26 */    for (i = M - 1; i >= 0; i--)    {        lsp_int[i] = mult(int_fac, st->lsp[i], pOverflow);/* Q14 * Q15 -> Q14 */    }    int_fac = sub(16384, int_fac, pOverflow); /* 1-k in Q14 */    /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */    L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en, pOverflow);    for (i = M - 1; i >= 0; i--)    {        /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */        lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i], pOverflow), pOverflow);        L_temp = ((Word32) lsp_int[i]) << 1;    /* Q14 -> Q15 */        if (L_temp != (Word32)((Word16) L_temp))        {            *pOverflow = 1;            L_temp = (Word32)((lsp_int[i] > 0) ? MAX_16 : MIN_16);        }        lsp_int[i] = (Word16) L_temp;    }    /* compute the amount of lsf variability */    lsf_variab_factor = sub(st->log_pg_mean, 2457, pOverflow); /* -0.6 in Q12 */    /* *0.3 Q12*Q15 -> Q12 */    lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830, pOverflow), pOverflow);    /* limit to values between 0..1 in Q12 */    if (lsf_variab_factor > 4095)    {        lsf_variab_factor = MAX_16;    }    else if (lsf_variab_factor < 0)    {        lsf_variab_factor = 0;    }    else    {        lsf_variab_factor <<= 3; /* -> Q15 */    }    /* get index of vector to do variability with */    lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3);    /* convert to lsf */    Lsp_lsf(lsp_int, lsf_int, M, pOverflow);    /* apply lsf variability */    Copy(lsf_int, lsf_int_variab, M);    for (i = M - 1; i >= 0; i--)    {        lsf_int_variab[i] = add(lsf_int_variab[i],                                mult(lsf_variab_factor,                                     st->lsf_hist_mean[i+lsf_variab_index*M], pOverflow)                                , pOverflow);    }    /* make sure that LSP's are ordered */    Reorder_lsf(lsf_int, LSF_GAP, M, pOverflow);    Reorder_lsf(lsf_int_variab, LSF_GAP, M, pOverflow);    /* copy lsf to speech decoders lsf state */    Copy(lsf_int, lsfState->past_lsf_q, M);    /* convert to lsp */    Lsf_lsp(lsf_int, lsp_int, M, pOverflow);    Lsf_lsp(lsf_int_variab, lsp_int_variab, M, pOverflow);    /* Compute acoeffs Q12 acoeff is used for level    *     * normalization and postfilter, acoeff_variab is  *     * used for synthesis filter                       *     * by doing this we make sure that the level       *     * in high frequenncies does not jump up and down  */    Lsp_Az(lsp_int, acoeff, pOverflow);    Lsp_Az(lsp_int_variab, acoeff_variab, pOverflow);    /* For use in postfilter */    Copy(acoeff, &A_t[0],           M + 1);    Copy(acoeff, &A_t[M + 1],       M + 1);    Copy(acoeff, &A_t[2 * (M + 1)], M + 1);    Copy(acoeff, &A_t[3 * (M + 1)], M + 1);    /* Compute reflection coefficients Q15 */    A_Refl(&acoeff[1], refl, pOverflow);    /* Compute prediction error in Q15 */    pred_err = MAX_16; /* 0.99997 in Q15 */    for (i = 0; i < M; i++)    {        L_temp = (((Word32) refl[i]) * refl[i]) >> 15;        if (L_temp <= 0x00007fffL)        {            temp = MAX_16 - (Word16) L_temp;        }        else        {            *pOverflow = 1;            temp = 0;        }        pred_err = mult(pred_err, temp, pOverflow);    }    /* compute logarithm of prediction gain */    Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m, pOverflow);    /* convert exponent and mantissa to Word16 Q12 */    log_pg = shl(sub(log_pg_e, 15, pOverflow), 12, pOverflow); /* Q12 */    log_pg = shr(sub(0, add(log_pg, shr(log_pg_m, 15 - 12, pOverflow),                            pOverflow), pOverflow), 1, pOverflow);    st->log_pg_mean = add(mult(29491, st->log_pg_mean, pOverflow),                          mult(3277, log_pg, pOverflow), pOverflow);    /* Compute interpolated log energy */    L_log_en_int = L_shr(L_log_en_int, 10, pOverflow); /* Q26 -> Q16 */    /* Add 4 in Q16 */    L_log_en_int = L_add(L_log_en_int, 4 * 65536L, pOverflow);    /* subtract prediction gain */    L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4, pOverflow), pOverflow);    /* adjust level to speech coder mode */    L_log_en_int = L_add(L_log_en_int,                         L_shl(L_deposit_l(st->log_en_adjust), 5, pOverflow), pOverflow);    log_en_int_e = (Word16)(L_log_en_int >> 16);    log_en_int_m = (Word16)(L_shr(L_sub(L_log_en_int,                                        L_deposit_h(log_en_int_e), pOverflow), 1, pOverflow));    level = (Word16)(Pow2(log_en_int_e, log_en_int_m, pOverflow));  /* Q4 */    for (i = 0; i < 4; i++)    {        /* Compute innovation vector */        build_CN_code(&st->L_pn_seed_rx, ex, pOverflow);        for (j = L_SUBFR - 1; j >= 0; j--)        {            ex[j] = mult(level, ex[j], pOverflow);        }        /* Synthesize */        Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR,                 mem_syn, 1);    } /* next i */    /* reset codebook averaging variables */    averState->hangVar = 20;    averState->hangCount = 0;    if (new_state == DTX_MUTE)    {        /* mute comfort noise as it has been quite a long time since         * last SID update  was performed                            */        tmp_int_length = st->since_last_sid;        if (tmp_int_length > 32)        {            tmp_int_length = 32;        }        else if (tmp_int_length <= 0)        {            /* safety guard against division by zero */            tmp_int_length = 8;        }        L_temp = ((Word32) tmp_int_length) << 10;        if (L_temp != (Word32)((Word16) L_temp))        {            *pOverflow = 1;            L_temp = (Word32)((tmp_int_length > 0) ? MAX_16 : MIN_16);        }        temp = (Word16) L_temp;        st->true_sid_period_inv = div_s(1 << 10, temp);        st->since_last_sid = 0;        Copy(st->lsp, st->lsp_old, M);        st->old_log_en = st->log_en;        /* subtract 1/8 in Q11 i.e -6/8 dB */        st->log_en = sub(st->log_en, 256, pOverflow);    }    /* reset interpolation length timer     * if data has been updated.        */    if ((st->sid_frame != 0) &&            ((st->valid_data != 0) ||             ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0)))    {        st->since_last_sid =  0;        st->data_updated = 1;    }    return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: dtx_dec_activity_update------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs:    st = pointer to a structure of type dtx_decState    lsf =        frame = Outputs:    st points to an updated structure of type dtx_decState Returns:    None. Global Variables Used:    None. Local Variables Needed:    None.------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function updates the DTX parameters.------------------------------------------------------------------------------ REQUIREMENTS None------------------------------------------------------------------------------ REFERENCES dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoid dtx_dec_activity_update(dtx_decState *st,                             Word16 lsf[],                             Word16 frame[]){   Word16 i;   Word32 L_frame_en;   Word16 log_en_e, log_en_m, log_en;   // update lsp history   st->lsf_hist_ptr = add(st->lsf_hist_ptr,M);   if (sub(st->lsf_hist_ptr, 80) == 0)   {      st->lsf_hist_ptr = 0;   }   Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M);   // compute log energy based on frame energy   L_frame_en = 0;     // Q0   for (i=0; i < L_FRAME; i++)   {      L_frame_en = L_mac(L_frame_en, frame[i], frame[i]);   }   Log2(L_frame_en, &log_en_e, &log_en_m);   // convert exponent and mantissa to Word16 Q10   log_en = shl(log_en_e, 10);  // Q10   log_en = add(log_en, shr(log_en_m, 15-10));

⌨️ 快捷键说明

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