Skip to content
Snippets Groups Projects
mpegaudiodec.c 70.9 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 Libav.
    
     * Libav 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
     *
    
     * Libav 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 Libav; 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
    
    /**
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
     * MPEG Audio decoder.
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
    
    #include "libavutil/audioconvert.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #include "avcodec.h"
    
    #include "get_bits.h"
    
    #include "mathops.h"
    
    #include "dct32.h"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    /*
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
     */
    
    
    Roberto Togni's avatar
    Roberto Togni committed
    #include "mpegaudio.h"
    
    #include "mpegaudiodecheader.h"
    
    #if CONFIG_FLOAT
    
    #   define FIXR_OLD(a)    ((int)((a) * FRAC_ONE + 0.5))
    
    #   define FIXR(x)        ((float)(x))
    #   define FIXHR(x)       ((float)(x))
    
    #   define MULH3(x, y, s) ((s)*(y)*(x))
    #   define MULLx(x, y, s) ((y)*(x))
    #   define RENAME(a) a ## _float
    
    #   define OUT_FMT AV_SAMPLE_FMT_FLT
    
    #else
    #   define SHR(a,b)       ((a)>>(b))
    
    /* WARNING: only correct for posititive numbers */
    
    #   define FIXR_OLD(a)    ((int)((a) * FRAC_ONE + 0.5))
    #   define FIXR(a)        ((int)((a) * FRAC_ONE + 0.5))
    #   define FIXHR(a)       ((int)((a) * (1LL<<32) + 0.5))
    #   define MULH3(x, y, s) MULH((s)*(x), y)
    #   define MULLx(x, y, s) MULL(x,y,s)
    
    #   define RENAME(a)      a ## _fixed
    
    #   define OUT_FMT AV_SAMPLE_FMT_S16
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #define HEADER_SIZE 4
    
    
    static void RENAME(compute_antialias)(MPADecodeContext *s, GranuleDef *g);
    
    static void apply_window_mp3_c(MPA_INT *synth_buf, MPA_INT *window,
                                   int *dither_state, OUT_INT *samples, int incr);
    
    /* vlc structure for decoding layer 3 huffman tables */
    
    static VLC huff_vlc[16];
    
    static VLC_TYPE huff_vlc_tables[
      0+128+128+128+130+128+154+166+
      142+204+190+170+542+460+662+414
      ][2];
    static const int huff_vlc_tables_sizes[16] = {
      0, 128, 128, 128, 130, 128, 154, 166,
      142, 204, 190, 170, 542, 460, 662, 414
    };
    
    static VLC_TYPE huff_quad_vlc_tables[128+16][2];
    static const int huff_quad_vlc_tables_sizes[2] = {
      128, 16
    };
    
    static uint16_t band_index_long[9][23];
    
    #include "mpegaudio_tablegen.h"
    
    static INTFLOAT is_table[2][16];
    static INTFLOAT is_table_lsf[2][2][16];
    
    static int32_t csa_table[8][4];
    static float csa_table_float[8][4];
    
    static INTFLOAT mdct_win[8][36];
    
    static int16_t division_tab3[1<<6 ];
    static int16_t division_tab5[1<<8 ];
    static int16_t division_tab9[1<<11];
    
    static int16_t * const division_tabs[4] = {
        division_tab3, division_tab5, NULL, division_tab9
    };
    
    
    /* 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_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(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 */
    
    DECLARE_ALIGNED(16, MPA_INT, RENAME(ff_mpa_synth_window))[512+256];
    
    /**
     * Convert region offsets to region sizes and truncate
     * size to big_values.
     */
    
    static void ff_region_offset2size(GranuleDef *g){
    
        int i, k, j=0;
        g->region_size[2] = (576 / 2);
        for(i=0;i<3;i++) {
            k = FFMIN(g->region_size[i], g->big_values);
            g->region_size[i] = k - j;
            j = k;
        }
    }
    
    
    static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){
    
        if (g->block_type == 2)
            g->region_size[0] = (36 / 2);
        else {
            if (s->sample_rate_index <= 2)
                g->region_size[0] = (36 / 2);
            else if (s->sample_rate_index != 8)
                g->region_size[0] = (54 / 2);
            else
                g->region_size[0] = (108 / 2);
        }
        g->region_size[1] = (576 / 2);
    }
    
    
    static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2){
    
        int l;
        g->region_size[0] =
            band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
        /* should not overflow */
        l = FFMIN(ra1 + ra2 + 2, 22);
        g->region_size[1] =
            band_index_long[s->sample_rate_index][l] >> 1;
    }
    
    
    static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){
    
        if (g->block_type == 2) {
            if (g->switch_point) {
                /* if switched mode, we handle the 36 first samples as
                    long blocks.  For 8000Hz, we handle the 48 first
                    exponents as long blocks (XXX: check this!) */
                if (s->sample_rate_index <= 2)
                    g->long_end = 8;
                else if (s->sample_rate_index != 8)
                    g->long_end = 6;
                else
                    g->long_end = 4; /* 8000 Hz */
    
                g->short_start = 2 + (s->sample_rate_index != 8);
            } else {
                g->long_end = 0;
                g->short_start = 0;
            }
        } else {
            g->short_start = 13;
            g->long_end = 22;
        }
    }
    
    
    /* 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 av_cold 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;
        }
    }
    
    
    static av_cold int decode_init(AVCodecContext * avctx)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        MPADecodeContext *s = avctx->priv_data;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    Michel Bardiaux's avatar
    Michel Bardiaux committed
        s->avctx = avctx;
    
        s->apply_window_mp3 = apply_window_mp3_c;
    
        ff_mpegaudiodec_init_mmx(s);
    
    #endif
    #if CONFIG_FLOAT
        ff_dct_init(&s->dct, 5, DCT_II);
    
        if (HAVE_ALTIVEC && CONFIG_FLOAT) ff_mpegaudiodec_init_altivec(s);
    
    
        s->error_recognition= avctx->error_recognition;
    
            /* 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] = MULLx(norm, FIXR(1.0          * 2.0), FRAC_BITS);
                scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
                scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
    
                av_dlog(avctx, "%d: norm=%x s=%x %x %x\n",
    
                        scale_factor_mult[i][0],
                        scale_factor_mult[i][1],
                        scale_factor_mult[i][2]);
            }
    
            RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
    
            for(i=1;i<16;i++) {
                const HuffTable *h = &mpa_huff_tables[i];
    
    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 */
    
                huff_vlc[i].table = huff_vlc_tables+offset;
                huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                init_vlc(&huff_vlc[i], 7, 512,
    
                         tmp_bits, 1, 1, tmp_codes, 2, 2,
                         INIT_VLC_USE_NEW_STATIC);
                offset += huff_vlc_tables_sizes[i];
    
            assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
    
                huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
                huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
    
                init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
    
                         mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
                         INIT_VLC_USE_NEW_STATIC);
                offset += huff_quad_vlc_tables_sizes[i];
    
            assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
    
    
            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 */
    
            for (i = 0; i < 4; i++)
                if (ff_mpa_quant_bits[i] < 0)
                    for (j = 0; j < (1<<(-ff_mpa_quant_bits[i]+1)); j++) {
                        int val1, val2, val3, steps;
                        int val = j;
                        steps  = ff_mpa_quant_steps[i];
                        val1 = val % steps;
                        val /= steps;
                        val2 = val % steps;
                        val3 = val / steps;
                        division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
                    }
    
    
    
                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);
    
                    av_dlog(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;
    
                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)));
    
            }
    
            /* 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];
                }
            }
    
    
    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;
    }
    
    
    #if CONFIG_FLOAT
    static inline float round_sample(float *sum)
    {
        float sum1=*sum;
        *sum = 0;
        return sum1;
    }
    
    /* signed 16x16 -> 32 multiply add accumulate */
    #define MACS(rt, ra, rb) rt+=(ra)*(rb)
    
    /* signed 16x16 -> 32 multiply */
    #define MULS(ra, rb) ((ra)*(rb))
    
    #define MLSS(rt, ra, rb) rt-=(ra)*(rb)
    
    
    static inline int round_sample(int64_t *sum)
    
        sum1 = (int)((*sum) >> OUT_SHIFT);
        *sum &= (1<<OUT_SHIFT)-1;
    
        return av_clip_int16(sum1);
    
    #   define MULS(ra, rb) MUL64(ra, rb)
    
    #   define MACS(rt, ra, rb) MAC64(rt, ra, rb)
    #   define MLSS(rt, ra, rb) MLS64(rt, ra, rb)
    
    #define SUM8(op, sum, w, p)               \
    {                                         \
    
        op(sum, (w)[0 * 64], (p)[0 * 64]);    \
        op(sum, (w)[1 * 64], (p)[1 * 64]);    \
        op(sum, (w)[2 * 64], (p)[2 * 64]);    \
        op(sum, (w)[3 * 64], (p)[3 * 64]);    \
        op(sum, (w)[4 * 64], (p)[4 * 64]);    \
        op(sum, (w)[5 * 64], (p)[5 * 64]);    \
        op(sum, (w)[6 * 64], (p)[6 * 64]);    \
        op(sum, (w)[7 * 64], (p)[7 * 64]);    \
    
    }
    
    #define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
    {                                               \
    
        INTFLOAT tmp;\
    
        op1(sum1, (w1)[0 * 64], tmp);\
        op2(sum2, (w2)[0 * 64], tmp);\
    
        op1(sum1, (w1)[1 * 64], tmp);\
        op2(sum2, (w2)[1 * 64], tmp);\
    
        op1(sum1, (w1)[2 * 64], tmp);\
        op2(sum2, (w2)[2 * 64], tmp);\
    
        op1(sum1, (w1)[3 * 64], tmp);\
        op2(sum2, (w2)[3 * 64], tmp);\
    
        op1(sum1, (w1)[4 * 64], tmp);\
        op2(sum2, (w2)[4 * 64], tmp);\
    
        op1(sum1, (w1)[5 * 64], tmp);\
        op2(sum2, (w2)[5 * 64], tmp);\
    
        op1(sum1, (w1)[6 * 64], tmp);\
        op2(sum2, (w2)[6 * 64], tmp);\
    
        op1(sum1, (w1)[7 * 64], tmp);\
        op2(sum2, (w2)[7 * 64], tmp);\
    
    void av_cold RENAME(ff_mpa_synth_init)(MPA_INT *window)
    
    
        /* max = 18760, max sum over all 16 coefs : 44736 */
        for(i=0;i<257;i++) {
    
            v = ff_mpa_enwindow[i];
    
    #if CONFIG_FLOAT
            v *= 1.0 / (1LL<<(16 + FRAC_BITS));
    
    #endif
            window[i] = v;
            if ((i & 63) != 0)
                v = -v;
            if (i != 0)
                window[512 - i] = v;
    
    
        // Needed for avoiding shuffles in ASM implementations
        for(i=0; i < 8; i++)
            for(j=0; j < 16; j++)
                window[512+16*i+j] = window[64*i+32-j];
    
        for(i=0; i < 8; i++)
            for(j=0; j < 16; j++)
                window[512+128+16*i+j] = window[64*i+48-j];
    
    static void apply_window_mp3_c(MPA_INT *synth_buf, MPA_INT *window,
                                   int *dither_state, OUT_INT *samples, int incr)
    
    Alex Beregszaszi's avatar
    Alex Beregszaszi committed
        register const MPA_INT *w, *w2, *p;
    
    #if CONFIG_FLOAT
        float sum, sum2;
    
        memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
    
        sum = *dither_state;
    
        SUM8(MLSS, 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, MACS, sum2, MLSS, w, w2, p);
    
            SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p);
    
            *samples = round_sample(&sum);
    
            sum += sum2;
            *samples2 = round_sample(&sum);
    
        SUM8(MLSS, sum, w + 32, p);
    
        *samples = round_sample(&sum);
    
        *dither_state= sum;
    
    }
    
    
    /* 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_fixed(MPA_INT *synth_buf_ptr, int *synth_buf_offset,
    
                             MPA_INT *window, int *dither_state,
                             OUT_INT *samples, int incr,
                             INTFLOAT sb_samples[SBLIMIT])
    {
        register MPA_INT *synth_buf;
        int offset;
    
        offset = *synth_buf_offset;
        synth_buf = synth_buf_ptr + offset;
    
    
        ff_dct32_fixed(synth_buf, sb_samples);
    
        apply_window_mp3_c(synth_buf, window, dither_state, samples, incr);
    
        *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 INTFLOAT icos36[9] = {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        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 INTFLOAT 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(INTFLOAT *out, INTFLOAT *in)
    
        INTFLOAT 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= MULH3(in2, C3, 2);
        in3= MULH3(in3, C3, 4);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        t1 = in0 - in4;
    
        t2 = MULH3(in1 - in5, icos36h[4], 2);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        out[10]= t1 + t2;
        out[ 1]=
        out[ 4]= t1 - t2;
    
    
        in0 += SHR(in4, 1);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        in4 = in0 + in2;
    
        in5 += 2*in1;
    
        in1 = MULH3(in5 + in3, icos36h[1], 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 = MULH3(in5 - in3, icos36h[7], 2);
    
    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)
    
    
    
    /* using Lee like decomposition followed by hand coded 9 points DCT */
    
    static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
    
        int i, j;
        INTFLOAT t0, t1, t2, t3, s0, s1, s2, s3;
        INTFLOAT tmp[18], *tmp1, *in1;
    
    
        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;
    
            t2 = in1[2*4] + in1[2*8] - in1[2*2];
    
            t3 = in1[2*0] + SHR(in1[2*6],1);
    
            t1 = in1[2*0] - in1[2*6];
    
            tmp1[ 6] = t1 - SHR(t2,1);
    
            tmp1[16] = t1 + t2;
    
    
            t0 = MULH3(in1[2*2] + in1[2*4] ,    C2, 2);
            t1 = MULH3(in1[2*4] - in1[2*8] , -2*C8, 1);
            t2 = MULH3(in1[2*2] + in1[2*8] ,   -C4, 2);
    
            tmp1[10] = t3 - t0 - t2;
            tmp1[ 2] = t3 + t0 + t1;
            tmp1[14] = t3 + t2 - t1;
    
            tmp1[ 4] = MULH3(in1[2*5] + in1[2*7] - in1[2*1], -C3, 2);
            t2 = MULH3(in1[2*1] + in1[2*5],    C1, 2);
            t3 = MULH3(in1[2*5] - in1[2*7], -2*C7, 1);
            t0 = MULH3(in1[2*3], C3, 2);
    
            t1 = MULH3(in1[2*1] + in1[2*7],   -C5, 2);
    
    
            tmp1[ 0] = t2 + t3 + t0;
            tmp1[12] = t2 + t1 - t0;
            tmp1[ 8] = t3 - t1 - t0;
    
        }
    
        i = 0;
        for(j=0;j<4;j++) {
            t0 = tmp[i];
            t1 = tmp[i + 2];
            s0 = t1 + t0;
            s2 = t1 - t0;
    
            t2 = tmp[i + 1];
            t3 = tmp[i + 3];
    
            s1 = MULH3(t3 + t2, icos36h[j], 2);
            s3 = MULLx(t3 - t2, icos36[8 - j], FRAC_BITS);
    
            out[(9 + j)*SBLIMIT] =  MULH3(t1, win[9 + j], 1) + buf[9 + j];
            out[(8 - j)*SBLIMIT] =  MULH3(t1, win[8 - j], 1) + buf[8 - j];
            buf[9 + j] = MULH3(t0, win[18 + 9 + j], 1);
            buf[8 - j] = MULH3(t0, win[18 + 8 - j], 1);
    
            out[(9 + 8 - j)*SBLIMIT] =  MULH3(t1, win[9 + 8 - j], 1) + buf[9 + 8 - j];
            out[(        j)*SBLIMIT] =  MULH3(t1, win[        j], 1) + buf[        j];
            buf[9 + 8 - j] = MULH3(t0, win[18 + 9 + 8 - j], 1);
            buf[      + j] = MULH3(t0, win[18         + j], 1);
    
        s1 = MULH3(tmp[17], icos36h[4], 2);
    
        out[(9 + 4)*SBLIMIT] =  MULH3(t1, win[9 + 4], 1) + buf[9 + 4];
        out[(8 - 4)*SBLIMIT] =  MULH3(t1, win[8 - 4], 1) + buf[8 - 4];
        buf[9 + 4] = MULH3(t0, win[18 + 9 + 4], 1);
        buf[8 - 4] = MULH3(t0, win[18 + 8 - 4], 1);
    
    }
    
    /* return the number of decoded frames */
    static int mp_decode_layer1(MPADecodeContext *s)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT];
        uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT];
    
        if (s->mode == MPA_JSTEREO)
    
            bound = (s->mode_ext + 1) * 4;
        else
            bound = SBLIMIT;
    
        /* allocation bits */
        for(i=0;i<bound;i++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                allocation[ch][i] = get_bits(&s->gb, 4);
            }
        }
        for(i=bound;i<SBLIMIT;i++) {
            allocation[0][i] = get_bits(&s->gb, 4);
        }
    
        /* scale factors */
        for(i=0;i<bound;i++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                if (allocation[ch][i])
                    scale_factors[ch][i] = get_bits(&s->gb, 6);
            }
        }
        for(i=bound;i<SBLIMIT;i++) {
            if (allocation[0][i]) {
                scale_factors[0][i] = get_bits(&s->gb, 6);
                scale_factors[1][i] = get_bits(&s->gb, 6);
            }
        }
    
        /* compute samples */
        for(j=0;j<12;j++) {
            for(i=0;i<bound;i++) {
                for(ch=0;ch<s->nb_channels;ch++) {
                    n = allocation[ch][i];
                    if (n) {
                        mant = get_bits(&s->gb, n + 1);
                        v = l1_unscale(n, mant, scale_factors[ch][i]);
                    } else {
                        v = 0;
                    }
                    s->sb_samples[ch][j][i] = v;
                }
            }
            for(i=bound;i<SBLIMIT;i++) {
                n = allocation[0][i];
                if (n) {
                    mant = get_bits(&s->gb, n + 1);
                    v = l1_unscale(n, mant, scale_factors[0][i]);
                    s->sb_samples[0][j][i] = v;
                    v = l1_unscale(n, mant, scale_factors[1][i]);
                    s->sb_samples[1][j][i] = v;
                } else {
                    s->sb_samples[0][j][i] = 0;
                    s->sb_samples[1][j][i] = 0;
                }
            }
        }
        return 12;
    }
    
    static int mp_decode_layer2(MPADecodeContext *s)
    {
        int sblimit; /* number of used subbands */
        const unsigned char *alloc_table;
        int table, bit_alloc_bits, i, j, ch, bound, v;
        unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
        unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
        unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf;
        int scale, qindex, bits, steps, k, l, m, b;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
    
        sblimit = ff_mpa_sblimit_table[table];
        alloc_table = ff_mpa_alloc_tables[table];
    
        if (s->mode == MPA_JSTEREO)
    
        av_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
    
    
        /* sanity check */
        if( bound > sblimit ) bound = sblimit;
    
    
        /* parse bit allocation */
        j = 0;
        for(i=0;i<bound;i++) {
            bit_alloc_bits = alloc_table[j];
            for(ch=0;ch<s->nb_channels;ch++) {
                bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
            }
            j += 1 << bit_alloc_bits;
        }
        for(i=bound;i<sblimit;i++) {
            bit_alloc_bits = alloc_table[j];
            v = get_bits(&s->gb, bit_alloc_bits);
            bit_alloc[0][i] = v;
            bit_alloc[1][i] = v;
            j += 1 << bit_alloc_bits;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    
        /* scale codes */
        for(i=0;i<sblimit;i++) {
            for(ch=0;ch<s->nb_channels;ch++) {
    
                if (bit_alloc[ch][i])
    
        /* scale factors */
        for(i=0;i<sblimit;i++) {
            for(ch=0;ch<s->nb_channels;ch++) {
                if (bit_alloc[ch][i]) {
                    sf = scale_factors[ch][i];
                    switch(scale_code[ch][i]) {
                    default:
                    case 0:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[1] = get_bits(&s->gb, 6);
                        sf[2] = get_bits(&s->gb, 6);
                        break;
                    case 2:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[1] = sf[0];
                        sf[2] = sf[0];
                        break;
                    case 1:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[2] = get_bits(&s->gb, 6);
                        sf[1] = sf[0];
                        break;
                    case 3:
                        sf[0] = get_bits(&s->gb, 6);
                        sf[2] = get_bits(&s->gb, 6);
                        sf[1] = sf[2];
                        break;
                    }
                }
            }
        }
    
        /* samples */
        for(k=0;k<3;k++) {
            for(l=0;l<12;l+=3) {
                j = 0;
                for(i=0;i<bound;i++) {
                    bit_alloc_bits = alloc_table[j];
                    for(ch=0;ch<s->nb_channels;ch++) {
                        b = bit_alloc[ch][i];
                        if (b) {
                            scale = scale_factors[ch][i][k];
                            qindex = alloc_table[j+b];
    
                            bits = ff_mpa_quant_bits[qindex];
    
                                /* 3 values at the same time */
                                v = get_bits(&s->gb, -bits);
    
                                v2 = division_tabs[qindex][v];
                                steps  = ff_mpa_quant_steps[qindex];
    
    
                                s->sb_samples[ch][k * 12 + l + 0][i] =
    
                                    l2_unscale_group(steps, v2        & 15, scale);
    
                                s->sb_samples[ch][k * 12 + l + 1][i] =
    
                                    l2_unscale_group(steps, (v2 >> 4) & 15, scale);
    
                                s->sb_samples[ch][k * 12 + l + 2][i] =
    
                                    l2_unscale_group(steps,  v2 >> 8      , scale);
    
                            } else {
                                for(m=0;m<3;m++) {
                                    v = get_bits(&s->gb, bits);
                                    v = l1_unscale(bits - 1, v, scale);
                                    s->sb_samples[ch][k * 12 + l + m][i] = v;
                                }
                            }
                        } else {
                            s->sb_samples[ch][k * 12 + l + 0][i] = 0;
                            s->sb_samples[ch][k * 12 + l + 1][i] = 0;
                            s->sb_samples[ch][k * 12 + l + 2][i] = 0;
                        }
                    }
                    /* next subband in alloc table */
    
                    j += 1 << bit_alloc_bits;
    
                }
                /* XXX: find a way to avoid this duplication of code */
                for(i=bound;i<sblimit;i++) {
                    bit_alloc_bits = alloc_table[j];
                    b = bit_alloc[0][i];
                    if (b) {
                        int mant, scale0, scale1;