Skip to content
Snippets Groups Projects
mpegaudiodec.c 85.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Fabrice Bellard's avatar
    Fabrice Bellard committed
    /*
     * MPEG Audio decoder
    
     * Copyright (c) 2001, 2002 Fabrice Bellard.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * This file is part of FFmpeg.
     *
     * FFmpeg is free software; you can redistribute it and/or
    
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
    
     * version 2.1 of the License, or (at your option) any later version.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * FFmpeg is distributed in the hope that it will be useful,
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
    
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * You should have received a copy of the GNU Lesser General Public
    
     * License along with FFmpeg; if not, write to the Free Software
    
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
    /**
     * @file mpegaudiodec.c
     * MPEG Audio decoder.
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #include "avcodec.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    /*
    
     * TODO:
     *  - in low precision mode, use more 16 bit multiplies in synth filter
     *  - test lsf / mpeg25 extensively.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     */
    
    
    /* define USE_HIGHPRECISION to have a bit exact (but slower) mpeg
       audio decoder */
    
    #   define USE_HIGHPRECISION
    
    Roberto Togni's avatar
    Roberto Togni committed
    #include "mpegaudio.h"
    
    Luca Barbato's avatar
    Luca Barbato committed
    #include "mathops.h"
    
    
    #define FRAC_ONE    (1 << FRAC_BITS)
    
    #define FIX(a)   ((int)((a) * FRAC_ONE))
    /* WARNING: only correct for posititive numbers */
    #define FIXR(a)   ((int)((a) * FRAC_ONE + 0.5))
    #define FRAC_RND(a) (((a) + (FRAC_ONE/2)) >> FRAC_BITS)
    
    
    #define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5))
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #define HEADER_SIZE 4
    #define BACKSTEP_SIZE 512
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    typedef struct MPADecodeContext {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        DECLARE_ALIGNED_8(uint8_t, last_buf[2*BACKSTEP_SIZE + EXTRABYTES]);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int frame_size;
    
        /* next header (used in free format parsing) */
    
        uint32_t free_format_next_header;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int error_protection;
        int layer;
        int sample_rate;
    
        int sample_rate_index; /* between 0 and 8 */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int bit_rate;
        GetBitContext gb;
    
        DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512 * 2]);
    
        int synth_buf_offset[MPA_MAX_CHANNELS];
    
        DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT]);
    
        int32_t mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
    
        void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g);
    
    Roberto Togni's avatar
    Roberto Togni committed
        int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
    
        int dither_state;
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
        AVCodecContext* avctx;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    } MPADecodeContext;
    
    
    /**
     * Context for MP3On4 decoder
     */
    typedef struct MP3On4DecodeContext {
        int frames;   ///< number of mp3 frames per block (number of mp3 decoder instances)
        int chan_cfg; ///< channel config number
        MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
    } MP3On4DecodeContext;
    
    
    /* layer 3 "granule" */
    typedef struct GranuleDef {
    
        uint8_t scfsi;
    
        int part2_3_length;
        int big_values;
        int global_gain;
        int scalefac_compress;
    
        uint8_t block_type;
        uint8_t switch_point;
    
        uint8_t scalefac_scale;
        uint8_t count1table_select;
    
        int region_size[3]; /* number of huffman codes in each region */
        int preflag;
        int short_start, long_end; /* long/short band indexes */
    
        uint8_t scale_factors[40];
        int32_t sb_hybrid[SBLIMIT * 18]; /* 576 samples */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    #define MODE_EXT_MS_STEREO 2
    #define MODE_EXT_I_STEREO  1
    
    /* layer 3 huffman tables */
    typedef struct HuffTable {
        int xsize;
    
        const uint8_t *bits;
        const uint16_t *codes;
    
    static void compute_antialias_integer(MPADecodeContext *s, GranuleDef *g);
    static void compute_antialias_float(MPADecodeContext *s, GranuleDef *g);
    
    
    /* vlc structure for decoding layer 3 huffman tables */
    
    static VLC huff_vlc[16];
    
    static VLC huff_quad_vlc[2];
    /* computed from band_size_long */
    
    static uint16_t band_index_long[9][23];
    
    /* XXX: free when all decoders are closed */
    
    #define TABLE_4_3_SIZE (8191 + 16)*4
    
    static int8_t  table_4_3_exp[TABLE_4_3_SIZE];
    static uint32_t table_4_3_value[TABLE_4_3_SIZE];
    
    static uint32_t exp_table[512];
    
    static uint32_t expval_table[512][16];
    
    static int32_t is_table[2][16];
    static int32_t is_table_lsf[2][2][16];
    
    static int32_t csa_table[8][4];
    static float csa_table_float[8][4];
    
    static int32_t mdct_win[8][36];
    
    
    /* lower 2 bits: modulo 3, higher bits: shift */
    
    static uint16_t scale_factor_modshift[64];
    
    /* [i][j]:  2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
    
    static int32_t scale_factor_mult[15][3];
    
    /* mult table for layer 2 group quantization */
    
    #define SCALE_GEN(v) \
    { FIXR(1.0 * (v)), FIXR(0.7937005259 * (v)), FIXR(0.6299605249 * (v)) }
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    static const int32_t scale_factor_mult2[3][3] = {
    
        SCALE_GEN(4.0 / 3.0), /* 3 steps */
        SCALE_GEN(4.0 / 5.0), /* 5 steps */
        SCALE_GEN(4.0 / 9.0), /* 9 steps */
    
    static DECLARE_ALIGNED_16(MPA_INT, window[512]);
    
    /* layer 1 unscaling */
    /* n = number of bits of the mantissa minus 1 */
    static inline int l1_unscale(int n, int mant, int scale_factor)
    {
        int shift, mod;
    
        int64_t val;
    
    
        shift = scale_factor_modshift[scale_factor];
        mod = shift & 3;
        shift >>= 2;
        val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
        shift += n;
    
        /* NOTE: at this point, 1 <= shift >= 21 + 15 */
        return (int)((val + (1LL << (shift - 1))) >> shift);
    
    }
    
    static inline int l2_unscale_group(int steps, int mant, int scale_factor)
    {
        int shift, mod, val;
    
        shift = scale_factor_modshift[scale_factor];
        mod = shift & 3;
        shift >>= 2;
    
    
        val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
        /* NOTE: at this point, 0 <= shift <= 21 */
        if (shift > 0)
            val = (val + (1 << (shift - 1))) >> shift;
        return val;
    
    }
    
    /* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
    static inline int l3_unscale(int value, int exponent)
    {
        unsigned int m;
        int e;
    
    
        e = table_4_3_exp  [4*value + (exponent&3)];
        m = table_4_3_value[4*value + (exponent&3)];
        e -= (exponent >> 2);
        assert(e>=1);
    
    /* all integer n^(4/3) computation code */
    #define DEV_ORDER 13
    
    #define POW_FRAC_BITS 24
    #define POW_FRAC_ONE    (1 << POW_FRAC_BITS)
    #define POW_FIX(a)   ((int)((a) * POW_FRAC_ONE))
    
    #define POW_MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> POW_FRAC_BITS)
    
    static int pow_mult3[3] = {
        POW_FIX(1.0),
        POW_FIX(1.25992104989487316476),
        POW_FIX(1.58740105196819947474),
    };
    
    
    static void int_pow_init(void)
    {
        int i, a;
    
        a = POW_FIX(1.0);
        for(i=0;i<DEV_ORDER;i++) {
            a = POW_MULL(a, POW_FIX(4.0 / 3.0) - i * POW_FIX(1.0)) / (i + 1);
            dev_4_3_coefs[i] = a;
        }
    }
    
    
    /* return the mantissa and the binary exponent */
    static int int_pow(int i, int *exp_ptr)
    {
        int e, er, eq, j;
        int a, a1;
    
        /* renormalize */
        a = i;
        e = POW_FRAC_BITS;
        while (a < (1 << (POW_FRAC_BITS - 1))) {
            a = a << 1;
            e--;
        }
        a -= (1 << POW_FRAC_BITS);
        a1 = 0;
        for(j = DEV_ORDER - 1; j >= 0; j--)
            a1 = POW_MULL(a, dev_4_3_coefs[j] + a1);
        a = (1 << POW_FRAC_BITS) + a1;
        /* exponent compute (exact) */
        e = e * 4;
        er = e % 3;
        eq = e / 3;
        a = POW_MULL(a, pow_mult3[er]);
        while (a >= 2 * POW_FRAC_ONE) {
            a = a >> 1;
            eq++;
        }
        /* convert to float */
        while (a < POW_FRAC_ONE) {
            a = a << 1;
            eq--;
        }
    
        /* now POW_FRAC_ONE <= a < 2 * POW_FRAC_ONE */
    
        a = (a + (1 << (POW_FRAC_BITS - FRAC_BITS - 1))) >> (POW_FRAC_BITS - FRAC_BITS);
        /* correct overflow */
        if (a >= 2 * (1 << FRAC_BITS)) {
            a = a >> 1;
            eq++;
        }
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    static int decode_init(AVCodecContext * avctx)
    {
        MPADecodeContext *s = avctx->priv_data;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
        s->avctx = avctx;
    
    
    #if defined(USE_HIGHPRECISION) && defined(CONFIG_AUDIO_NONSHORT)
    
        avctx->sample_fmt= SAMPLE_FMT_S32;
    #else
        avctx->sample_fmt= SAMPLE_FMT_S16;
    
        s->error_resilience= avctx->error_resilience;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        if(avctx->antialias_algo != FF_AA_FLOAT)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            s->compute_antialias= compute_antialias_integer;
        else
            s->compute_antialias= compute_antialias_float;
    
    
            /* scale factors table for layer 1/2 */
            for(i=0;i<64;i++) {
                int shift, mod;
                /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
    
                mod = i % 3;
                scale_factor_modshift[i] = mod | (shift << 2);
            }
    
            /* scale factor multiply for layer 1 */
            for(i=0;i<15;i++) {
                int n, norm;
                n = i + 2;
    
                norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
    
                scale_factor_mult[i][0] = MULL(FIXR(1.0 * 2.0), norm);
                scale_factor_mult[i][1] = MULL(FIXR(0.7937005259 * 2.0), norm);
                scale_factor_mult[i][2] = MULL(FIXR(0.6299605249 * 2.0), norm);
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                dprintf(avctx, "%d: norm=%x s=%x %x %x\n",
    
                        scale_factor_mult[i][0],
                        scale_factor_mult[i][1],
                        scale_factor_mult[i][2]);
            }
    
            ff_mpa_synth_init(window);
    
            /* huffman decode tables */
            for(i=1;i<16;i++) {
                const HuffTable *h = &mpa_huff_tables[i];
    
                unsigned int n;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                uint8_t  tmp_bits [512];
                uint16_t tmp_codes[512];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
                memset(tmp_bits , 0, sizeof(tmp_bits ));
                memset(tmp_codes, 0, sizeof(tmp_codes));
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    for(y=0;y<xsize;y++){
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                        tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j  ];
                        tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
                /* XXX: fail test */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                init_vlc(&huff_vlc[i], 7, 512,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                         tmp_bits, 1, 1, tmp_codes, 2, 2, 1);
    
                init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
    
                         mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1, 1);
    
            }
    
            for(i=0;i<9;i++) {
                k = 0;
                for(j=0;j<22;j++) {
                    band_index_long[i][j] = k;
                    k += band_size_long[i][j];
                }
                band_index_long[i][22] = k;
            }
    
    
            /* compute n ^ (4/3) and store it in mantissa/exp format */
    
                f = pow((double)(i/4), 4.0 / 3.0) * pow(2, (i&3)*0.25);
                fm = frexp(f, &e);
    
                e+= FRAC_BITS - 31 + 5 - 100;
    
                /* normalized to FRAC_BITS */
                table_4_3_value[i] = m;
    
    //            av_log(NULL, AV_LOG_DEBUG, "%d %d %f\n", i, m, pow((double)i, 4.0 / 3.0));
                table_4_3_exp[i] = -e;
    
            for(i=0; i<512*16; i++){
    
                int exponent= (i>>4);
                double f= pow(i&15, 4.0 / 3.0) * pow(2, (exponent-400)*0.25 + FRAC_BITS + 5);
    
                expval_table[exponent][i&15]= llrint(f);
    
                    exp_table[exponent]= llrint(f);
    
            for(i=0;i<7;i++) {
                float f;
                int v;
                if (i != 6) {
                    f = tan((double)i * M_PI / 12.0);
                    v = FIXR(f / (1.0 + f));
                } else {
                    v = FIXR(1.0);
                }
                is_table[0][i] = v;
                is_table[1][6 - i] = v;
            }
            /* invalid values */
            for(i=7;i<16;i++)
                is_table[0][i] = is_table[1][i] = 0.0;
    
            for(i=0;i<16;i++) {
                double f;
                int e, k;
    
                for(j=0;j<2;j++) {
                    e = -(j + 1) * ((i + 1) >> 1);
                    f = pow(2.0, e / 4.0);
                    k = i & 1;
                    is_table_lsf[j][k ^ 1][i] = FIXR(f);
                    is_table_lsf[j][k][i] = FIXR(1.0);
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
                    dprintf(avctx, "is_table_lsf %d %d: %x %x\n",
    
                            i, j, is_table_lsf[j][0][i], is_table_lsf[j][1][i]);
                }
            }
    
            for(i=0;i<8;i++) {
                float ci, cs, ca;
                ci = ci_table[i];
                cs = 1.0 / sqrt(1.0 + ci * ci);
                ca = cs * ci;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                csa_table[i][0] = FIXHR(cs/4);
                csa_table[i][1] = FIXHR(ca/4);
                csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
    
                csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
    
                csa_table_float[i][0] = cs;
                csa_table_float[i][1] = ca;
                csa_table_float[i][2] = ca + cs;
    
                csa_table_float[i][3] = ca - cs;
    
    //            printf("%d %d %d %d\n", FIX(cs), FIX(cs-1), FIX(ca), FIX(cs)-FIX(ca));
    
    //            av_log(NULL, AV_LOG_DEBUG,"%f %f %f %f\n", cs, ca, ca+cs, ca-cs);
    
                for(j=0; j<4; j++){
                    double d;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    if(j==2 && i%3 != 1)
                        continue;
    
                    d= sin(M_PI * (i + 0.5) / 36.0);
                    if(j==1){
                        if     (i>=30) d= 0;
                        else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0);
                        else if(i>=18) d= 1;
                    }else if(j==3){
                        if     (i<  6) d= 0;
                        else if(i< 12) d= sin(M_PI * (i -  6 + 0.5) / 12.0);
                        else if(i< 18) d= 1;
                    }
                    //merge last stage of imdct into the window coefficients
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    d*= 0.5 / cos(M_PI*(2*i + 19)/72);
    
                    if(j==2)
                        mdct_win[j][i/3] = FIXHR((d / (1<<5)));
                    else
                        mdct_win[j][i  ] = FIXHR((d / (1<<5)));
    
    //                av_log(NULL, AV_LOG_DEBUG, "%2d %d %f\n", i,j,d / (1<<5));
                }
    
            }
    
            /* NOTE: we do frequency inversion adter the MDCT by changing
               the sign of the right window coefs */
            for(j=0;j<4;j++) {
                for(i=0;i<36;i+=2) {
                    mdct_win[j + 4][i] = mdct_win[j][i];
                    mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1];
                }
            }
    
    #if defined(DEBUG)
            for(j=0;j<8;j++) {
    
                av_log(avctx, AV_LOG_DEBUG, "win%d=\n", j);
    
                    av_log(avctx, AV_LOG_DEBUG, "%f, ", (double)mdct_win[j][i] / FRAC_ONE);
                av_log(avctx, AV_LOG_DEBUG, "\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            init = 1;
        }
    
    
    Roberto Togni's avatar
    Roberto Togni committed
        if (avctx->codec_id == CODEC_ID_MP3ADU)
            s->adu_mode = 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }
    
    
    /* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */
    
    #define COS0_0  FIXHR(0.50060299823519630134/2)
    #define COS0_1  FIXHR(0.50547095989754365998/2)
    #define COS0_2  FIXHR(0.51544730992262454697/2)
    #define COS0_3  FIXHR(0.53104259108978417447/2)
    #define COS0_4  FIXHR(0.55310389603444452782/2)
    #define COS0_5  FIXHR(0.58293496820613387367/2)
    #define COS0_6  FIXHR(0.62250412303566481615/2)
    #define COS0_7  FIXHR(0.67480834145500574602/2)
    #define COS0_8  FIXHR(0.74453627100229844977/2)
    #define COS0_9  FIXHR(0.83934964541552703873/2)
    #define COS0_10 FIXHR(0.97256823786196069369/2)
    #define COS0_11 FIXHR(1.16943993343288495515/4)
    #define COS0_12 FIXHR(1.48416461631416627724/4)
    #define COS0_13 FIXHR(2.05778100995341155085/8)
    #define COS0_14 FIXHR(3.40760841846871878570/8)
    #define COS0_15 FIXHR(10.19000812354805681150/32)
    
    #define COS1_0 FIXHR(0.50241928618815570551/2)
    #define COS1_1 FIXHR(0.52249861493968888062/2)
    #define COS1_2 FIXHR(0.56694403481635770368/2)
    #define COS1_3 FIXHR(0.64682178335999012954/2)
    #define COS1_4 FIXHR(0.78815462345125022473/2)
    #define COS1_5 FIXHR(1.06067768599034747134/4)
    #define COS1_6 FIXHR(1.72244709823833392782/4)
    #define COS1_7 FIXHR(5.10114861868916385802/16)
    
    #define COS2_0 FIXHR(0.50979557910415916894/2)
    #define COS2_1 FIXHR(0.60134488693504528054/2)
    #define COS2_2 FIXHR(0.89997622313641570463/2)
    #define COS2_3 FIXHR(2.56291544774150617881/8)
    
    #define COS3_0 FIXHR(0.54119610014619698439/2)
    #define COS3_1 FIXHR(1.30656296487637652785/4)
    
    #define COS4_0 FIXHR(0.70710678118654752439/2)
    
    {\
        tmp0 = tab[a] + tab[b];\
        tmp1 = tab[a] - tab[b];\
        tab[a] = tmp0;\
    
        tab[c] += tab[d];\
        tab[a] += tab[c];\
        tab[c] += tab[b];\
        tab[b] += tab[d];\
    }
    
    #define ADD(a, b) tab[a] += tab[b]
    
    /* DCT32 without 1/sqrt(2) coef zero scaling. */
    
    static void dct32(int32_t *out, int32_t *tab)
    
        BF( 0,  7, COS2_0 , 1);
        BF( 8, 15,-COS2_0 , 1);
        BF(16, 23, COS2_0 , 1);
        BF(24, 31,-COS2_0 , 1);
    
        BF( 3,  4, COS2_3 , 3);
        BF(11, 12,-COS2_3 , 3);
        BF(19, 20, COS2_3 , 3);
        BF(27, 28,-COS2_3 , 3);
    
        BF( 0,  3, COS3_0 , 1);
        BF( 4,  7,-COS3_0 , 1);
        BF( 8, 11, COS3_0 , 1);
        BF(12, 15,-COS3_0 , 1);
        BF(16, 19, COS3_0 , 1);
        BF(20, 23,-COS3_0 , 1);
        BF(24, 27, COS3_0 , 1);
        BF(28, 31,-COS3_0 , 1);
    
        BF( 1,  6, COS2_1 , 1);
        BF( 9, 14,-COS2_1 , 1);
        BF(17, 22, COS2_1 , 1);
        BF(25, 30,-COS2_1 , 1);
    
        BF( 2,  5, COS2_2 , 1);
        BF(10, 13,-COS2_2 , 1);
        BF(18, 21, COS2_2 , 1);
        BF(26, 29,-COS2_2 , 1);
    
        BF( 1,  2, COS3_1 , 2);
        BF( 5,  6,-COS3_1 , 2);
        BF( 9, 10, COS3_1 , 2);
        BF(13, 14,-COS3_1 , 2);
        BF(17, 18, COS3_1 , 2);
        BF(21, 22,-COS3_1 , 2);
        BF(25, 26, COS3_1 , 2);
        BF(29, 30,-COS3_1 , 2);
    
        BF1( 0,  1,  2,  3);
        BF2( 4,  5,  6,  7);
        BF1( 8,  9, 10, 11);
    
        BF2(12, 13, 14, 15);
        BF1(16, 17, 18, 19);
        BF2(20, 21, 22, 23);
        BF1(24, 25, 26, 27);
        BF2(28, 29, 30, 31);
    
        ADD( 8, 12);
        ADD(12, 10);
        ADD(10, 14);
        ADD(14,  9);
        ADD( 9, 13);
        ADD(13, 11);
        ADD(11, 15);
    
        out[ 0] = tab[0];
        out[16] = tab[1];
        out[ 8] = tab[2];
        out[24] = tab[3];
        out[ 4] = tab[4];
        out[20] = tab[5];
        out[12] = tab[6];
        out[28] = tab[7];
        out[ 2] = tab[8];
        out[18] = tab[9];
        out[10] = tab[10];
        out[26] = tab[11];
        out[ 6] = tab[12];
        out[22] = tab[13];
        out[14] = tab[14];
        out[30] = tab[15];
    
        ADD(24, 28);
        ADD(28, 26);
        ADD(26, 30);
        ADD(30, 25);
        ADD(25, 29);
        ADD(29, 27);
        ADD(27, 31);
    
        out[ 1] = tab[16] + tab[24];
        out[17] = tab[17] + tab[25];
        out[ 9] = tab[18] + tab[26];
        out[25] = tab[19] + tab[27];
        out[ 5] = tab[20] + tab[28];
        out[21] = tab[21] + tab[29];
        out[13] = tab[22] + tab[30];
        out[29] = tab[23] + tab[31];
        out[ 3] = tab[24] + tab[20];
        out[19] = tab[25] + tab[21];
        out[11] = tab[26] + tab[22];
        out[27] = tab[27] + tab[23];
        out[ 7] = tab[28] + tab[18];
        out[23] = tab[29] + tab[19];
        out[15] = tab[30] + tab[17];
        out[31] = tab[31];
    }
    
    #if FRAC_BITS <= 15
    
    
    static inline int round_sample(int *sum)
    
        sum1 = (*sum) >> OUT_SHIFT;
        *sum &= (1<<OUT_SHIFT)-1;
    
        if (sum1 < OUT_MIN)
            sum1 = OUT_MIN;
        else if (sum1 > OUT_MAX)
            sum1 = OUT_MAX;
    
    Luca Barbato's avatar
    Luca Barbato committed
    /* signed 16x16 -> 32 multiply add accumulate */
    #define MACS(rt, ra, rb) MAC16(rt, ra, rb)
    
    Luca Barbato's avatar
    Luca Barbato committed
    /* signed 16x16 -> 32 multiply */
    #define MULS(ra, rb) MUL16(ra, rb)
    
    static inline int round_sample(int64_t *sum)
    
        sum1 = (int)((*sum) >> OUT_SHIFT);
        *sum &= (1<<OUT_SHIFT)-1;
    
        if (sum1 < OUT_MIN)
            sum1 = OUT_MIN;
        else if (sum1 > OUT_MAX)
            sum1 = OUT_MAX;
    
    #   define MULS(ra, rb) MUL64(ra, rb)
    
        sum op MULS((w)[0 * 64], p[0 * 64]);\
        sum op MULS((w)[1 * 64], p[1 * 64]);\
        sum op MULS((w)[2 * 64], p[2 * 64]);\
        sum op MULS((w)[3 * 64], p[3 * 64]);\
        sum op MULS((w)[4 * 64], p[4 * 64]);\
        sum op MULS((w)[5 * 64], p[5 * 64]);\
        sum op MULS((w)[6 * 64], p[6 * 64]);\
        sum op MULS((w)[7 * 64], p[7 * 64]);\
    }
    
    #define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
    {                                               \
        int tmp;\
        tmp = p[0 * 64];\
        sum1 op1 MULS((w1)[0 * 64], tmp);\
        sum2 op2 MULS((w2)[0 * 64], tmp);\
        tmp = p[1 * 64];\
        sum1 op1 MULS((w1)[1 * 64], tmp);\
        sum2 op2 MULS((w2)[1 * 64], tmp);\
        tmp = p[2 * 64];\
        sum1 op1 MULS((w1)[2 * 64], tmp);\
        sum2 op2 MULS((w2)[2 * 64], tmp);\
        tmp = p[3 * 64];\
        sum1 op1 MULS((w1)[3 * 64], tmp);\
        sum2 op2 MULS((w2)[3 * 64], tmp);\
        tmp = p[4 * 64];\
        sum1 op1 MULS((w1)[4 * 64], tmp);\
        sum2 op2 MULS((w2)[4 * 64], tmp);\
        tmp = p[5 * 64];\
        sum1 op1 MULS((w1)[5 * 64], tmp);\
        sum2 op2 MULS((w2)[5 * 64], tmp);\
        tmp = p[6 * 64];\
        sum1 op1 MULS((w1)[6 * 64], tmp);\
        sum2 op2 MULS((w2)[6 * 64], tmp);\
        tmp = p[7 * 64];\
        sum1 op1 MULS((w1)[7 * 64], tmp);\
        sum2 op2 MULS((w2)[7 * 64], tmp);\
    
    void ff_mpa_synth_init(MPA_INT *window)
    {
        int i;
    
        /* max = 18760, max sum over all 16 coefs : 44736 */
        for(i=0;i<257;i++) {
            int v;
            v = mpa_enwindow[i];
    #if WFRAC_BITS < 16
            v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
    #endif
            window[i] = v;
            if ((i & 63) != 0)
                v = -v;
            if (i != 0)
                window[512 - i] = v;
    
    
    /* 32 sub band synthesis filter. Input: 32 sub band samples, Output:
       32 samples. */
    /* XXX: optimize by avoiding ring buffer usage */
    
    void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset,
    
                             MPA_INT *window, int *dither_state,
    
                             OUT_INT *samples, int incr,
    
                             int32_t sb_samples[SBLIMIT])
    
        int32_t tmp[32];
    
    Alex Beregszaszi's avatar
    Alex Beregszaszi committed
        register const MPA_INT *w, *w2, *p;
    
        offset = *synth_buf_offset;
        synth_buf = synth_buf_ptr + offset;
    
            /* NOTE: can cause a loss in precision if very high amplitude
               sound */
    
            if (v > 32767)
                v = 32767;
            else if (v < -32768)
                v = -32768;
    #endif
            synth_buf[j] = v;
        }
        /* copy to avoid wrap */
        memcpy(synth_buf + 512, synth_buf, 32 * sizeof(MPA_INT));
    
    
        sum = *dither_state;
    
        p = synth_buf + 16;
        SUM8(sum, +=, w, p);
        p = synth_buf + 48;
        SUM8(sum, -=, w + 32, p);
    
        *samples = round_sample(&sum);
    
        /* we calculate two samples at the same time to avoid one memory
           access per two sample */
        for(j=1;j<16;j++) {
            sum2 = 0;
            p = synth_buf + 16 + j;
            SUM8P2(sum, +=, sum2, -=, w, w2, p);
            p = synth_buf + 48 - j;
            SUM8P2(sum, -=, sum2, -=, w + 32, w2 + 32, p);
    
    
            *samples = round_sample(&sum);
    
            sum += sum2;
            *samples2 = round_sample(&sum);
    
        *samples = round_sample(&sum);
    
        *dither_state= sum;
    
        *synth_buf_offset = offset;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #define C3 FIXHR(0.86602540378443864676/2)
    
    /* 0.5 / cos(pi*(2*i+1)/36) */
    static const int icos36[9] = {
        FIXR(0.50190991877167369479),
        FIXR(0.51763809020504152469), //0
        FIXR(0.55168895948124587824),
        FIXR(0.61038729438072803416),
        FIXR(0.70710678118654752439), //1
        FIXR(0.87172339781054900991),
        FIXR(1.18310079157624925896),
        FIXR(1.93185165257813657349), //2
        FIXR(5.73685662283492756461),
    };
    
    /* 0.5 / cos(pi*(2*i+1)/36) */
    static const int icos36h[9] = {
        FIXHR(0.50190991877167369479/2),
        FIXHR(0.51763809020504152469/2), //0
        FIXHR(0.55168895948124587824/2),
        FIXHR(0.61038729438072803416/2),
        FIXHR(0.70710678118654752439/2), //1
        FIXHR(0.87172339781054900991/2),
        FIXHR(1.18310079157624925896/4),
        FIXHR(1.93185165257813657349/4), //2
    //    FIXHR(5.73685662283492756461),
    };
    
    
    /* 12 points IMDCT. We compute it "by hand" by factorizing obvious
       cases. */
    static void imdct12(int *out, int *in)
    {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int in0, in1, in2, in3, in4, in5, t1, t2;
    
    
        in0= in[0*3];
        in1= in[1*3] + in[0*3];
        in2= in[2*3] + in[1*3];
        in3= in[3*3] + in[2*3];
        in4= in[4*3] + in[3*3];
        in5= in[5*3] + in[4*3];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        in5 += in3;
        in3 += in1;
    
        in2= MULH(2*in2, C3);
    
        in3= MULH(4*in3, C3);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        t1 = in0 - in4;
    
        t2 = MULH(2*(in1 - in5), icos36h[4]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        out[10]= t1 + t2;
        out[ 1]=
        out[ 4]= t1 - t2;
    
        in0 += in4>>1;
        in4 = in0 + in2;
    
        in5 += 2*in1;
        in1 = MULH(in5 + in3, icos36h[1]);
    
        out[ 9]= in4 + in1;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        out[ 2]=
    
        out[ 3]= in4 - in1;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        in0 -= in2;
    
        in5 = MULH(2*(in5 - in3), icos36h[7]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        out[ 0]=
    
        out[ 5]= in0 - in5;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        out[ 6]=
    
        out[11]= in0 + in5;
    
    #define C1 FIXHR(0.98480775301220805936/2)
    #define C2 FIXHR(0.93969262078590838405/2)
    #define C3 FIXHR(0.86602540378443864676/2)
    #define C4 FIXHR(0.76604444311897803520/2)
    #define C5 FIXHR(0.64278760968653932632/2)
    #define C6 FIXHR(0.5/2)
    #define C7 FIXHR(0.34202014332566873304/2)
    #define C8 FIXHR(0.17364817766693034885/2)