Skip to content
Snippets Groups Projects
mpegaudiodec.c 74 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 library 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 of the License, or (at your option) any later version.
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     *
    
     * This library 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 this library; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
    Fabrice Bellard's avatar
    Fabrice Bellard 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 */
    
    #ifdef CONFIG_MPEGAUDIO_HP
    #define USE_HIGHPRECISION
    #endif
    
    
    #ifdef USE_HIGHPRECISION
    #define FRAC_BITS   23   /* fractional bits for sb_samples and dct */
    #define WFRAC_BITS  16   /* fractional bits for window */
    #else
    #define FRAC_BITS   15   /* fractional bits for sb_samples and dct */
    #define WFRAC_BITS  14   /* fractional bits for window */
    #endif
    
    #define FRAC_ONE    (1 << FRAC_BITS)
    
    #define MULL(a,b) (((INT64)(a) * (INT64)(b)) >> FRAC_BITS)
    #define MUL64(a,b) ((INT64)(a) * (INT64)(b))
    #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)
    
    #if FRAC_BITS <= 15
    typedef INT16 MPA_INT;
    #else
    typedef INT32 MPA_INT;
    #endif
    
    /****************/
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #define HEADER_SIZE 4
    #define BACKSTEP_SIZE 512
    
    typedef struct MPADecodeContext {
    
        UINT8 inbuf1[2][MPA_MAX_CODED_FRAME_SIZE + BACKSTEP_SIZE];	/* input buffer */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int inbuf_index;
        UINT8 *inbuf_ptr, *inbuf;
        int frame_size;
    
        int free_format_frame_size; /* frame size in case of free format
                                       (zero if currently unknown) */
        /* next header (used in free format parsing) */
        UINT32 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;
        int old_frame_size;
        GetBitContext gb;
    
        int nb_channels;
        int mode;
        int mode_ext;
        int lsf;
        MPA_INT synth_buf[MPA_MAX_CHANNELS][512 * 2];
        int synth_buf_offset[MPA_MAX_CHANNELS];
        INT32 sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT];
        INT32 mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
    #ifdef DEBUG
        int frame_count;
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    } MPADecodeContext;
    
    
    /* layer 3 "granule" */
    typedef struct GranuleDef {
        UINT8 scfsi;
        int part2_3_length;
        int big_values;
        int global_gain;
        int scalefac_compress;
        UINT8 block_type;
        UINT8 switch_point;
        int table_select[3];
        int subblock_gain[3];
        UINT8 scalefac_scale;
        UINT8 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 scale_factors[40];
        INT32 sb_hybrid[SBLIMIT * 18]; /* 576 samples */
    } GranuleDef;
    
    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 *bits;
        const UINT16 *codes;
    } HuffTable;
    
    #include "mpegaudiodectab.h"
    
    /* vlc structure for decoding layer 3 huffman tables */
    static VLC huff_vlc[16]; 
    static UINT8 *huff_code_table[16];
    static VLC huff_quad_vlc[2];
    /* computed from band_size_long */
    static UINT16 band_index_long[9][23];
    /* XXX: free when all decoders are closed */
    #define TABLE_4_3_SIZE (8191 + 16)
    
    static INT8  *table_4_3_exp;
    
    #if FRAC_BITS <= 15
    static UINT16 *table_4_3_value;
    #else
    static UINT32 *table_4_3_value;
    #endif
    /* intensity stereo coef table */
    static INT32 is_table[2][16];
    static INT32 is_table_lsf[2][2][16];
    static INT32 csa_table[8][2];
    static INT32 mdct_win[8][36];
    
    /* lower 2 bits: modulo 3, higher bits: shift */
    static UINT16 scale_factor_modshift[64];
    /* [i][j]:  2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
    static INT32 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)) }
    
    static INT32 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 */
    
    };
    
    /* 2^(n/4) */
    static UINT32 scale_factor_mult3[4] = {
        FIXR(1.0),
        FIXR(1.18920711500272106671),
        FIXR(1.41421356237309504880),
        FIXR(1.68179283050742908605),
    
    static 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 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)
    {
    #if FRAC_BITS <= 15    
        unsigned int m;
    #else
        UINT64 m;
    #endif
        int e;
    
        e = table_4_3_exp[value];
        e += (exponent >> 2);
        e = FRAC_BITS - e;
    #if FRAC_BITS <= 15    
        if (e > 31)
            e = 31;
    #endif
        m = table_4_3_value[value];
    #if FRAC_BITS <= 15    
        m = (m * scale_factor_mult3[exponent & 3]);
        m = (m + (1 << (e-1))) >> e;
        return m;
    #else
        m = MUL64(m, scale_factor_mult3[exponent & 3]);
        m = (m + (UINT64_C(1) << (e-1))) >> e;
        return m;
    #endif
    }
    
    
    /* 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)(a) * (INT64)(b)) >> POW_FRAC_BITS)
    
    static int dev_4_3_coefs[DEV_ORDER];
    
    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
    
        if(!init) {
    
            /* 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);
    
                dprintf("%d: norm=%x s=%x %x %x\n",
                        i, norm, 
                        scale_factor_mult[i][0],
                        scale_factor_mult[i][1],
                        scale_factor_mult[i][2]);
            }
            
            /* window */
            /* 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;
            }
            
            /* huffman decode tables */
            huff_code_table[0] = NULL;
            for(i=1;i<16;i++) {
                const HuffTable *h = &mpa_huff_tables[i];
    
    	    int xsize, x, y;
                unsigned int n;
    
                UINT8 *code_table;
    
                xsize = h->xsize;
                n = xsize * xsize;
                /* XXX: fail test */
                init_vlc(&huff_vlc[i], 8, n, 
                         h->bits, 1, 1, h->codes, 2, 2);
                
                code_table = av_mallocz(n);
                j = 0;
                for(x=0;x<xsize;x++) {
                    for(y=0;y<xsize;y++)
                        code_table[j++] = (x << 4) | y;
                }
                huff_code_table[i] = code_table;
            }
            for(i=0;i<2;i++) {
                init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, 
                         mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 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 */
    	if (!av_mallocz_static(&table_4_3_exp,
    			       TABLE_4_3_SIZE * sizeof(table_4_3_exp[0])))
    	    return -1;
    	if (!av_mallocz_static(&table_4_3_value,
    			       TABLE_4_3_SIZE * sizeof(table_4_3_value[0])))
    
                m = int_pow(i, &e);
    #if 0
                /* test code */
                {
                    double f, fm;
                    int e1, m1;
                    f = pow((double)i, 4.0 / 3.0);
                    fm = frexp(f, &e1);
                    m1 = FIXR(2 * fm);
    #if FRAC_BITS <= 15
    
                    if ((unsigned short)m1 != m1) {
                        m1 = m1 >> 1;
                        e1++;
                    }
    
    #endif
                    e1--;
                    if (m != m1 || e != e1) {
                        printf("%4d: m=%x m1=%x e=%d e1=%d\n",
                               i, m, m1, e, e1);
                    }
                }
    
    #endif
                /* normalized to FRAC_BITS */
                table_4_3_value[i] = m;
    
            }
            
            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);
                    dprintf("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;
                csa_table[i][0] = FIX(cs);
                csa_table[i][1] = FIX(ca);
            }
    
            /* compute mdct windows */
            for(i=0;i<36;i++) {
                int v;
                v = FIXR(sin(M_PI * (i + 0.5) / 36.0));
                mdct_win[0][i] = v;
                mdct_win[1][i] = v;
                mdct_win[3][i] = v;
            }
            for(i=0;i<6;i++) {
                mdct_win[1][18 + i] = FIXR(1.0);
                mdct_win[1][24 + i] = FIXR(sin(M_PI * ((i + 6) + 0.5) / 12.0));
                mdct_win[1][30 + i] = FIXR(0.0);
    
                mdct_win[3][i] = FIXR(0.0);
                mdct_win[3][6 + i] = FIXR(sin(M_PI * (i + 0.5) / 12.0));
                mdct_win[3][12 + i] = FIXR(1.0);
            }
    
            for(i=0;i<12;i++)
                mdct_win[2][i] = FIXR(sin(M_PI * (i + 0.5) / 12.0));
            
            /* 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++) {
                printf("win%d=\n", j);
                for(i=0;i<36;i++)
                    printf("%f, ", (double)mdct_win[j][i] / FRAC_ONE);
                printf("\n");
            }
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            init = 1;
        }
    
        s->inbuf_index = 0;
        s->inbuf = &s->inbuf1[s->inbuf_index][BACKSTEP_SIZE];
        s->inbuf_ptr = s->inbuf;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }
    
    
    /* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */
    
    
    /* cos(i*pi/64) */
    
    #define COS0_0  FIXR(0.50060299823519630134)
    #define COS0_1  FIXR(0.50547095989754365998)
    #define COS0_2  FIXR(0.51544730992262454697)
    #define COS0_3  FIXR(0.53104259108978417447)
    #define COS0_4  FIXR(0.55310389603444452782)
    #define COS0_5  FIXR(0.58293496820613387367)
    #define COS0_6  FIXR(0.62250412303566481615)
    #define COS0_7  FIXR(0.67480834145500574602)
    #define COS0_8  FIXR(0.74453627100229844977)
    #define COS0_9  FIXR(0.83934964541552703873)
    #define COS0_10 FIXR(0.97256823786196069369)
    #define COS0_11 FIXR(1.16943993343288495515)
    #define COS0_12 FIXR(1.48416461631416627724)
    #define COS0_13 FIXR(2.05778100995341155085)
    #define COS0_14 FIXR(3.40760841846871878570)
    #define COS0_15 FIXR(10.19000812354805681150)
    
    #define COS1_0 FIXR(0.50241928618815570551)
    #define COS1_1 FIXR(0.52249861493968888062)
    #define COS1_2 FIXR(0.56694403481635770368)
    #define COS1_3 FIXR(0.64682178335999012954)
    #define COS1_4 FIXR(0.78815462345125022473)
    #define COS1_5 FIXR(1.06067768599034747134)
    #define COS1_6 FIXR(1.72244709823833392782)
    #define COS1_7 FIXR(5.10114861868916385802)
    
    #define COS2_0 FIXR(0.50979557910415916894)
    #define COS2_1 FIXR(0.60134488693504528054)
    #define COS2_2 FIXR(0.89997622313641570463)
    #define COS2_3 FIXR(2.56291544774150617881)
    
    #define COS3_0 FIXR(0.54119610014619698439)
    #define COS3_1 FIXR(1.30656296487637652785)
    
    #define COS4_0 FIXR(0.70710678118654752439)
    
    /* butterfly operator */
    #define BF(a, b, c)\
    {\
        tmp0 = tab[a] + tab[b];\
        tmp1 = tab[a] - tab[b];\
        tab[a] = tmp0;\
        tab[b] = MULL(tmp1, c);\
    }
    
    #define BF1(a, b, c, d)\
    {\
        BF(a, b, COS4_0);\
        BF(c, d, -COS4_0);\
        tab[c] += tab[d];\
    }
    
    #define BF2(a, b, c, d)\
    {\
        BF(a, b, COS4_0);\
        BF(c, d, -COS4_0);\
        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 *out, INT32 *tab)
    {
        int tmp0, tmp1;
    
        /* pass 1 */
        BF(0, 31, COS0_0);
        BF(1, 30, COS0_1);
        BF(2, 29, COS0_2);
        BF(3, 28, COS0_3);
        BF(4, 27, COS0_4);
        BF(5, 26, COS0_5);
        BF(6, 25, COS0_6);
        BF(7, 24, COS0_7);
        BF(8, 23, COS0_8);
        BF(9, 22, COS0_9);
        BF(10, 21, COS0_10);
        BF(11, 20, COS0_11);
        BF(12, 19, COS0_12);
        BF(13, 18, COS0_13);
        BF(14, 17, COS0_14);
        BF(15, 16, COS0_15);
    
        /* pass 2 */
        BF(0, 15, COS1_0);
        BF(1, 14, COS1_1);
        BF(2, 13, COS1_2);
        BF(3, 12, COS1_3);
        BF(4, 11, COS1_4);
        BF(5, 10, COS1_5);
        BF(6,  9, COS1_6);
        BF(7,  8, COS1_7);
        
        BF(16, 31, -COS1_0);
        BF(17, 30, -COS1_1);
        BF(18, 29, -COS1_2);
        BF(19, 28, -COS1_3);
        BF(20, 27, -COS1_4);
        BF(21, 26, -COS1_5);
        BF(22, 25, -COS1_6);
        BF(23, 24, -COS1_7);
        
        /* pass 3 */
        BF(0, 7, COS2_0);
        BF(1, 6, COS2_1);
        BF(2, 5, COS2_2);
        BF(3, 4, COS2_3);
        
        BF(8, 15, -COS2_0);
        BF(9, 14, -COS2_1);
        BF(10, 13, -COS2_2);
        BF(11, 12, -COS2_3);
        
        BF(16, 23, COS2_0);
        BF(17, 22, COS2_1);
        BF(18, 21, COS2_2);
        BF(19, 20, COS2_3);
        
        BF(24, 31, -COS2_0);
        BF(25, 30, -COS2_1);
        BF(26, 29, -COS2_2);
        BF(27, 28, -COS2_3);
    
        /* pass 4 */
        BF(0, 3, COS3_0);
        BF(1, 2, COS3_1);
        
        BF(4, 7, -COS3_0);
        BF(5, 6, -COS3_1);
        
        BF(8, 11, COS3_0);
        BF(9, 10, COS3_1);
        
        BF(12, 15, -COS3_0);
        BF(13, 14, -COS3_1);
        
        BF(16, 19, COS3_0);
        BF(17, 18, COS3_1);
        
        BF(20, 23, -COS3_0);
        BF(21, 22, -COS3_1);
        
        BF(24, 27, COS3_0);
        BF(25, 26, COS3_1);
        
        BF(28, 31, -COS3_0);
        BF(29, 30, -COS3_1);
        
        /* pass 5 */
        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);
        
        /* pass 6 */
        
        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];
    }
    
    #define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15)
    
    #if FRAC_BITS <= 15
    
    #define OUT_SAMPLE(sum)\
    {\
        int sum1;\
        sum1 = (sum + (1 << (OUT_SHIFT - 1))) >> OUT_SHIFT;\
        if (sum1 < -32768)\
            sum1 = -32768;\
        else if (sum1 > 32767)\
            sum1 = 32767;\
        *samples = sum1;\
        samples += incr;\
    }
    
    #define SUM8(off, op)                           \
    {                                               \
        sum op w[0 * 64 + off] * p[0 * 64];\
        sum op w[1 * 64 + off] * p[1 * 64];\
        sum op w[2 * 64 + off] * p[2 * 64];\
        sum op w[3 * 64 + off] * p[3 * 64];\
        sum op w[4 * 64 + off] * p[4 * 64];\
        sum op w[5 * 64 + off] * p[5 * 64];\
        sum op w[6 * 64 + off] * p[6 * 64];\
        sum op w[7 * 64 + off] * p[7 * 64];\
    }
    
    #else
    
    #define OUT_SAMPLE(sum)\
    {\
        int sum1;\
        sum1 = (int)((sum + (INT64_C(1) << (OUT_SHIFT - 1))) >> OUT_SHIFT);\
        if (sum1 < -32768)\
            sum1 = -32768;\
        else if (sum1 > 32767)\
            sum1 = 32767;\
        *samples = sum1;\
        samples += incr;\
    }
    
    #define SUM8(off, op)                           \
    {                                               \
        sum op MUL64(w[0 * 64 + off], p[0 * 64]);\
        sum op MUL64(w[1 * 64 + off], p[1 * 64]);\
        sum op MUL64(w[2 * 64 + off], p[2 * 64]);\
        sum op MUL64(w[3 * 64 + off], p[3 * 64]);\
        sum op MUL64(w[4 * 64 + off], p[4 * 64]);\
        sum op MUL64(w[5 * 64 + off], p[5 * 64]);\
        sum op MUL64(w[6 * 64 + off], p[6 * 64]);\
        sum op MUL64(w[7 * 64 + off], p[7 * 64]);\
    }
    
    #endif
    
    /* 32 sub band synthesis filter. Input: 32 sub band samples, Output:
       32 samples. */
    /* XXX: optimize by avoiding ring buffer usage */
    static void synth_filter(MPADecodeContext *s1,
                             int ch, INT16 *samples, int incr, 
                             INT32 sb_samples[SBLIMIT])
    {
        INT32 tmp[32];
        register MPA_INT *synth_buf, *p;
        register MPA_INT *w;
        int j, offset, v;
    #if FRAC_BITS <= 15
        int sum;
    #else
        INT64 sum;
    #endif
    
        dct32(tmp, sb_samples);
        
        offset = s1->synth_buf_offset[ch];
        synth_buf = s1->synth_buf[ch] + offset;
    
        for(j=0;j<32;j++) {
            v = tmp[j];
    #if FRAC_BITS <= 15
    
            /* 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));
    
        w = window;
        for(j=0;j<16;j++) {
            sum = 0;
            p = synth_buf + 16 + j;    /* 0-15  */
            SUM8(0, +=);
            p = synth_buf + 48 - j;    /* 32-47 */
            SUM8(32, -=);
            OUT_SAMPLE(sum);
            w++;
        }
        
        p = synth_buf + 32; /* 48 */
        sum = 0;
        SUM8(32, -=);
        OUT_SAMPLE(sum);
        w++;
    
        for(j=17;j<32;j++) {
            sum = 0;
            p = synth_buf + 48 - j; /* 17-31 */
            SUM8(0, -=);
            p = synth_buf + 16 + j; /* 49-63 */
            SUM8(32, -=);
            OUT_SAMPLE(sum);
            w++;
        }
        offset = (offset - 32) & 511;
        s1->synth_buf_offset[ch] = offset;
    }
    
    /* cos(pi*i/24) */
    #define C1  FIXR(0.99144486137381041114)
    #define C3  FIXR(0.92387953251128675612)
    #define C5  FIXR(0.79335334029123516458)
    #define C7  FIXR(0.60876142900872063941)
    #define C9  FIXR(0.38268343236508977173)
    #define C11 FIXR(0.13052619222005159154)
    
    /* 12 points IMDCT. We compute it "by hand" by factorizing obvious
       cases. */
    static void imdct12(int *out, int *in)
    {
        int tmp;
        INT64 in1_3, in1_9, in4_3, in4_9;
    
        in1_3 = MUL64(in[1], C3);
        in1_9 = MUL64(in[1], C9);
        in4_3 = MUL64(in[4], C3);
        in4_9 = MUL64(in[4], C9);
        
        tmp = FRAC_RND(MUL64(in[0], C7) - in1_3 - MUL64(in[2], C11) + 
                       MUL64(in[3], C1) - in4_9 - MUL64(in[5], C5));
        out[0] = tmp;
        out[5] = -tmp;
        tmp = FRAC_RND(MUL64(in[0] - in[3], C9) - in1_3 + 
                       MUL64(in[2] + in[5], C3) - in4_9);
        out[1] = tmp;
        out[4] = -tmp;
        tmp = FRAC_RND(MUL64(in[0], C11) - in1_9 + MUL64(in[2], C7) -
                       MUL64(in[3], C5) + in4_3 - MUL64(in[5], C1));
        out[2] = tmp;
        out[3] = -tmp;
        tmp = FRAC_RND(MUL64(-in[0], C5) + in1_9 + MUL64(in[2], C1) + 
                       MUL64(in[3], C11) - in4_3 - MUL64(in[5], C7));
        out[6] = tmp;
        out[11] = tmp;
        tmp = FRAC_RND(MUL64(-in[0] + in[3], C3) - in1_9 + 
                       MUL64(in[2] + in[5], C9) + in4_3);
        out[7] = tmp;
        out[10] = tmp;
        tmp = FRAC_RND(-MUL64(in[0], C1) - in1_3 - MUL64(in[2], C5) -
                       MUL64(in[3], C7) - in4_9 - MUL64(in[5], C11));
        out[8] = tmp;
        out[9] = tmp;
    }
    
    #undef C1
    #undef C3
    #undef C5
    #undef C7
    #undef C9
    #undef C11
    
    /* cos(pi*i/18) */
    #define C1 FIXR(0.98480775301220805936)
    #define C2 FIXR(0.93969262078590838405)
    #define C3 FIXR(0.86602540378443864676)
    #define C4 FIXR(0.76604444311897803520)
    #define C5 FIXR(0.64278760968653932632)
    #define C6 FIXR(0.5)
    #define C7 FIXR(0.34202014332566873304)
    #define C8 FIXR(0.17364817766693034885)
    
    /* 0.5 / cos(pi*(2*i+1)/36) */
    static const int icos36[9] = {
        FIXR(0.50190991877167369479),
        FIXR(0.51763809020504152469),
        FIXR(0.55168895948124587824),
        FIXR(0.61038729438072803416),
        FIXR(0.70710678118654752439),
        FIXR(0.87172339781054900991),
        FIXR(1.18310079157624925896),
        FIXR(1.93185165257813657349),
        FIXR(5.73685662283492756461),
    };
    
    static const int icos72[18] = {
        /* 0.5 / cos(pi*(2*i+19)/72) */
        FIXR(0.74009361646113053152),
        FIXR(0.82133981585229078570),
        FIXR(0.93057949835178895673),
        FIXR(1.08284028510010010928),
        FIXR(1.30656296487637652785),
        FIXR(1.66275476171152078719),
        FIXR(2.31011315767264929558),
        FIXR(3.83064878777019433457),
        FIXR(11.46279281302667383546),
    
        /* 0.5 / cos(pi*(2*(i + 18) +19)/72) */
        FIXR(-0.67817085245462840086),
        FIXR(-0.63023620700513223342),
        FIXR(-0.59284452371708034528),
        FIXR(-0.56369097343317117734),
        FIXR(-0.54119610014619698439),
        FIXR(-0.52426456257040533932),
        FIXR(-0.51213975715725461845),
        FIXR(-0.50431448029007636036),
        FIXR(-0.50047634258165998492),
    };
    
    /* using Lee like decomposition followed by hand coded 9 points DCT */
    static void imdct36(int *out, int *in)
    {
        int i, j, t0, t1, t2, t3, s0, s1, s2, s3;
        int tmp[18], *tmp1, *in1;
        INT64 in3_3, in6_6;
    
        for(i=17;i>=1;i--)
            in[i] += in[i-1];
        for(i=17;i>=3;i-=2)
            in[i] += in[i-2];
    
        for(j=0;j<2;j++) {
            tmp1 = tmp + j;
            in1 = in + j;
    
            in3_3 = MUL64(in1[2*3], C3);
            in6_6 = MUL64(in1[2*6], C6);
    
            tmp1[0] = FRAC_RND(MUL64(in1[2*1], C1) + in3_3 + 
                               MUL64(in1[2*5], C5) + MUL64(in1[2*7], C7));
            tmp1[2] = in1[2*0] + FRAC_RND(MUL64(in1[2*2], C2) + 
                                          MUL64(in1[2*4], C4) + in6_6 + 
                                          MUL64(in1[2*8], C8));
            tmp1[4] = FRAC_RND(MUL64(in1[2*1] - in1[2*5] - in1[2*7], C3));
            tmp1[6] = FRAC_RND(MUL64(in1[2*2] - in1[2*4] - in1[2*8], C6)) - 
                in1[2*6] + in1[2*0];
            tmp1[8] = FRAC_RND(MUL64(in1[2*1], C5) - in3_3 - 
                               MUL64(in1[2*5], C7) + MUL64(in1[2*7], C1));
            tmp1[10] = in1[2*0] + FRAC_RND(MUL64(-in1[2*2], C8) - 
                                           MUL64(in1[2*4], C2) + in6_6 + 
                                           MUL64(in1[2*8], C4));
            tmp1[12] = FRAC_RND(MUL64(in1[2*1], C7) - in3_3 + 
                                MUL64(in1[2*5], C1) - 
                                MUL64(in1[2*7], C5));
            tmp1[14] = in1[2*0] + FRAC_RND(MUL64(-in1[2*2], C4) + 
                                           MUL64(in1[2*4], C8) + in6_6 - 
                                           MUL64(in1[2*8], C2));
            tmp1[16] = in1[2*0] - in1[2*2] + in1[2*4] - in1[2*6] + in1[2*8];
        }
    
        i = 0;
        for(j=0;j<4;j++) {
            t0 = tmp[i];
            t1 = tmp[i + 2];
            s0 = t1 + t0;
            s2 = t1 - t0;