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

📄 cod_main.c

📁 通讯协议
💻 C
📖 第 1 页 / 共 5 页
字号:
            L_Extract(L_gain_code, &gain_code, &gain_code_lo);

            /*------------------------------------------------------------*
             * noise enhancer                                             *
             * ~~~~~~~~~~~~~~                                             *
             * - Enhance excitation on noise. (modify gain of code)       *
             *   If signal is noisy and LPC filter is stable, move gain   *
             *   of code 1.5 dB toward gain of code threshold.            *
             *   This decrease by 3 dB noise energy variation.            *
             *------------------------------------------------------------*/

            tmp = sub(16384, shr(voice_fac, 1));        /* 1=unvoiced, 0=voiced */
            fac = mult(stab_fac, tmp);

            L_tmp = L_gain_code;           move32();
            test();
            if (L_sub(L_tmp, st->L_gc_thres) < 0)
            {
                L_tmp = L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
                test();
                if (L_sub(L_tmp, st->L_gc_thres) > 0)
                {
                    L_tmp = st->L_gc_thres;move32();
                }
            } else
            {
                L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
                test();
                if (L_sub(L_tmp, st->L_gc_thres) < 0)
                {
                    L_tmp = st->L_gc_thres;move32();
                }
            }
            st->L_gc_thres = L_tmp;        move32();

            L_gain_code = Mpy_32_16(gain_code, gain_code_lo, sub(32767, fac));
            L_Extract(L_tmp, &gain_code, &gain_code_lo);
            L_gain_code = L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));

            /*------------------------------------------------------------*
             * pitch enhancer                                             *
             * ~~~~~~~~~~~~~~                                             *
             * - Enhance excitation on voice. (HP filtering of code)      *
             *   On voiced signal, filtering of code by a smooth fir HP   *
             *   filter to decrease energy of code in low frequency.      *
             *------------------------------------------------------------*/

            tmp = add(shr(voice_fac, 3), 4096); /* 0.25=voiced, 0=unvoiced */

            L_tmp = L_deposit_h(code[0]);
            L_tmp = L_msu(L_tmp, code[1], tmp);
            code2[0] = round(L_tmp);       move16();

            for (i = 1; i < L_SUBFR - 1; i++)
            {
                L_tmp = L_deposit_h(code[i]);
                L_tmp = L_msu(L_tmp, code[i + 1], tmp);
                L_tmp = L_msu(L_tmp, code[i - 1], tmp);
                code2[i] = round(L_tmp);   move16();
            }

            L_tmp = L_deposit_h(code[L_SUBFR - 1]);
            L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);
            code2[L_SUBFR - 1] = round(L_tmp);  move16();

            /* build excitation */

            gain_code = round(L_shl(L_gain_code, Q_new));

            for (i = 0; i < L_SUBFR; i++)
            {
                L_tmp = L_mult(code2[i], gain_code);
                L_tmp = L_shl(L_tmp, 5);
                L_tmp = L_mac(L_tmp, exc2[i], gain_pit);
                L_tmp = L_shl(L_tmp, 1);   /* saturation can occur here */
                exc2[i] = round(L_tmp);    move16();
            }

            corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
            Parm_serial(corr_gain, 4, &prms);
        }
        p_A += (M + 1);
        move16();
        p_Aq += (M + 1);
        move16();

    }                                      /* end of subframe loop */

    /*--------------------------------------------------*
     * Update signal for next frame.                    *
     * -> save past of speech[], wsp[] and exc[].       *
     *--------------------------------------------------*/

    Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
    Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
    Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);

    return;
}

/*-----------------------------------------------------*
 * Function synthesis()                                *
 *                                                     *
 * Synthesis of signal at 16kHz with HF extension.     *
 *                                                     *
 *-----------------------------------------------------*/

static Word16 synthesis(
     Word16 Aq[],                          /* A(z)  : quantized Az               */
     Word16 exc[],                         /* (i)   : excitation at 12kHz        */
     Word16 Q_new,                         /* (i)   : scaling performed on exc   */
     Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
     Coder_State * st                      /* (i/o) : State structure            */
)
{
    Word16 i, fac, tmp, exp;
    Word16 ener, exp_ener;
    Word32 L_tmp;

    Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
    Word16 synth[L_SUBFR];
    Word16 HF[L_SUBFR16k];                 /* High Frequency vector      */
    Word16 Ap[M + 1];

    Word16 HF_SP[L_SUBFR16k];              /* High Frequency vector (from original signal) */

    Word16 HP_est_gain, HP_calc_gain, HP_corr_gain;
    Word16 dist_min, dist;
    Word16 HP_gain_ind = 0;
    Word16 gain1, gain2;
    Word16 weight1, weight2;

    /*------------------------------------------------------------*
     * speech synthesis                                           *
     * ~~~~~~~~~~~~~~~~                                           *
     * - Find synthesis speech corresponding to exc2[].           *
     * - Perform fixed deemphasis and hp 50hz filtering.          *
     * - Oversampling from 12.8kHz to 16kHz.                      *
     *------------------------------------------------------------*/


    Copy(st->mem_syn_hi, synth_hi, M);
    Copy(st->mem_syn_lo, synth_lo, M);

    Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);

    Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
    Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);

    Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));

    HP50_12k8(synth, L_SUBFR, st->mem_sig_out);

    /* Original speech signal as reference for high band gain quantisation */
    for (i = 0; i < L_SUBFR16k; i++)
    {
        HF_SP[i] = synth16k[i];            move16();
    }

    /*------------------------------------------------------*
     * HF noise synthesis                                   *
     * ~~~~~~~~~~~~~~~~~~                                   *
     * - Generate HF noise between 5.5 and 7.5 kHz.         *
     * - Set energy of noise according to synthesis tilt.   *
     *     tilt > 0.8 ==> - 14 dB (voiced)                  *
     *     tilt   0.5 ==> - 6 dB  (voiced or noise)         *
     *     tilt < 0.0 ==>   0 dB  (noise)                   *
     *------------------------------------------------------*/

    /* generate white noise vector */
    for (i = 0; i < L_SUBFR16k; i++)
    {
        HF[i] = shr(Random(&(st->seed2)), 3);   move16();
    }

    /* energy of excitation */

    Scale_sig(exc, L_SUBFR, -3);
    Q_new = sub(Q_new, 3);

    ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
    exp_ener = sub(exp_ener, add(Q_new, Q_new));

    /* set energy of white noise to energy of excitation */

    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));

    test();
    if (sub(tmp, ener) > 0)
    {
        tmp = shr(tmp, 1);                 /* Be sure tmp < ener */
        exp = add(exp, 1);
    }
    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
    exp = sub(exp, exp_ener);
    Isqrt_n(&L_tmp, &exp);
    L_tmp = L_shl(L_tmp, add(exp, 1));     /* L_tmp x 2, L_tmp in Q31 */
    tmp = extract_h(L_tmp);                /* tmp = 2 x sqrt(ener_exc/ener_hf) */

    for (i = 0; i < L_SUBFR16k; i++)
    {
        HF[i] = mult(HF[i], tmp);          move16();
    }

    /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */

    HP400_12k8(synth, L_SUBFR, st->mem_hp400);

    L_tmp = 1L;                            move32();
    for (i = 0; i < L_SUBFR; i++)
        L_tmp = L_mac(L_tmp, synth[i], synth[i]);

    exp = norm_l(L_tmp);
    ener = extract_h(L_shl(L_tmp, exp));   /* ener = r[0] */

    L_tmp = 1L;                            move32();
    for (i = 1; i < L_SUBFR; i++)
        L_tmp = L_mac(L_tmp, synth[i], synth[i - 1]);

    tmp = extract_h(L_shl(L_tmp, exp));    /* tmp = r[1] */

    test();
    if (tmp > 0)
    {
        fac = div_s(tmp, ener);
    } else
    {
        fac = 0;                           move16();
    }


    /* modify energy of white noise according to synthesis tilt */
    gain1 = sub(32767, fac);
    gain2 = mult(sub(32767, fac), 20480);
    gain2 = shl(gain2, 1);

    test();
    if (st->vad_hist > 0)
    {
        weight1 = 0;
        weight2 = 32767;
    } else
    {
        weight1 = 32767;
        weight2 = 0;
    }
    tmp = mult(weight1, gain1);
    tmp = add(tmp, mult(weight2, gain2));

    test();
    if (tmp != 0)
    {
        tmp = add(tmp, 1);
    }
    HP_est_gain = tmp;

    test();
    if (sub(HP_est_gain, 3277) < 0)
    {
        HP_est_gain = 3277;                /* 0.1 in Q15 */
        move16();
    }
    /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
    Weight_a(Aq, Ap, 19661, M);            /* fac=0.6 */
    Syn_filt(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);

    /* noise High Pass filtering (1ms of delay) */
    Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);

    /* filtering of the original signal */
    Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2);

    /* check the gain difference */
    Scale_sig(HF_SP, L_SUBFR16k, -1);

    ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));

    /* set energy of white noise to energy of excitation */
    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));

    test();
    if (sub(tmp, ener) > 0)
    {
        tmp = shr(tmp, 1);                 /* Be sure tmp < ener */
        exp = add(exp, 1);
    }
    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
    exp = sub(exp, exp_ener);
    Isqrt_n(&L_tmp, &exp);
    L_tmp = L_shl(L_tmp, exp);             /* L_tmp, L_tmp in Q31 */
    HP_calc_gain = extract_h(L_tmp);       /* tmp = sqrt(ener_input/ener_hf) */

    /* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */
    L_tmp = L_shl(L_mult(st->dtx_encSt->dtxHangoverCount, 4681), 15);
    st->gain_alpha = mult(st->gain_alpha, extract_h(L_tmp));

    test();
    if (sub(st->dtx_encSt->dtxHangoverCount, 6) > 0)
        st->gain_alpha = 32767;
    HP_est_gain = shr(HP_est_gain, 1);     /* From Q15 to Q14 */
    HP_corr_gain = add(mult(HP_calc_gain, st->gain_alpha), mult(sub(32767, st->gain_alpha), HP_est_gain));

    /* Quantise the correction gain */
    dist_min = 32767;
    for (i = 0; i < 16; i++)
    {
        dist = mult(sub(HP_corr_gain, HP_gain[i]), sub(HP_corr_gain, HP_gain[i]));
        test();
        if (dist_min > dist)
        {
            dist_min = dist;
            HP_gain_ind = i;
        }
    }

    HP_corr_gain = HP_gain[HP_gain_ind];

    /* return the quantised gain index when using the highest mode, otherwise zero */
    return (HP_gain_ind);

}

⌨️ 快捷键说明

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