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

📄 dec_main.c

📁 通讯协议
💻 C
📖 第 1 页 / 共 3 页
字号:
    Isf_isp(isf, ispnew, M);
    test();
    if (st->first_frame != 0)
    {
        st->first_frame = 0;               move16();
        Copy(ispnew, st->ispold, M);
    }
    /* Find the interpolated ISPs and convert to a[] for all subframes */
    Int_isp(st->ispold, ispnew, interpol_frac, Aq);

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

    /* 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));
    tmp = mult(tmp, 26214);                /* tmp = L_tmp*0.8/256 */

    tmp = sub(20480, tmp);                 /* 1.25 - tmp */
    stab_fac = shl(tmp, 1);                /* Q14 -> Q15 with saturation */
    test();
    if (stab_fac < 0)
    {
        stab_fac = 0;                      move16();
    }
    Copy(st->isfold, isf_tmp, M);
    Copy(isf, st->isfold, M);

    /*------------------------------------------------------------------------*
     *          Loop for every subframe in the analysis frame                 *
     *------------------------------------------------------------------------*
     * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR  *
     *  times                                                                 *
     *     - decode the pitch delay and filter mode                           *
     *     - decode algebraic code                                            *
     *     - decode pitch and codebook gains                                  *
     *     - find voicing factor and tilt of code for next subframe.          *
     *     - find the excitation and compute synthesis speech                 *
     *------------------------------------------------------------------------*/

    p_Aq = Aq;                             move16();  /* pointer to interpolated LPC parameters */

    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(nb_bits, NBBITS_7k) > 0))
        {
            pit_flag = 0;                  move16();
        }
        /*-------------------------------------------------*
         * - Decode pitch lag                              *
         * Lag indeces received also in case of BFI,       *
         * so that the parameter pointer stays in sync.    *
         *-------------------------------------------------*/
        test();
        if (pit_flag == 0)
        {
            test();
            if (sub(nb_bits, NBBITS_9k) <= 0)
            {
                index = Serial_parm(8, &prms);
                test();
                if (sub(index, (PIT_FR1_8b - PIT_MIN) * 2) < 0)
                {
                    T0 = add(PIT_MIN, shr(index, 1));
                    T0_frac = sub(index, shl(sub(T0, PIT_MIN), 1));
                    T0_frac = shl(T0_frac, 1);
                } else
                {
                    T0 = add(index, PIT_FR1_8b - ((PIT_FR1_8b - PIT_MIN) * 2));
                    T0_frac = 0;           move16();
                }
            } else
            {
                index = Serial_parm(9, &prms);
                test();test();
                if (sub(index, (PIT_FR2 - PIT_MIN) * 4) < 0)
                {
                    T0 = add(PIT_MIN, shr(index, 2));
                    T0_frac = sub(index, shl(sub(T0, PIT_MIN), 2));
                } else if (sub(index, (((PIT_FR2 - PIT_MIN) * 4) + ((PIT_FR1_9b - PIT_FR2) * 2))) < 0)
                {
                    index = sub(index, (PIT_FR2 - PIT_MIN) * 4);
                    T0 = add(PIT_FR2, shr(index, 1));
                    T0_frac = sub(index, shl(sub(T0, PIT_FR2), 1));
                    T0_frac = shl(T0_frac, 1);
                } else
                {
                    T0 = add(index, (PIT_FR1_9b - ((PIT_FR2 - PIT_MIN) * 4) - ((PIT_FR1_9b - PIT_FR2) * 2)));
                    T0_frac = 0;           move16();
                }
            }

            /* 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 */
            test();
            if (sub(nb_bits, NBBITS_9k) <= 0)
            {
                index = Serial_parm(5, &prms);

                T0 = add(T0_min, shr(index, 1));
                T0_frac = sub(index, shl(sub(T0, T0_min), 1));
                T0_frac = shl(T0_frac, 1);
            } else
            {
                index = Serial_parm(6, &prms);

                T0 = add(T0_min, shr(index, 2));
                T0_frac = sub(index, shl(sub(T0, T0_min), 2));
            }
        }

        /* check BFI after pitch lag decoding */
        test();
        if (bfi != 0)                      /* if frame erasure */
        {
            lagconc(&(st->dec_gain[17]), st->lag_hist, &T0, &(st->old_T0), &(st->seed3), unusable_frame);
            T0_frac = 0;                   move16();
        }
        /*-------------------------------------------------*
         * - Find the pitch gain, the interpolation filter *
         *   and the adaptive codebook vector.             *
         *-------------------------------------------------*/

        Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);

        test();
        if (unusable_frame)
        {
            select = 1;                    move16();
        } else
        {
            test();
            if (sub(nb_bits, NBBITS_9k) <= 0)
            {
                select = 0;                move16();
            } else
            {
                select = Serial_parm(1, &prms);
            }
        }

        test();
        if (select == 0)
        {
            /* find pitch excitation with lp filter */
            for (i = 0; i < L_SUBFR; i++)
            {
                L_tmp = L_mult(5898, exc[i - 1 + i_subfr]);
                L_tmp = L_mac(L_tmp, 20972, exc[i + i_subfr]);
                L_tmp = L_mac(L_tmp, 5898, exc[i + 1 + i_subfr]);
                code[i] = round(L_tmp);    move16();
            }
            Copy(code, &exc[i_subfr], L_SUBFR);
        }
        /*-------------------------------------------------------*
         * - Decode innovative codebook.                         *
         * - Add the fixed-gain pitch contribution to code[].    *
         *-------------------------------------------------------*/
        test();test();test();test();test();test();test();test();
        if (unusable_frame != 0)
        {
            /* the innovative code doesn't need to be scaled (see Q_gain2) */
            for (i = 0; i < L_SUBFR; i++)
            {
                code[i] = shr(Random(&(st->seed)), 3);  move16();
            }
        } else if (sub(nb_bits, NBBITS_7k) <= 0)
        {
            ind[0] = Serial_parm(12, &prms);    move16();
            DEC_ACELP_2t64_fx(ind[0], code);
        } else if (sub(nb_bits, NBBITS_9k) <= 0)
        {
            for (i = 0; i < 4; i++)
            {
                ind[i] = Serial_parm(5, &prms); move16();
            }
            DEC_ACELP_4t64_fx(ind, 20, code);
        } else if (sub(nb_bits, NBBITS_12k) <= 0)
        {
            for (i = 0; i < 4; i++)
            {
                ind[i] = Serial_parm(9, &prms); move16();
            }
            DEC_ACELP_4t64_fx(ind, 36, code);
        } else if (sub(nb_bits, NBBITS_14k) <= 0)
        {
            ind[0] = Serial_parm(13, &prms);    move16();
            ind[1] = Serial_parm(13, &prms);    move16();
            ind[2] = Serial_parm(9, &prms);move16();
            ind[3] = Serial_parm(9, &prms);move16();
            DEC_ACELP_4t64_fx(ind, 44, code);
        } else if (sub(nb_bits, NBBITS_16k) <= 0)
        {
            for (i = 0; i < 4; i++)
            {
                ind[i] = Serial_parm(13, &prms);        move16();
            }
            DEC_ACELP_4t64_fx(ind, 52, code);
        } else if (sub(nb_bits, NBBITS_18k) <= 0)
        {
            for (i = 0; i < 4; i++)
            {
                ind[i] = Serial_parm(2, &prms); move16();
            }
            for (i = 4; i < 8; i++)
            {
                ind[i] = Serial_parm(14, &prms);        move16();
            }
            DEC_ACELP_4t64_fx(ind, 64, code);
        } else if (sub(nb_bits, NBBITS_20k) <= 0)
        {
            ind[0] = Serial_parm(10, &prms);    move16();
            ind[1] = Serial_parm(10, &prms);    move16();
            ind[2] = Serial_parm(2, &prms);move16();
            ind[3] = Serial_parm(2, &prms);move16();
            ind[4] = Serial_parm(10, &prms);    move16();
            ind[5] = Serial_parm(10, &prms);    move16();
            ind[6] = Serial_parm(14, &prms);    move16();
            ind[7] = Serial_parm(14, &prms);    move16();
            DEC_ACELP_4t64_fx(ind, 72, code);
        } else
        {
            for (i = 0; i < 4; i++)
            {
                ind[i] = Serial_parm(11, &prms);        move16();
            }
            for (i = 4; i < 8; i++)
            {
                ind[i] = Serial_parm(11, &prms);        move16();
            }
            DEC_ACELP_4t64_fx(ind, 88, code);
        }

        tmp = 0;                           move16();
        Preemph(code, st->tilt_code, L_SUBFR, &tmp);

        tmp = T0;                          move16();
        test();
        if (sub(T0_frac, 2) > 0)
        {
            tmp = add(tmp, 1);
        }
        Pit_shrp(code, tmp, PIT_SHARP, L_SUBFR);

        /*-------------------------------------------------*
         * - Decode codebooks gains.                       *
         *-------------------------------------------------*/
        test();
        if (sub(nb_bits, NBBITS_9k) <= 0)
        {
            index = Serial_parm(6, &prms); /* codebook gain index */

            D_gain2(index, 6, code, L_SUBFR, &gain_pit, &L_gain_code, bfi, st->prev_bfi, st->state, unusable_frame, st->vad_hist, st->dec_gain);
        } else
        {
            index = Serial_parm(7, &prms); /* codebook gain index */

            D_gain2(index, 7, code, L_SUBFR, &gain_pit, &L_gain_code, bfi, st->prev_bfi, st->state, unusable_frame, st->vad_hist, st->dec_gain);
        }

        /* find best scaling to perform on excitation (Q_new) */

        tmp = st->Qsubfr[0];
        for (i = 1; i < 4; i++)
        {
            test();move16();
            if (sub(st->Qsubfr[i], tmp) < 0)
            {
                tmp = st->Qsubfr[i];       move16();
            }
        }

        /* limit scaling (Q_new) to Q_MAX: see cnst.h and syn_filt_32() */
        test();
        if (sub(tmp, Q_MAX) > 0)
        {
            tmp = Q_MAX;                   move16();
        }
        Q_new = 0;                         move16();
        L_tmp = L_gain_code;               move32();  /* L_gain_code in Q16 */

        test();test();
        while ((L_sub(L_tmp, 0x08000000L) < 0) && (sub(Q_new, tmp) < 0))
        {
            L_tmp = L_shl(L_tmp, 1);
            Q_new = add(Q_new, 1);
            test();test();
        }
        gain_code = round(L_tmp);          /* scaled gain_code with Qnew */

        Scale_sig(exc + i_subfr - (PIT_MAX + L_INTERPOL),
            PIT_MAX + L_INTERPOL + L_SUBFR, sub(Q_new, st->Q_old));
        st->Q_old = Q_new;                 move16();


        /*----------------------------------------------------------*
         * Update parameters for the next subframe.                 *
         * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)           *
         *----------------------------------------------------------*/

        test();
        if (bfi == 0)
        {
            /* LTP-Lag history update */
            for (i = 4; i > 0; i--)
            {
                st->lag_hist[i] = st->lag_hist[i - 1];  move16();
            }
            st->lag_hist[0] = T0;          move16();

            st->old_T0 = T0;               move16();
            st->old_T0_frac = 0;           move16();  /* Remove fraction in case of BFI */
        }
        /* find voice factor in Q15 (1=voiced, -1=unvoiced) */

        Copy(&exc[i_subfr], exc2, L_SUBFR);
        Scale_sig(exc2, L_SUBFR, -3);

        /* post processing of excitation elements */
        test();
        if (sub(nb_bits, NBBITS_9k) <= 0)
        {
            pit_sharp = shl(gain_pit, 1);
            test();
            if (sub(pit_sharp, 16384) > 0)
            {
                for (i = 0; i < L_SUBFR; i++)
                {
                    tmp = mult(exc2[i], pit_sharp);
                    L_tmp = L_mult(tmp, gain_pit);
                    L_tmp = L_shr(L_tmp, 1);
                    excp[i] = round(L_tmp);
                    move16();
                }
            }
        } else
        {
            pit_sharp = 0;                 move16();
        }

        voice_fac = voice_factor(exc2, -3, gain_pit, code, gain_code, L_SUBFR);

        /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */

        st->tilt_code = add(shr(voice_fac, 2), 8192);   move16();

        /*-------------------------------------------------------*
         * - Find the total excitation.                          *
         * - Find synthesis speech corresponding to exc[].       *
         *-------------------------------------------------------*/

        Copy(&exc[i_subfr], exc2, L_SUBFR);

        for (i = 0; i < L_SUBFR; i++)
        {
            L_tmp = L_mult(code[i], gain_code);
            L_tmp = L_shl(L_tmp, 5);
            L_tmp = L_mac(L_tmp, exc[i + i_subfr], gain_pit);

⌨️ 快捷键说明

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