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

📄 ps_dec.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 5 页
字号:
    y[3] = f2 - f8;
    y[0] = f2 + f8;
    y[2] = f1 - f7;
    y[1] = f1 + f7;
}

/* complex filter, size 8 */
static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
                            qmf_t *buffer, qmf_t **X_hybrid)
{
    uint8_t i, n;
    real_t input_re1[4], input_re2[4], input_im1[4], input_im2[4];
    real_t x[4];

    for (i = 0; i < frame_len; i++)
    {
        input_re1[0] =  MUL_F(filter[6],QMF_RE(buffer[6+i]));
        input_re1[1] =  MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i])));
        input_re1[2] = -MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))) + MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i])));
        input_re1[3] = -MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))) + MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i])));

        input_im1[0] = MUL_F(filter[5],(QMF_IM(buffer[7+i]) - QMF_IM(buffer[5+i])));
        input_im1[1] = MUL_F(filter[0],(QMF_IM(buffer[12+i]) - QMF_IM(buffer[0+i]))) + MUL_F(filter[4],(QMF_IM(buffer[8+i]) - QMF_IM(buffer[4+i])));
        input_im1[2] = MUL_F(filter[1],(QMF_IM(buffer[11+i]) - QMF_IM(buffer[1+i]))) + MUL_F(filter[3],(QMF_IM(buffer[9+i]) - QMF_IM(buffer[3+i])));
        input_im1[3] = MUL_F(filter[2],(QMF_IM(buffer[10+i]) - QMF_IM(buffer[2+i])));

        for (n = 0; n < 4; n++)
        {
            x[n] = input_re1[n] - input_im1[3-n];
        }
        DCT3_4_unscaled(x, x);
        QMF_RE(X_hybrid[i][7]) = x[0];
        QMF_RE(X_hybrid[i][5]) = x[2];
        QMF_RE(X_hybrid[i][3]) = x[3];
        QMF_RE(X_hybrid[i][1]) = x[1];

        for (n = 0; n < 4; n++)
        {
            x[n] = input_re1[n] + input_im1[3-n];
        }
        DCT3_4_unscaled(x, x);
        QMF_RE(X_hybrid[i][6]) = x[1];
        QMF_RE(X_hybrid[i][4]) = x[3];
        QMF_RE(X_hybrid[i][2]) = x[2];
        QMF_RE(X_hybrid[i][0]) = x[0];

        input_im2[0] =  MUL_F(filter[6],QMF_IM(buffer[6+i]));
        input_im2[1] =  MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i])));
        input_im2[2] = -MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))) + MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i])));
        input_im2[3] = -MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))) + MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i])));

        input_re2[0] = MUL_F(filter[5],(QMF_RE(buffer[7+i]) - QMF_RE(buffer[5+i])));
        input_re2[1] = MUL_F(filter[0],(QMF_RE(buffer[12+i]) - QMF_RE(buffer[0+i]))) + MUL_F(filter[4],(QMF_RE(buffer[8+i]) - QMF_RE(buffer[4+i])));
        input_re2[2] = MUL_F(filter[1],(QMF_RE(buffer[11+i]) - QMF_RE(buffer[1+i]))) + MUL_F(filter[3],(QMF_RE(buffer[9+i]) - QMF_RE(buffer[3+i])));
        input_re2[3] = MUL_F(filter[2],(QMF_RE(buffer[10+i]) - QMF_RE(buffer[2+i])));

        for (n = 0; n < 4; n++)
        {
            x[n] = input_im2[n] + input_re2[3-n];
        }
        DCT3_4_unscaled(x, x);
        QMF_IM(X_hybrid[i][7]) = x[0];
        QMF_IM(X_hybrid[i][5]) = x[2];
        QMF_IM(X_hybrid[i][3]) = x[3];
        QMF_IM(X_hybrid[i][1]) = x[1];

        for (n = 0; n < 4; n++)
        {
            x[n] = input_im2[n] - input_re2[3-n];
        }
        DCT3_4_unscaled(x, x);
        QMF_IM(X_hybrid[i][6]) = x[1];
        QMF_IM(X_hybrid[i][4]) = x[3];
        QMF_IM(X_hybrid[i][2]) = x[2];
        QMF_IM(X_hybrid[i][0]) = x[0];
    }
}

static void INLINE DCT3_6_unscaled(real_t *y, real_t *x)
{
    real_t f0, f1, f2, f3, f4, f5, f6, f7;

    f0 = MUL_F(x[3], FRAC_CONST(0.70710678118655));
    f1 = x[0] + f0;
    f2 = x[0] - f0;
    f3 = MUL_F((x[1] - x[5]), FRAC_CONST(0.70710678118655));
    f4 = MUL_F(x[2], FRAC_CONST(0.86602540378444)) + MUL_F(x[4], FRAC_CONST(0.5));
    f5 = f4 - x[4];
    f6 = MUL_F(x[1], FRAC_CONST(0.96592582628907)) + MUL_F(x[5], FRAC_CONST(0.25881904510252));
    f7 = f6 - f3;
    y[0] = f1 + f6 + f4;
    y[1] = f2 + f3 - x[4];
    y[2] = f7 + f2 - f5;
    y[3] = f1 - f7 - f5;
    y[4] = f1 - f3 - x[4];
    y[5] = f2 - f6 + f4;
}

/* complex filter, size 12 */
static void channel_filter12(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
                             qmf_t *buffer, qmf_t **X_hybrid)
{
    uint8_t i, n;
    real_t input_re1[6], input_re2[6], input_im1[6], input_im2[6];
    real_t out_re1[6], out_re2[6], out_im1[6], out_im2[6];

    for (i = 0; i < frame_len; i++)
    {
        for (n = 0; n < 6; n++)
        {
            if (n == 0)
            {
                input_re1[0] = MUL_F(QMF_RE(buffer[6+i]), filter[6]);
                input_re2[0] = MUL_F(QMF_IM(buffer[6+i]), filter[6]);
            } else {
                input_re1[6-n] = MUL_F((QMF_RE(buffer[n+i]) + QMF_RE(buffer[12-n+i])), filter[n]);
                input_re2[6-n] = MUL_F((QMF_IM(buffer[n+i]) + QMF_IM(buffer[12-n+i])), filter[n]);
            }
            input_im2[n] = MUL_F((QMF_RE(buffer[n+i]) - QMF_RE(buffer[12-n+i])), filter[n]);
            input_im1[n] = MUL_F((QMF_IM(buffer[n+i]) - QMF_IM(buffer[12-n+i])), filter[n]);
        }

        DCT3_6_unscaled(out_re1, input_re1);
        DCT3_6_unscaled(out_re2, input_re2);

        DCT3_6_unscaled(out_im1, input_im1);
        DCT3_6_unscaled(out_im2, input_im2);

        for (n = 0; n < 6; n += 2)
        {
            QMF_RE(X_hybrid[i][n]) = out_re1[n] - out_im1[n];
            QMF_IM(X_hybrid[i][n]) = out_re2[n] + out_im2[n];
            QMF_RE(X_hybrid[i][n+1]) = out_re1[n+1] + out_im1[n+1];
            QMF_IM(X_hybrid[i][n+1]) = out_re2[n+1] - out_im2[n+1];

            QMF_RE(X_hybrid[i][10-n]) = out_re1[n+1] - out_im1[n+1];
            QMF_IM(X_hybrid[i][10-n]) = out_re2[n+1] + out_im2[n+1];
            QMF_RE(X_hybrid[i][11-n]) = out_re1[n] + out_im1[n];
            QMF_IM(X_hybrid[i][11-n]) = out_re2[n] - out_im2[n];
        }
    }
}

/* Hybrid analysis: further split up QMF subbands
 * to improve frequency resolution
 */
static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32],
                            uint8_t use34)
{
    uint8_t k, n, band;
    uint8_t offset = 0;
    uint8_t qmf_bands = (use34) ? 5 : 3;
    uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20;

    for (band = 0; band < qmf_bands; band++)
    {
        /* build working buffer */
        memcpy(hyb->work, hyb->buffer[band], 12 * sizeof(qmf_t));

        /* add new samples */
        for (n = 0; n < hyb->frame_len; n++)
        {
            QMF_RE(hyb->work[12 + n]) = QMF_RE(X[n + 6 /*delay*/][band]);
            QMF_IM(hyb->work[12 + n]) = QMF_IM(X[n + 6 /*delay*/][band]);
        }

        /* store samples */
        memcpy(hyb->buffer[band], hyb->work + hyb->frame_len, 12 * sizeof(qmf_t));


        switch(resolution[band])
        {
        case 2:
            /* Type B real filter, Q[p] = 2 */
            channel_filter2(hyb, hyb->frame_len, p2_13_20, hyb->work, hyb->temp);
            break;
        case 4:
            /* Type A complex filter, Q[p] = 4 */
            channel_filter4(hyb, hyb->frame_len, p4_13_34, hyb->work, hyb->temp);
            break;
        case 8:
            /* Type A complex filter, Q[p] = 8 */
            channel_filter8(hyb, hyb->frame_len, (use34) ? p8_13_34 : p8_13_20,
                hyb->work, hyb->temp);
            break;
        case 12:
            /* Type A complex filter, Q[p] = 12 */
            channel_filter12(hyb, hyb->frame_len, p12_13_34, hyb->work, hyb->temp);
            break;
        }

        for (n = 0; n < hyb->frame_len; n++)
        {
            for (k = 0; k < resolution[band]; k++)
            {
                QMF_RE(X_hybrid[n][offset + k]) = QMF_RE(hyb->temp[n][k]);
                QMF_IM(X_hybrid[n][offset + k]) = QMF_IM(hyb->temp[n][k]);
            }
        }
        offset += resolution[band];
    }

    /* group hybrid channels */
    if (!use34)
    {
        for (n = 0; n < 32 /*30?*/; n++)
        {
            QMF_RE(X_hybrid[n][3]) += QMF_RE(X_hybrid[n][4]);
            QMF_IM(X_hybrid[n][3]) += QMF_IM(X_hybrid[n][4]);
            QMF_RE(X_hybrid[n][4]) = 0;
            QMF_IM(X_hybrid[n][4]) = 0;

            QMF_RE(X_hybrid[n][2]) += QMF_RE(X_hybrid[n][5]);
            QMF_IM(X_hybrid[n][2]) += QMF_IM(X_hybrid[n][5]);
            QMF_RE(X_hybrid[n][5]) = 0;
            QMF_IM(X_hybrid[n][5]) = 0;
        }
    }
}

static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32],
                             uint8_t use34)
{
    uint8_t k, n, band;
    uint8_t offset = 0;
    uint8_t qmf_bands = (use34) ? 5 : 3;
    uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20;

    for(band = 0; band < qmf_bands; band++)
    {
        for (n = 0; n < hyb->frame_len; n++)
        {
            QMF_RE(X[n][band]) = 0;
            QMF_IM(X[n][band]) = 0;

            for (k = 0; k < resolution[band]; k++)
            {
                QMF_RE(X[n][band]) += QMF_RE(X_hybrid[n][offset + k]);
                QMF_IM(X[n][band]) += QMF_IM(X_hybrid[n][offset + k]);
            }
        }
        offset += resolution[band];
    }
}

/* limits the value i to the range [min,max] */
static int8_t delta_clip(int8_t i, int8_t min, int8_t max)
{
    if (i < min)
        return min;
    else if (i > max)
        return max;
    else
        return i;
}

//int iid = 0;

/* delta decode array */
static void delta_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
                         uint8_t dt_flag, uint8_t nr_par, uint8_t stride,
                         int8_t min_index, int8_t max_index)
{
    int8_t i;

    if (enable == 1)
    {
        if (dt_flag == 0)
        {
            /* delta coded in frequency direction */
            index[0] = 0 + index[0];
            index[0] = delta_clip(index[0], min_index, max_index);

            for (i = 1; i < nr_par; i++)
            {
                index[i] = index[i-1] + index[i];
                index[i] = delta_clip(index[i], min_index, max_index);
            }
        } else {
            /* delta coded in time direction */
            for (i = 0; i < nr_par; i++)
            {
                //int8_t tmp2;
                //int8_t tmp = index[i];

                //printf("%d %d\n", index_prev[i*stride], index[i]);
                //printf("%d\n", index[i]);

                index[i] = index_prev[i*stride] + index[i];
                //tmp2 = index[i];
                index[i] = delta_clip(index[i], min_index, max_index);

                //if (iid)
                //{
                //    if (index[i] == 7)
                //    {
                //        printf("%d %d %d\n", index_prev[i*stride], tmp, tmp2);
                //    }
                //}
            }
        }
    } else {
        /* set indices to zero */
        for (i = 0; i < nr_par; i++)
        {
            index[i] = 0;
        }
    }

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

/* delta modulo decode array */
/* in: log2 value of the modulo value to allow using AND instead of MOD */
static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
                                uint8_t dt_flag, uint8_t nr_par, uint8_t stride,
                                int8_t log2modulo)
{
    int8_t i;

    if (enable == 1)
    {
        if (dt_flag == 0)
        {
            /* delta coded in frequency direction */
            index[0] = 0 + index[0];
            index[0] &= log2modulo;

            for (i = 1; i < nr_par; i++)
            {
                index[i] = index[i-1] + index[i];
                index[i] &= log2modulo;
            }
        } else {
            /* delta coded in time direction */
            for (i = 0; i < nr_par; i++)
            {
                index[i] = index_prev[i*stride] + index[i];
                index[i] &= log2modulo;
            }
        }
    } else {
        /* set indices to zero */
        for (i = 0; i < nr_par; i++)
        {
            index[i] = 0;
        }
    }

⌨️ 快捷键说明

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