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

📄 cod_main.c

📁 通讯协议
💻 C
📖 第 1 页 / 共 5 页
字号:
         * Update signal for next frame.                    *
         * -> save past of speech[] and wsp[].              *
         *--------------------------------------------------*/

        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);

        return;
    }
    /*----------------------------------------------------------------------*
     *                               ACELP                                  *
     *----------------------------------------------------------------------*/

    /* Quantize and code the ISFs */

    test();
    if (sub(*ser_size, NBBITS_7k) <= 0)
    {
        Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4);

        Parm_serial(indice[0], 8, &prms);
        Parm_serial(indice[1], 8, &prms);
        Parm_serial(indice[2], 7, &prms);
        Parm_serial(indice[3], 7, &prms);
        Parm_serial(indice[4], 6, &prms);
    } else
    {
        Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4);

        Parm_serial(indice[0], 8, &prms);
        Parm_serial(indice[1], 8, &prms);
        Parm_serial(indice[2], 6, &prms);
        Parm_serial(indice[3], 7, &prms);
        Parm_serial(indice[4], 7, &prms);
        Parm_serial(indice[5], 5, &prms);
        Parm_serial(indice[6], 5, &prms);
    }

    /* Check stability on isf : distance between old isf and current isf */

    L_tmp = 0;                             move32();
    for (i = 0; i < M - 1; i++)
    {
        tmp = sub(isf[i], st->isfold[i]);
        L_tmp = L_mac(L_tmp, tmp, tmp);
    }

    tmp = extract_h(L_shl(L_tmp, 8));      /* saturation can occur here */

    tmp = mult(tmp, 26214);                /* tmp = L_tmp*0.8/256 */
    tmp = sub(20480, tmp);                 /* 1.25 - tmp (in Q14) */

    stab_fac = shl(tmp, 1);                /* saturation can occur here */

    test();
    if (stab_fac < 0)
    {
        stab_fac = 0;                      move16();
    }
    Copy(isf, st->isfold, M);

    /* Convert ISFs to the cosine domain */
    Isf_isp(isf, ispnew_q, M);

    test();
    if (st->first_frame != 0)
    {
        st->first_frame = 0;               move16();
        Copy(ispnew_q, st->ispold_q, M);
    }
    /* Find the interpolated ISPs and convert to a[] for all subframes */

    Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq);

    /* update ispold[] for the next frame */
    Copy(ispnew_q, st->ispold_q, M);

    p_Aq = Aq;
    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
    {
        Residu(p_Aq, M, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
        p_Aq += (M + 1);                   move16();
    }

    /* Buffer isf's and energy for dtx on non-speech frame */

    test();
    if (vad_flag == 0)
    {
        for (i = 0; i < L_FRAME; i++)
        {
            exc2[i] = shr(exc[i], Q_new);  move16();
        }
        L_tmp = 0;                         move32();
        for (i = 0; i < L_FRAME; i++)
            L_tmp = L_mac(L_tmp, exc2[i], exc2[i]);
        L_tmp = L_shr(L_tmp, 1);

        dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
    }
    /* range for closed loop pitch search in 1st subframe */

    T0_min = sub(T_op, 8);
    test();
    if (sub(T0_min, PIT_MIN) < 0)
    {
        T0_min = PIT_MIN;                  move16();
    }
    T0_max = add(T0_min, 15);
    test();
    if (sub(T0_max, PIT_MAX) > 0)
    {
        T0_max = PIT_MAX;                  move16();
        T0_min = sub(T0_max, 15);          move16();
    }
    /*------------------------------------------------------------------------*
     *          Loop for every subframe in the analysis frame                 *
     *------------------------------------------------------------------------*
     *  To find the pitch and innovation parameters. The subframe size is     *
     *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
     *     - compute the target signal for pitch search                       *
     *     - compute impulse response of weighted synthesis filter (h1[])     *
     *     - find the closed-loop pitch parameters                            *
     *     - encode the pitch dealy                                           *
     *     - find 2 lt prediction (with / without LP filter for lt pred)      *
     *     - find 2 pitch gains and choose the best lt prediction.            *
     *     - find target vector for codebook search                           *
     *     - update the impulse response h1[] for codebook search             *
     *     - correlation between target vector and impulse response           *
     *     - codebook search and encoding                                     *
     *     - VQ of pitch and codebook gains                                   *
     *     - find voicing factor and tilt of code for next subframe.          *
     *     - update states of weighting filter                                *
     *     - find excitation and synthesis speech                             *
     *------------------------------------------------------------------------*/

    p_A = A;                               move16();
    p_Aq = Aq;                             move16();

    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
    {
        pit_flag = i_subfr;                move16();
        test();test();
        if ((sub(i_subfr, 2 * L_SUBFR) == 0) && (sub(*ser_size, NBBITS_7k) > 0))
        {
            pit_flag = 0;                  move16();

            /* range for closed loop pitch search in 3rd subframe */

            T0_min = sub(T_op2, 8);
            test();
            if (sub(T0_min, PIT_MIN) < 0)
            {
                T0_min = PIT_MIN;          move16();
            }
            T0_max = add(T0_min, 15);
            test();
            if (sub(T0_max, PIT_MAX) > 0)
            {
                T0_max = PIT_MAX;          move16();
                T0_min = sub(T0_max, 15);
            }
        }
        /*-----------------------------------------------------------------------*
         *                                                                       *
         *        Find the target vector for pitch search:                       *
         *        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                        *
         *                                                                       *
         *             |------|  res[n]                                          *
         * speech[n]---| A(z) |--------                                          *
         *             |------|       |   |--------| error[n]  |------|          *
         *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
         *                   exc          |--------|           |------|          *
         *                                                                       *
         * Instead of subtracting the zero-input response of filters from        *
         * the weighted input speech, the above configuration is used to         *
         * compute the target vector.                                            *
         *                                                                       *
         *-----------------------------------------------------------------------*/

        for (i = 0; i < M; i++)
        {
            error[i] = sub(speech[i + i_subfr - M], st->mem_syn[i]);    move16();
        }
        Residu(p_Aq, M, &speech[i_subfr], &exc[i_subfr], L_SUBFR);

        Syn_filt(p_Aq, M, &exc[i_subfr], error + M, L_SUBFR, error, 0);

        Weight_a(p_A, Ap, GAMMA1, M);
        Residu(Ap, M, error + M, xn, L_SUBFR);

        Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0));

        /*----------------------------------------------------------------------*
         * Find approx. target in residual domain "cn[]" for inovation search.  *
         *----------------------------------------------------------------------*/

        /* first half: xn[] --> cn[] */
        Set_zero(code, M);
        Copy(xn, code + M, L_SUBFR / 2);
        tmp = 0;                           move16();
        Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
        Weight_a(p_A, Ap, GAMMA1, M);
        Syn_filt(Ap, M, code + M, code + M, L_SUBFR / 2, code, 0);
        Residu(p_Aq, M, code + M, cn, L_SUBFR / 2);

        /* second half: res[] --> cn[] (approximated and faster) */
        Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);

        /*---------------------------------------------------------------*
         * Compute impulse response, h1[], of weighted synthesis filter  *
         *---------------------------------------------------------------*/

        Set_zero(error, M + L_SUBFR);
        Weight_a(p_A, error + M, GAMMA1, M);

        for (i = 0; i < L_SUBFR; i++)
        {
            L_tmp = L_mult(error[i + M], 16384);        /* x4 (Q12 to Q14) */
            for (j = 1; j <= M; j++)
                L_tmp = L_msu(L_tmp, p_Aq[j], error[i + M - j]);

            h1[i] = error[i + M] = round(L_shl(L_tmp, 3));      move16();move16();
        }
        /* deemph without division by 2 -> Q14 to Q15 */
        tmp = 0;                           move16();
        Deemph2(h1, TILT_FAC, L_SUBFR, &tmp);   /* h1 in Q14 */

        /* h2 in Q12 for codebook search */
        Copy(h1, h2, L_SUBFR);
        Scale_sig(h2, L_SUBFR, -2);

        /*---------------------------------------------------------------*
         * scale xn[] and h1[] to avoid overflow in dot_product12()      *
         *---------------------------------------------------------------*/

        Scale_sig(xn, L_SUBFR, shift);     /* scaling of xn[] to limit dynamic at 12 bits */
        Scale_sig(h1, L_SUBFR, add(1, shift));  /* set h1[] in Q15 with scaling for convolution */

        /*----------------------------------------------------------------------*
         *                 Closed-loop fractional pitch search                  *
         *----------------------------------------------------------------------*/

        /* find closed loop fractional pitch  lag */

        test();
        if (sub(*ser_size, NBBITS_9k) <= 0)
        {
            T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
                pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR);

            /* encode pitch lag */

            test();
            if (pit_flag == 0)             /* if 1st/3rd subframe */
            {
                /*--------------------------------------------------------------*
                 * The pitch range for the 1st/3rd subframe is encoded with     *
                 * 8 bits and is divided as follows:                            *
                 *   PIT_MIN to PIT_FR1-1  resolution 1/2 (frac = 0 or 2)       *
                 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
                 *--------------------------------------------------------------*/

                test();
                if (sub(T0, PIT_FR1_8b) < 0)
                {
                    index = sub(add(shl(T0, 1), shr(T0_frac, 1)), (PIT_MIN * 2));
                } else
                {
                    index = add(sub(T0, PIT_FR1_8b), ((PIT_FR1_8b - PIT_MIN) * 2));
                }

                Parm_serial(index, 8, &prms);

                /* find T0_min and T0_max for subframe 2 and 4 */

                T0_min = sub(T0, 8);
                test();
                if (sub(T0_min, PIT_MIN) < 0)
                {
                    T0_min = PIT_MIN;      move16();
                }
                T0_max = add(T0_min, 15);
                test();
                if (sub(T0_max, PIT_MAX) > 0)
                {
                    T0_max = PIT_MAX;      move16();
                    T0_min = sub(T0_max, 15);
                }
            } else
            {                              /* if subframe 2 or 4 */
                /*--------------------------------------------------------------*
                 * The pitch range for subframe 2 or 4 is encoded with 5 bits:  *
                 *   T0_min  to T0_max     resolution 1/2 (frac = 0 or 2)       *
                 *--------------------------------------------------------------*/

                i = sub(T0, T0_min);
                index = add(shl(i, 1), shr(T0_frac, 1));

                Parm_serial(index, 5, &prms);
            }
        } else
        {
            T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
                pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR);

            /* encode pitch lag */

            test();
            if (pit_flag == 0)             /* if 1st/3rd subframe */
            {
                /*--------------------------------------------------------------*
                 * The pitch range for the 1st/3rd subframe is encoded with     *
                 * 9 bits and is divided as follows:                            *
                 *   PIT_MIN to PIT_FR2-1  resolution 1/4 (frac = 0,1,2 or 3)   *
                 *   PIT_FR2 to PIT_FR1-1  resolution 1/2 (frac = 0 or 1)       *
                 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
                 *--------------------------------------------------------------*/

                test();test();
                if (sub(T0, PIT_FR2) < 0)
                {
                    index = sub(add(shl(T0, 2), T0_frac), (PIT_MIN * 4));
                } else if (sub(T0, PIT_FR1_9b) < 0)
                {

⌨️ 快捷键说明

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