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

📄 ps_dec.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 5 页
字号:

    /* coarse */
    if (stride == 2)
    {
        index[0] = 0;
        for (i = (nr_par<<1)-1; i > 0; i--)
        {
            index[i] = index[i>>1];
        }
    }
}

#ifdef PS_LOW_POWER
static void map34indexto20(int8_t *index, uint8_t bins)
{
    index[0] = (2*index[0]+index[1])/3;
    index[1] = (index[1]+2*index[2])/3;
    index[2] = (2*index[3]+index[4])/3;
    index[3] = (index[4]+2*index[5])/3;
    index[4] = (index[6]+index[7])/2;
    index[5] = (index[8]+index[9])/2;
    index[6] = index[10];
    index[7] = index[11];
    index[8] = (index[12]+index[13])/2;
    index[9] = (index[14]+index[15])/2;
    index[10] = index[16];

    if (bins == 34)
    {
        index[11] = index[17];
        index[12] = index[18];
        index[13] = index[19];
        index[14] = (index[20]+index[21])/2;
        index[15] = (index[22]+index[23])/2;
        index[16] = (index[24]+index[25])/2;
        index[17] = (index[26]+index[27])/2;
        index[18] = (index[28]+index[29]+index[30]+index[31])/4;
        index[19] = (index[32]+index[33])/2;
    }
}
#endif

static void map20indexto34(int8_t *index, uint8_t bins)
{
    index[0] = index[0];
    index[1] = (index[0] + index[1])/2;
    index[2] = index[1];
    index[3] = index[2];
    index[4] = (index[2] + index[3])/2;
    index[5] = index[3];
    index[6] = index[4];
    index[7] = index[4];
    index[8] = index[5];
    index[9] = index[5];
    index[10] = index[6];
    index[11] = index[7];
    index[12] = index[8];
    index[13] = index[8];
    index[14] = index[9];
    index[15] = index[9];
    index[16] = index[10];

    if (bins == 34)
    {
        index[17] = index[11];
        index[18] = index[12];
        index[19] = index[13];
        index[20] = index[14];
        index[21] = index[14];
        index[22] = index[15];
        index[23] = index[15];
        index[24] = index[16];
        index[25] = index[16];
        index[26] = index[17];
        index[27] = index[17];
        index[28] = index[18];
        index[29] = index[18];
        index[30] = index[18];
        index[31] = index[18];
        index[32] = index[19];
        index[33] = index[19];
    }
}

/* parse the bitstream data decoded in ps_data() */
static void ps_data_decode(ps_info *ps)
{
    uint8_t env, bin;

    /* ps data not available, use data from previous frame */
    if (ps->ps_data_available == 0)
    {
        ps->num_env = 0;
    }

    for (env = 0; env < ps->num_env; env++)
    {
        int8_t *iid_index_prev;
        int8_t *icc_index_prev;
        int8_t *ipd_index_prev;
        int8_t *opd_index_prev;

        int8_t num_iid_steps = (ps->iid_mode < 3) ? 7 : 15 /*fine quant*/;

        if (env == 0)
        {
            /* take last envelope from previous frame */
            iid_index_prev = ps->iid_index_prev;
            icc_index_prev = ps->icc_index_prev;
            ipd_index_prev = ps->ipd_index_prev;
            opd_index_prev = ps->opd_index_prev;
        } else {
            /* take index values from previous envelope */
            iid_index_prev = ps->iid_index[env - 1];
            icc_index_prev = ps->icc_index[env - 1];
            ipd_index_prev = ps->ipd_index[env - 1];
            opd_index_prev = ps->opd_index[env - 1];
        }

//        iid = 1;
        /* delta decode iid parameters */
        delta_decode(ps->enable_iid, ps->iid_index[env], iid_index_prev,
            ps->iid_dt[env], ps->nr_iid_par,
            (ps->iid_mode == 0 || ps->iid_mode == 3) ? 2 : 1,
            -num_iid_steps, num_iid_steps);
//        iid = 0;

        /* delta decode icc parameters */
        delta_decode(ps->enable_icc, ps->icc_index[env], icc_index_prev,
            ps->icc_dt[env], ps->nr_icc_par,
            (ps->icc_mode == 0 || ps->icc_mode == 3) ? 2 : 1,
            0, 7);

        /* delta modulo decode ipd parameters */
        delta_modulo_decode(ps->enable_ipdopd, ps->ipd_index[env], ipd_index_prev,
            ps->ipd_dt[env], ps->nr_ipdopd_par, 1, /*log2(8)*/ 3);

        /* delta modulo decode opd parameters */
        delta_modulo_decode(ps->enable_ipdopd, ps->opd_index[env], opd_index_prev,
            ps->opd_dt[env], ps->nr_ipdopd_par, 1, /*log2(8)*/ 3);
    }

    /* handle error case */
    if (ps->num_env == 0)
    {
        /* force to 1 */
        ps->num_env = 1;

        if (ps->enable_iid)
        {
            for (bin = 0; bin < 34; bin++)
                ps->iid_index[0][bin] = ps->iid_index_prev[bin];
        } else {
            for (bin = 0; bin < 34; bin++)
                ps->iid_index[0][bin] = 0;
        }

        if (ps->enable_icc)
        {
            for (bin = 0; bin < 34; bin++)
                ps->icc_index[0][bin] = ps->icc_index_prev[bin];
        } else {
            for (bin = 0; bin < 34; bin++)
                ps->icc_index[0][bin] = 0;
        }

        if (ps->enable_ipdopd)
        {
            for (bin = 0; bin < 17; bin++)
            {
                ps->ipd_index[0][bin] = ps->ipd_index_prev[bin];
                ps->opd_index[0][bin] = ps->opd_index_prev[bin];
            }
        } else {
            for (bin = 0; bin < 17; bin++)
            {
                ps->ipd_index[0][bin] = 0;
                ps->opd_index[0][bin] = 0;
            }
        }
    }

    /* update previous indices */
    for (bin = 0; bin < 34; bin++)
        ps->iid_index_prev[bin] = ps->iid_index[ps->num_env-1][bin];
    for (bin = 0; bin < 34; bin++)
        ps->icc_index_prev[bin] = ps->icc_index[ps->num_env-1][bin];
    for (bin = 0; bin < 17; bin++)
    {
        ps->ipd_index_prev[bin] = ps->ipd_index[ps->num_env-1][bin];
        ps->opd_index_prev[bin] = ps->opd_index[ps->num_env-1][bin];
    }

    ps->ps_data_available = 0;

    if (ps->frame_class == 0)
    {
        ps->border_position[0] = 0;
        for (env = 1; env < ps->num_env; env++)
        {
            ps->border_position[env] = (env * 32 /* 30 for 960? */) / ps->num_env;
        }
        ps->border_position[ps->num_env] = 32 /* 30 for 960? */;
    } else {
        ps->border_position[0] = 0;

        if (ps->border_position[ps->num_env] < 32 /* 30 for 960? */)
        {
            ps->num_env++;
            ps->border_position[ps->num_env] = 32 /* 30 for 960? */;
            for (bin = 0; bin < 34; bin++)
            {
                ps->iid_index[ps->num_env][bin] = ps->iid_index[ps->num_env-1][bin];
                ps->icc_index[ps->num_env][bin] = ps->icc_index[ps->num_env-1][bin];
            }
            for (bin = 0; bin < 17; bin++)
            {
                ps->ipd_index[ps->num_env][bin] = ps->ipd_index[ps->num_env-1][bin];
                ps->opd_index[ps->num_env][bin] = ps->opd_index[ps->num_env-1][bin];
            }
        }

        for (env = 1; env < ps->num_env; env++)
        {
            int8_t thr = 32 /* 30 for 960? */ - (ps->num_env - env);

            if (ps->border_position[env] > thr)
            {
                ps->border_position[env] = thr;
            } else {
                thr = ps->border_position[env-1]+1;
                if (ps->border_position[env] < thr)
                {
                    ps->border_position[env] = thr;
                }
            }
        }
    }

    /* make sure that the indices of all parameters can be mapped
     * to the same hybrid synthesis filterbank
     */
#ifdef PS_LOW_POWER
    for (env = 0; env < ps->num_env; env++)
    {
        if (ps->iid_mode == 2 || ps->iid_mode == 5)
            map34indexto20(ps->iid_index[env], 34);
        if (ps->icc_mode == 2 || ps->icc_mode == 5)
            map34indexto20(ps->icc_index[env], 34);

        /* disable ipd/opd */
        for (bin = 0; bin < 17; bin++)
        {
            ps->aaIpdIndex[env][bin] = 0;
            ps->aaOpdIndex[env][bin] = 0;
        }
    }
#else
    if (ps->use34hybrid_bands)
    {
        for (env = 0; env < ps->num_env; env++)
        {
            if (ps->iid_mode != 2 && ps->iid_mode != 5)
                map20indexto34(ps->iid_index[env], 34);
            if (ps->icc_mode != 2 && ps->icc_mode != 5)
                map20indexto34(ps->icc_index[env], 34);
            if (ps->ipd_mode != 2 && ps->ipd_mode != 5)
            {
                map20indexto34(ps->ipd_index[env], 17);
                map20indexto34(ps->opd_index[env], 17);
            }
        }
    }
#endif

#if 0
    for (env = 0; env < ps->num_env; env++)
    {
        printf("iid[env:%d]:", env);
        for (bin = 0; bin < 34; bin++)
        {
            printf(" %d", ps->iid_index[env][bin]);
        }
        printf("\n");
    }
    for (env = 0; env < ps->num_env; env++)
    {
        printf("icc[env:%d]:", env);
        for (bin = 0; bin < 34; bin++)
        {
            printf(" %d", ps->icc_index[env][bin]);
        }
        printf("\n");
    }
    for (env = 0; env < ps->num_env; env++)
    {
        printf("ipd[env:%d]:", env);
        for (bin = 0; bin < 17; bin++)
        {
            printf(" %d", ps->ipd_index[env][bin]);
        }
        printf("\n");
    }
    for (env = 0; env < ps->num_env; env++)
    {
        printf("opd[env:%d]:", env);
        for (bin = 0; bin < 17; bin++)
        {
            printf(" %d", ps->opd_index[env][bin]);
        }
        printf("\n");
    }
    printf("\n");
#endif
}

/* decorrelate the mono signal using an allpass filter */
static void ps_decorrelate(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64],
                           qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32])
{
    uint8_t gr, n, m, bk;
    uint8_t temp_delay;
    uint8_t sb, maxsb;
    const complex_t *Phi_Fract_SubQmf;
    uint8_t temp_delay_ser[NO_ALLPASS_LINKS];
    real_t P_SmoothPeakDecayDiffNrg, nrg;
    real_t P[32][34];
    real_t G_TransientRatio[32][34] = {{0}};
    complex_t inputLeft;


    /* chose hybrid filterbank: 20 or 34 band case */
    if (ps->use34hybrid_bands)
    {
        Phi_Fract_SubQmf = Phi_Fract_SubQmf34;
    } else{
        Phi_Fract_SubQmf = Phi_Fract_SubQmf20;
    }

    /* clear the energy values */
    for (n = 0; n < 32; n++)
    {
        for (bk = 0; bk < 34; bk++)
        {
            P[n][bk] = 0;
        }
    }

    /* calculate the energy in each parameter band b(k) */
    for (gr = 0; gr < ps->num_groups; gr++)
    {
        /* select the parameter index b(k) to which this group belongs */
        bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr];

        /* select the upper subband border for this group */

⌨️ 快捷键说明

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