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

📄 ps_dec.c

📁 tcpmp.src.0.72RC1 优秀的多媒体播放器TCPMP的源代码
💻 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_32KHZstatic const uint8_t delay_length_d[2][NO_ALLPASS_LINKS] = {    { 1, 2, 3 } /* d_24kHz */,    { 3, 4, 5 } /* d_48kHz */};#elsestatic const uint8_t delay_length_d[NO_ALLPASS_LINKS] = {    3, 4, 5 /* d_48kHz */};#endifstatic 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_POWERstatic void map34indexto20(int8_t *index, uint8_t bins);#endifstatic 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;    y[3] = f2 - f8;    y[0] = f2 + f8;    y[2] = f1 - f7;    y[1] = f1 + f7;}

⌨️ 快捷键说明

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