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

📄 dec_main.c

📁 通讯协议
💻 C
📖 第 1 页 / 共 3 页
字号:
            L_tmp = L_shl(L_tmp, 1);
            exc[i + i_subfr] = round(L_tmp);    move16();
        }

        /* find maximum value of excitation for next scaling */

        max = 1;                           move16();
        for (i = 0; i < L_SUBFR; i++)
        {
            tmp = abs_s(exc[i + i_subfr]);
            test();
            if (sub(tmp, max) > 0)
            {
                max = tmp;                 move16();
            }
        }

        /* tmp = scaling possible according to max value of excitation */
        tmp = sub(add(norm_s(max), Q_new), 1);

        st->Qsubfr[3] = st->Qsubfr[2];     move16();
        st->Qsubfr[2] = st->Qsubfr[1];     move16();
        st->Qsubfr[1] = st->Qsubfr[0];     move16();
        st->Qsubfr[0] = tmp;               move16();

        /*------------------------------------------------------------*
         * phase dispersion to enhance noise in low bit rate          *
         *------------------------------------------------------------*/

        /* L_gain_code in Q16 */
        L_Extract(L_gain_code, &gain_code, &gain_code_lo);
        test();test();move16();
        if (sub(nb_bits, NBBITS_7k) <= 0)
            j = 0;                         /* high dispersion for rate <= 7.5 kbit/s */
        else if (sub(nb_bits, NBBITS_9k) <= 0)
            j = 1;                         /* low dispersion for rate <= 9.6 kbit/s */
        else
            j = 2;                         /* no dispersion for rate > 9.6 kbit/s */

        Phase_dispersion(gain_code, gain_pit, code, j, st->disp_mem);

        /*------------------------------------------------------------*
         * 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();
        }

        if (sub(nb_bits, NBBITS_9k) <= 0)
        {
            if (sub(pit_sharp, 16384) > 0)
            {
                for (i = 0; i < L_SUBFR; i++)
                {
                    excp[i] = add(excp[i], exc2[i]);
                    move16();
                }
                agc2(exc2, excp, L_SUBFR);
                Copy(excp, exc2, L_SUBFR);
            }
        }
        if (sub(nb_bits, NBBITS_7k) <= 0)
        {
            j = shr(i_subfr, 6);
            for (i = 0; i < M; i++)
            {
                L_tmp = L_mult(isf_tmp[i], sub(32767, interpol_frac[j]));
                L_tmp = L_mac(L_tmp, isf[i], interpol_frac[j]);
                HfIsf[i] = round(L_tmp);
            }
        } else
        {
            Set_zero(st->mem_syn_hf, M16k - M);
        }

        if (sub(nb_bits, NBBITS_24k) >= 0)
        {
            corr_gain = Serial_parm(4, &prms);
            synthesis(p_Aq, exc2, Q_new, &synth16k[i_subfr * 5 / 4], corr_gain, HfIsf, nb_bits, newDTXState, st, bfi);
        } else
            synthesis(p_Aq, exc2, Q_new, &synth16k[i_subfr * 5 / 4], 0, HfIsf, nb_bits, newDTXState, st, bfi);

        p_Aq += (M + 1);                   /* interpolated LPC parameters for next subframe */
    }

    /*--------------------------------------------------*
     * Update signal for next frame.                    *
     * -> save past of exc[].                           *
     * -> save pitch parameters.                        *
     *--------------------------------------------------*/

    Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);

    Scale_sig(exc, L_FRAME, sub(0, Q_new));
    dtx_dec_activity_update(st->dtx_decSt, isf, exc);

    st->dtx_decSt->dtxGlobalState = newDTXState;        move16();

    st->prev_bfi = bfi;                    move16();

    return;
}



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

static void 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     */
     Word16 prms,                          /* (i)   : parameter                  */
     Word16 HfIsf[],
     Word16 nb_bits,
     Word16 newDTXState,
     Decoder_State * st,                   /* (i/o) : State structure            */
     Word16 bfi                            /* (i)   : bad frame indicator        */
)
{
    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[M16k + 1];
    Word16 HfA[M16k + 1];
    Word16 HF_corr_gain;
    Word16 HF_gain_ind;
    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);

    Oversamp_16k(synth, L_SUBFR, synth16k, st->mem_oversamp);

    /*------------------------------------------------------*
    * 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;                       move16();
        weight2 = 32767;                   move16();
    } else
    {
        weight1 = 32767;                   move16();
        weight2 = 0;                       move16();
    }
    tmp = mult(weight1, gain1);
    tmp = add(tmp, mult(weight2, gain2));

    test();
    if (tmp != 0)
    {
        tmp = add(tmp, 1);
    }
    test();
    if (sub(tmp, 3277) < 0)
    {
        tmp = 3277;                        /* 0.1 in Q15 */
        move16();
    }
    test(); test();
    if ((sub(nb_bits, NBBITS_24k) >= 0 ) && (bfi == 0))
    {
        /* HF correction gain */
        HF_gain_ind = prms;
        HF_corr_gain = HP_gain[HF_gain_ind];

        /* HF gain */
        for (i = 0; i < L_SUBFR16k; i++)
        {
            HF[i] = shl(mult(HF[i], HF_corr_gain), 1);  move16();
        }
    } else
    {
        for (i = 0; i < L_SUBFR16k; i++)
        {
            HF[i] = mult(HF[i], tmp);      move16();
        }
    }

    test();test();
    if ((sub(nb_bits, NBBITS_7k) <= 0) && (sub(newDTXState, SPEECH) == 0))
    {
        Isf_Extrapolation(HfIsf);
        Isp_Az(HfIsf, HfA, M16k, 0);

        Weight_a(HfA, Ap, 29491, M16k);    /* fac=0.9 */
        Syn_filt(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
    } else
    {
        /* 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 + (M16k - M), 1);
    }

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

    test();
    if (sub(nb_bits, NBBITS_24k) >= 0)
    {
        /* Low Pass filtering (7 kHz) */
        Filt_7k(HF, L_SUBFR16k, st->mem_hf3);
    }
    /* add filtered HF noise to speech synthesis */
    for (i = 0; i < L_SUBFR16k; i++)
    {
        synth16k[i] = add(synth16k[i], HF[i]);  move16();
    }

    return;
}

⌨️ 快捷键说明

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