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

📄 ps_dec.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR and PS decoding
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
** $Id: ps_dec.c,v 1.10 2004/09/04 14:56:28 menno Exp $
**/

#include "common.h"

#ifdef PS_DEC

#include <stdlib.h>
#include "ps_dec.h"
#include "ps_tables.h"

/* constants */
#define NEGATE_IPD_MASK            (0x1000)
#define DECAY_SLOPE                FRAC_CONST(0.05)
#define COEF_SQRT2                 COEF_CONST(1.4142135623731)

/* tables */
/* filters are mirrored in coef 6, second half left out */
static const real_t p8_13_20[7] =
{
    FRAC_CONST(0.00746082949812),
    FRAC_CONST(0.02270420949825),
    FRAC_CONST(0.04546865930473),
    FRAC_CONST(0.07266113929591),
    FRAC_CONST(0.09885108575264),
    FRAC_CONST(0.11793710567217),
    FRAC_CONST(0.125)
};

static const real_t p2_13_20[7] =
{
    FRAC_CONST(0.0),
    FRAC_CONST(0.01899487526049),
    FRAC_CONST(0.0),
    FRAC_CONST(-0.07293139167538),
    FRAC_CONST(0.0),
    FRAC_CONST(0.30596630545168),
    FRAC_CONST(0.5)
};

static const real_t p12_13_34[7] =
{
    FRAC_CONST(0.04081179924692),
    FRAC_CONST(0.03812810994926),
    FRAC_CONST(0.05144908135699),
    FRAC_CONST(0.06399831151592),
    FRAC_CONST(0.07428313801106),
    FRAC_CONST(0.08100347892914),
    FRAC_CONST(0.08333333333333)
};

static const real_t p8_13_34[7] =
{
    FRAC_CONST(0.01565675600122),
    FRAC_CONST(0.03752716391991),
    FRAC_CONST(0.05417891378782),
    FRAC_CONST(0.08417044116767),
    FRAC_CONST(0.10307344158036),
    FRAC_CONST(0.12222452249753),
    FRAC_CONST(0.125)
};

static const real_t p4_13_34[7] =
{
    FRAC_CONST(-0.05908211155639),
    FRAC_CONST(-0.04871498374946),
    FRAC_CONST(0.0),
    FRAC_CONST(0.07778723915851),
    FRAC_CONST(0.16486303567403),
    FRAC_CONST(0.23279856662996),
    FRAC_CONST(0.25)
};

#ifdef PARAM_32KHZ
static const uint8_t delay_length_d[2][NO_ALLPASS_LINKS] = {
    { 1, 2, 3 } /* d_24kHz */,
    { 3, 4, 5 } /* d_48kHz */
};
#else
static const uint8_t delay_length_d[NO_ALLPASS_LINKS] = {
    3, 4, 5 /* d_48kHz */
};
#endif
static const real_t filter_a[NO_ALLPASS_LINKS] = { /* a(m) = exp(-d_48kHz(m)/7) */
    FRAC_CONST(0.65143905753106),
    FRAC_CONST(0.56471812200776),
    FRAC_CONST(0.48954165955695)
};

static const uint8_t group_border20[10+12 + 1] =
{
    6, 7, 0, 1, 2, 3, /* 6 subqmf subbands */
    9, 8,             /* 2 subqmf subbands */
    10, 11,           /* 2 subqmf subbands */
    3, 4, 5, 6, 7, 8, 9, 11, 14, 18, 23, 35, 64
};

static const uint8_t group_border34[32+18 + 1] =
{
     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, /* 12 subqmf subbands */
     12, 13, 14, 15, 16, 17, 18, 19,                 /*  8 subqmf subbands */
     20, 21, 22, 23,                                 /*  4 subqmf subbands */
     24, 25, 26, 27,                                 /*  4 subqmf subbands */
     28, 29, 30, 31,                                 /*  4 subqmf subbands */
     32-27, 33-27, 34-27, 35-27, 36-27, 37-27, 38-27, 40-27, 42-27, 44-27, 46-27, 48-27, 51-27, 54-27, 57-27, 60-27, 64-27, 68-27, 91-27
};

static const uint16_t map_group2bk20[10+12] =
{
    (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0),
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
};

static const uint16_t map_group2bk34[32+18] =
{
    0,  1,  2,  3,  4,  5,  6,  6,  7, (NEGATE_IPD_MASK | 2), (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0),
    10, 10, 4,  5,  6,  7,  8,  9,
    10, 11, 12, 9,
    14, 11, 12, 13,
    14, 15, 16, 13,
    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33
};

/* type definitions */
typedef struct
{
    uint8_t frame_len;
    uint8_t resolution20[3];
    uint8_t resolution34[5];

    qmf_t *work;
    qmf_t **buffer;
    qmf_t **temp;
} hyb_info;

/* static function declarations */
static void ps_data_decode(ps_info *ps);
static hyb_info *hybrid_init();
static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
                            qmf_t *buffer, qmf_t **X_hybrid);
static void INLINE DCT3_4_unscaled(real_t *y, real_t *x);
static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
                            qmf_t *buffer, qmf_t **X_hybrid);
static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32],
                            uint8_t use34);
static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32],
                             uint8_t use34);
static int8_t delta_clip(int8_t i, int8_t min, int8_t max);
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);
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);
static void map20indexto34(int8_t *index, uint8_t bins);
#ifdef PS_LOW_POWER
static void map34indexto20(int8_t *index, uint8_t bins);
#endif
static void ps_data_decode(ps_info *ps);
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]);
static void ps_mix_phase(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]);

/*  */


static hyb_info *hybrid_init()
{
    uint8_t i;

    hyb_info *hyb = (hyb_info*)faad_malloc(sizeof(hyb_info));

    hyb->resolution34[0] = 12;
    hyb->resolution34[1] = 8;
    hyb->resolution34[2] = 4;
    hyb->resolution34[3] = 4;
    hyb->resolution34[4] = 4;

    hyb->resolution20[0] = 8;
    hyb->resolution20[1] = 2;
    hyb->resolution20[2] = 2;

    hyb->frame_len = 32;

    hyb->work = (qmf_t*)faad_malloc((hyb->frame_len+12) * sizeof(qmf_t));
    memset(hyb->work, 0, (hyb->frame_len+12) * sizeof(qmf_t));

    hyb->buffer = (qmf_t**)faad_malloc(5 * sizeof(qmf_t*));
    for (i = 0; i < 5; i++)
    {
        hyb->buffer[i] = (qmf_t*)faad_malloc(hyb->frame_len * sizeof(qmf_t));
        memset(hyb->buffer[i], 0, hyb->frame_len * sizeof(qmf_t));
    }

    hyb->temp = (qmf_t**)faad_malloc(hyb->frame_len * sizeof(qmf_t*));
    for (i = 0; i < hyb->frame_len; i++)
    {
        hyb->temp[i] = (qmf_t*)faad_malloc(12 /*max*/ * sizeof(qmf_t));
    }

    return hyb;
}

static void hybrid_free(hyb_info *hyb)
{
    uint8_t i;

    if (hyb->work)
        faad_free(hyb->work);

    for (i = 0; i < 5; i++)
    {
        if (hyb->buffer[i])
            faad_free(hyb->buffer[i]);
    }
    if (hyb->buffer)
        faad_free(hyb->buffer);

    for (i = 0; i < hyb->frame_len; i++)
    {
        if (hyb->temp[i])
            faad_free(hyb->temp[i]);
    }
    if (hyb->temp)
        faad_free(hyb->temp);

	faad_free(hyb);
}

/* real filter, size 2 */
static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
                            qmf_t *buffer, qmf_t **X_hybrid)
{
    uint8_t i;

    for (i = 0; i < frame_len; i++)
    {
        real_t r0 = MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i])));
        real_t r1 = MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i])));
        real_t r2 = MUL_F(filter[2],(QMF_RE(buffer[2+i]) + QMF_RE(buffer[10+i])));
        real_t r3 = MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i])));
        real_t r4 = MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i])));
        real_t r5 = MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i])));
        real_t r6 = MUL_F(filter[6],QMF_RE(buffer[6+i]));
        real_t i0 = MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i])));
        real_t i1 = MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i])));
        real_t i2 = MUL_F(filter[2],(QMF_IM(buffer[2+i]) + QMF_IM(buffer[10+i])));
        real_t i3 = MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i])));
        real_t i4 = MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i])));
        real_t i5 = MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i])));
        real_t i6 = MUL_F(filter[6],QMF_IM(buffer[6+i]));

        /* q = 0 */
        QMF_RE(X_hybrid[i][0]) = r0 + r1 + r2 + r3 + r4 + r5 + r6;
        QMF_IM(X_hybrid[i][0]) = i0 + i1 + i2 + i3 + i4 + i5 + i6;

        /* q = 1 */
        QMF_RE(X_hybrid[i][1]) = r0 - r1 + r2 - r3 + r4 - r5 + r6;
        QMF_IM(X_hybrid[i][1]) = i0 - i1 + i2 - i3 + i4 - i5 + i6;
    }
}

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

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

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

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

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

        /* q == 0 */
        QMF_RE(X_hybrid[i][0]) =  input_re1[0] + input_re1[1] + input_im1[0] + input_im1[1];
        QMF_IM(X_hybrid[i][0]) = -input_re2[0] - input_re2[1] + input_im2[0] + input_im2[1];

        /* q == 1 */
        QMF_RE(X_hybrid[i][1]) =  input_re1[0] - input_re1[1] - input_im1[0] + input_im1[1];
        QMF_IM(X_hybrid[i][1]) =  input_re2[0] - input_re2[1] + input_im2[0] - input_im2[1];

        /* q == 2 */
        QMF_RE(X_hybrid[i][2]) =  input_re1[0] - input_re1[1] + input_im1[0] - input_im1[1];
        QMF_IM(X_hybrid[i][2]) = -input_re2[0] + input_re2[1] + input_im2[0] - input_im2[1];

        /* q == 3 */
        QMF_RE(X_hybrid[i][3]) =  input_re1[0] + input_re1[1] - input_im1[0] - input_im1[1];
        QMF_IM(X_hybrid[i][3]) =  input_re2[0] + input_re2[1] + input_im2[0] + input_im2[1];
    }
}

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

    f0 = MUL_F(x[2], FRAC_CONST(0.7071067811865476));
    f1 = x[0] - f0;
    f2 = x[0] + f0;
    f3 = x[1] + x[3];
    f4 = MUL_C(x[1], COEF_CONST(1.3065629648763766));
    f5 = MUL_F(f3, FRAC_CONST(-0.9238795325112866));
    f6 = MUL_F(x[3], FRAC_CONST(-0.5411961001461967));
    f7 = f4 + f5;
    f8 = f6 - f5;

⌨️ 快捷键说明

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