Skip to content
Snippets Groups Projects
mpegaudiodec.c 85.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* using Lee like decomposition followed by hand coded 9 points DCT */
    
    static void imdct36(int *out, int *buf, int *in, int *win)
    
    {
        int i, j, t0, t1, t2, t3, s0, s1, s2, s3;
        int 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;
    
    #if 0
    //more accurate but slower
            int64_t t0, t1, t2, t3;
            t2 = in1[2*4] + in1[2*8] - in1[2*2];
    
            t3 = (in1[2*0] + (int64_t)(in1[2*6]>>1))<<32;
            t1 = in1[2*0] - in1[2*6];
            tmp1[ 6] = t1 - (t2>>1);
            tmp1[16] = t1 + t2;
    
            t0 = MUL64(2*(in1[2*2] + in1[2*4]),    C2);
            t1 = MUL64(   in1[2*4] - in1[2*8] , -2*C8);
            t2 = MUL64(2*(in1[2*2] + in1[2*8]),   -C4);
    
            tmp1[10] = (t3 - t0 - t2) >> 32;
            tmp1[ 2] = (t3 + t0 + t1) >> 32;
            tmp1[14] = (t3 + t2 - t1) >> 32;
    
            tmp1[ 4] = MULH(2*(in1[2*5] + in1[2*7] - in1[2*1]), -C3);
            t2 = MUL64(2*(in1[2*1] + in1[2*5]),    C1);
            t3 = MUL64(   in1[2*5] - in1[2*7] , -2*C7);
            t0 = MUL64(2*in1[2*3], C3);
    
            t1 = MUL64(2*(in1[2*1] + in1[2*7]),   -C5);
    
            tmp1[ 0] = (t2 + t3 + t0) >> 32;
            tmp1[12] = (t2 + t1 - t0) >> 32;
            tmp1[ 8] = (t3 - t1 - t0) >> 32;
    #else
            t2 = in1[2*4] + in1[2*8] - in1[2*2];
    
            t3 = in1[2*0] + (in1[2*6]>>1);
            t1 = in1[2*0] - in1[2*6];
            tmp1[ 6] = t1 - (t2>>1);
            tmp1[16] = t1 + t2;
    
            t0 = MULH(2*(in1[2*2] + in1[2*4]),    C2);
            t1 = MULH(   in1[2*4] - in1[2*8] , -2*C8);
            t2 = MULH(2*(in1[2*2] + in1[2*8]),   -C4);
    
            tmp1[10] = t3 - t0 - t2;
            tmp1[ 2] = t3 + t0 + t1;
            tmp1[14] = t3 + t2 - t1;
    
            tmp1[ 4] = MULH(2*(in1[2*5] + in1[2*7] - in1[2*1]), -C3);
            t2 = MULH(2*(in1[2*1] + in1[2*5]),    C1);
            t3 = MULH(   in1[2*5] - in1[2*7] , -2*C7);
            t0 = MULH(2*in1[2*3], C3);
    
            t1 = MULH(2*(in1[2*1] + in1[2*7]),   -C5);
    
            tmp1[ 0] = t2 + t3 + t0;
            tmp1[12] = t2 + t1 - t0;
            tmp1[ 8] = t3 - t1 - t0;
    #endif
    
        }
    
        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 = MULH(2*(t3 + t2), icos36h[j]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            out[(9 + j)*SBLIMIT] =  MULH(t1, win[9 + j]) + buf[9 + j];
    
            out[(8 - j)*SBLIMIT] =  MULH(t1, win[8 - j]) + buf[8 - j];
            buf[9 + j] = MULH(t0, win[18 + 9 + j]);
            buf[8 - j] = MULH(t0, win[18 + 8 - j]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            out[(9 + 8 - j)*SBLIMIT] =  MULH(t1, win[9 + 8 - j]) + buf[9 + 8 - j];
    
            out[(        j)*SBLIMIT] =  MULH(t1, win[        j]) + buf[        j];
            buf[9 + 8 - j] = MULH(t0, win[18 + 9 + 8 - j]);
            buf[      + j] = MULH(t0, win[18         + j]);
    
        s1 = MULH(2*tmp[17], icos36h[4]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        out[(9 + 4)*SBLIMIT] =  MULH(t1, win[9 + 4]) + buf[9 + 4];
    
        out[(8 - 4)*SBLIMIT] =  MULH(t1, win[8 - 4]) + buf[8 - 4];
        buf[9 + 4] = MULH(t0, win[18 + 9 + 4]);
        buf[8 - 4] = MULH(t0, win[18 + 8 - 4]);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    /* header decoding. MUST check the header before because no
    
       consistency check is done there. Return 1 if free format found and
       that the frame size must be computed externally */
    
    static int decode_header(MPADecodeContext *s, uint32_t header)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
        int sample_rate, frame_size, mpeg25, padding;
        int sample_rate_index, bitrate_index;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (header & (1<<20)) {
    
            s->lsf = (header & (1<<19)) ? 0 : 1;
            mpeg25 = 0;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        } else {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        s->layer = 4 - ((header >> 17) & 3);
        /* extract frequency */
    
        sample_rate_index = (header >> 10) & 3;
        sample_rate = mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);
        sample_rate_index += 3 * (s->lsf + mpeg25);
        s->sample_rate_index = sample_rate_index;
        s->error_protection = ((header >> 16) & 1) ^ 1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        bitrate_index = (header >> 12) & 0xf;
        padding = (header >> 9) & 1;
        //extension = (header >> 8) & 1;
        s->mode = (header >> 6) & 3;
        s->mode_ext = (header >> 4) & 3;
        //copyright = (header >> 3) & 1;
        //original = (header >> 2) & 1;
        //emphasis = header & 3;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
        if (s->mode == MPA_MONO)
            s->nb_channels = 1;
        else
            s->nb_channels = 2;
    
        if (bitrate_index != 0) {
            frame_size = mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];
            s->bit_rate = frame_size * 1000;
            switch(s->layer) {
            case 1:
                frame_size = (frame_size * 12000) / sample_rate;
                frame_size = (frame_size + padding) * 4;
                break;
            case 2:
                frame_size = (frame_size * 144000) / sample_rate;
                frame_size += padding;
                break;
            default:
            case 3:
                frame_size = (frame_size * 144000) / (sample_rate << s->lsf);
                frame_size += padding;
                break;
            }
            s->frame_size = frame_size;
        } else {
            /* if no frame size computed, signal it */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
    #if defined(DEBUG)
    
        dprintf("layer%d, %d Hz, %d kbits/s, ",
    
               s->layer, s->sample_rate, s->bit_rate);
        if (s->nb_channels == 2) {
            if (s->layer == 3) {
                if (s->mode_ext & MODE_EXT_MS_STEREO)
    
                    dprintf("ms-");
    
                    dprintf("i-");
    
            dprintf("stereo");
    
            dprintf("mono");
    
        dprintf("\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    #endif
    
    /* useful helper to get mpeg audio stream infos. Return -1 if error in
    
       header, otherwise the coded frame size in bytes */
    
    int mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate)
    
        if (ff_mpa_check_header(head) != 0)
    
            return -1;
    
        if (decode_header(s, head) != 0) {
            return -1;
        }
    
        switch(s->layer) {
        case 1:
    
            avctx->frame_size = 384;
    
            avctx->frame_size = 1152;
    
                avctx->frame_size = 576;
    
                avctx->frame_size = 1152;
    
        avctx->channels = s->nb_channels;
        avctx->bit_rate = s->bit_rate;
        avctx->sub_id = s->layer;
        return s->frame_size;
    
    /* 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;
    }
    
    /* bitrate is in kb/s */
    int l2_select_table(int bitrate, int nb_channels, int freq, int lsf)
    {
        int ch_bitrate, table;
    
        ch_bitrate = bitrate / nb_channels;
        if (!lsf) {
            if ((freq == 48000 && ch_bitrate >= 56) ||
    
                (ch_bitrate >= 56 && ch_bitrate <= 80))
    
            else if (freq != 48000 && ch_bitrate >= 96)
    
            else if (freq != 32000 && ch_bitrate <= 48)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
    
    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 = l2_select_table(s->bit_rate / 1000, s->nb_channels,
    
                                s->sample_rate, s->lsf);
        sblimit = sblimit_table[table];
        alloc_table = alloc_tables[table];
    
    
        if (s->mode == MPA_JSTEREO)
    
            bound = (s->mode_ext + 1) * 4;
        else
            bound = sblimit;
    
        dprintf("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
        }
    
    
    #ifdef DEBUG
        {
            for(ch=0;ch<s->nb_channels;ch++) {
                for(i=0;i<sblimit;i++)
    
                    dprintf(" %d", bit_alloc[ch][i]);
                dprintf("\n");
    
            }
        }
    #endif
    
        /* 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;
                    }
                }
            }
        }
    
    #ifdef DEBUG
        for(ch=0;ch<s->nb_channels;ch++) {
            for(i=0;i<sblimit;i++) {
                if (bit_alloc[ch][i]) {
                    sf = scale_factors[ch][i];
    
                    dprintf(" %d %d %d", sf[0], sf[1], sf[2]);
    
                    dprintf(" -");
    
            dprintf("\n");
    
        }
    #endif
    
        /* 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 = quant_bits[qindex];
                            if (bits < 0) {
                                /* 3 values at the same time */
                                v = get_bits(&s->gb, -bits);
                                steps = quant_steps[qindex];
    
                                s->sb_samples[ch][k * 12 + l + 0][i] =
    
                                    l2_unscale_group(steps, v % steps, scale);
                                v = v / steps;
    
                                s->sb_samples[ch][k * 12 + l + 1][i] =
    
                                    l2_unscale_group(steps, v % steps, scale);
                                v = v / steps;
    
                                s->sb_samples[ch][k * 12 + l + 2][i] =
    
                                    l2_unscale_group(steps, v, 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;
                        scale0 = scale_factors[0][i][k];
                        scale1 = scale_factors[1][i][k];
                        qindex = alloc_table[j+b];
                        bits = quant_bits[qindex];
                        if (bits < 0) {
                            /* 3 values at the same time */
                            v = get_bits(&s->gb, -bits);
                            steps = quant_steps[qindex];
                            mant = v % steps;
                            v = v / steps;
    
                            s->sb_samples[0][k * 12 + l + 0][i] =
    
                            s->sb_samples[1][k * 12 + l + 0][i] =
    
                                l2_unscale_group(steps, mant, scale1);
                            mant = v % steps;
                            v = v / steps;
    
                            s->sb_samples[0][k * 12 + l + 1][i] =
    
                            s->sb_samples[1][k * 12 + l + 1][i] =
    
                            s->sb_samples[0][k * 12 + l + 2][i] =
    
                            s->sb_samples[1][k * 12 + l + 2][i] =
    
                                l2_unscale_group(steps, v, scale1);
                        } else {
                            for(m=0;m<3;m++) {
                                mant = get_bits(&s->gb, bits);
    
                                s->sb_samples[0][k * 12 + l + m][i] =
    
                                s->sb_samples[1][k * 12 + l + m][i] =
    
                                    l1_unscale(bits - 1, mant, scale1);
                            }
                        }
                    } else {
                        s->sb_samples[0][k * 12 + l + 0][i] = 0;
                        s->sb_samples[0][k * 12 + l + 1][i] = 0;
                        s->sb_samples[0][k * 12 + l + 2][i] = 0;
                        s->sb_samples[1][k * 12 + l + 0][i] = 0;
                        s->sb_samples[1][k * 12 + l + 1][i] = 0;
                        s->sb_samples[1][k * 12 + l + 2][i] = 0;
                    }
                    /* next subband in alloc table */
    
                    j += 1 << bit_alloc_bits;
    
                }
                /* fill remaining samples to zero */
                for(i=sblimit;i<SBLIMIT;i++) {
                    for(ch=0;ch<s->nb_channels;ch++) {
                        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;
                    }
                }
            }
        }
        return 3 * 12;
    
    static inline void lsf_sf_expand(int *slen,
                                     int sf, int n1, int n2, int n3)
    {
        if (n3) {
            slen[3] = sf % n3;
            sf /= n3;
        } else {
            slen[3] = 0;
        }
        if (n2) {
            slen[2] = sf % n2;
            sf /= n2;
        } else {
            slen[2] = 0;
        }
        slen[1] = sf % n1;
        sf /= n1;
        slen[0] = sf;
    }
    
    
    static void exponents_from_scale_factors(MPADecodeContext *s,
    
                                             int16_t *exponents)
    
        const uint8_t *bstab, *pretab;
    
        int len, i, j, k, l, v0, shift, gain, gains[3];
    
        int16_t *exp_ptr;
    
    
        exp_ptr = exponents;
        gain = g->global_gain - 210;
        shift = g->scalefac_scale + 1;
    
        bstab = band_size_long[s->sample_rate_index];
        pretab = mpa_pretab[g->preflag];
        for(i=0;i<g->long_end;i++) {
    
            v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
    
            len = bstab[i];
            for(j=len;j>0;j--)
                *exp_ptr++ = v0;
        }
    
        if (g->short_start < 13) {
            bstab = band_size_short[s->sample_rate_index];
            gains[0] = gain - (g->subblock_gain[0] << 3);
            gains[1] = gain - (g->subblock_gain[1] << 3);
            gains[2] = gain - (g->subblock_gain[2] << 3);
            k = g->long_end;
            for(i=g->short_start;i<13;i++) {
                len = bstab[i];
                for(l=0;l<3;l++) {
    
                    v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
    
                    for(j=len;j>0;j--)
                    *exp_ptr++ = v0;
                }
            }
        }
    }
    
    /* handle n = 0 too */
    static inline int get_bitsz(GetBitContext *s, int n)
    {
        if (n == 0)
            return 0;
        else
            return get_bits(s, n);
    }
    
    static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
    
        int end_pos= FFMIN(end_pos2, s->gb.size_in_bits);
    
    
        /* low frequencies (called big values) */
        s_index = 0;
        for(i=0;i<3;i++) {
    
            j = g->region_size[i];
            if (j == 0)
                continue;
            /* select vlc table */
            k = g->table_select[i];
            l = mpa_huff_data[k][0];
            linbits = mpa_huff_data[k][1];
            vlc = &huff_vlc[l];
    
    
                memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*2*j);
    
            /* read huffcode and compute each couple */
            for(;j>0;j--) {
    
                int pos= get_bits_count(&s->gb);
    
                if (pos >= end_pos){
    //                av_log(NULL, AV_LOG_ERROR, "pos: %d %d %d %d\n", pos, end_pos, end_pos2, s_index);
                    if(s->in_gb.buffer && pos >= s->gb.size_in_bits){
                        s->gb= s->in_gb;
                        s->in_gb.buffer=NULL;
                        assert((get_bits_count(&s->gb) & 7) == 0);
                        skip_bits_long(&s->gb, pos - end_pos);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                        end_pos2=
    
                        end_pos= end_pos2 + get_bits_count(&s->gb) - pos;
                        pos= get_bits_count(&s->gb);
                    }
    //                av_log(NULL, AV_LOG_ERROR, "new pos: %d %d\n", pos, end_pos);
                    if(pos >= end_pos)
                        break;
                }
    
                y = get_vlc2(&s->gb, vlc->table, 7, 3);
    
    
                if(!y){
                    g->sb_hybrid[s_index  ] =
                    g->sb_hybrid[s_index+1] = 0;
                    s_index += 2;
                    continue;
                }
    
    
                exponent= exponents[s_index];
    
                dprintf("region=%d n=%d x=%d y=%d exp=%d\n",
    
                        i, g->region_size[i] - j, x, y, exponent);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                if(y&16){
                    x = y >> 5;
                    y = y & 0x0f;
    
                        v = expval_table[ exponent ][ x ];
    //                      v = expval_table[ (exponent&3) ][ x ] >> FFMIN(0 - (exponent>>2), 31);
    
                    }else{
                        x += get_bitsz(&s->gb, linbits);
    
                        v = l3_unscale(x, exponent);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    g->sb_hybrid[s_index] = v;
    
                        v = expval_table[ exponent ][ y ];
    
                    }else{
                        y += get_bitsz(&s->gb, linbits);
    
                        v = l3_unscale(y, exponent);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    g->sb_hybrid[s_index+1] = v;
                }else{
                    x = y >> 5;
                    y = y & 0x0f;
                    x += y;
                    if (x < 15){
                        v = expval_table[ exponent ][ x ];
                    }else{
                        x += get_bitsz(&s->gb, linbits);
                        v = l3_unscale(x, exponent);
                    }
                    if (get_bits1(&s->gb))
                        v = -v;
                    g->sb_hybrid[s_index+!!y] = v;
    
                    g->sb_hybrid[s_index+ !y] = 0;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                s_index+=2;
    
        /* high frequencies */
        vlc = &huff_quad_vlc[g->count1table_select];
    
            pos = get_bits_count(&s->gb);
            if (pos >= end_pos) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                if (pos > end_pos2 && last_pos){
                    /* some encoders generate an incorrect size for this
                       part. We must go back into the data */
                    s_index -= 4;
                    skip_bits_long(&s->gb, last_pos - pos);
                    av_log(NULL, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
                    break;
                }
    
    //                av_log(NULL, AV_LOG_ERROR, "pos2: %d %d %d %d\n", pos, end_pos, end_pos2, s_index);
                if(s->in_gb.buffer && pos >= s->gb.size_in_bits){
                    s->gb= s->in_gb;
                    s->in_gb.buffer=NULL;
                    assert((get_bits_count(&s->gb) & 7) == 0);
                    skip_bits_long(&s->gb, pos - end_pos);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    end_pos2=
    
                    end_pos= end_pos2 + get_bits_count(&s->gb) - pos;
                    pos= get_bits_count(&s->gb);
                }
    //                av_log(NULL, AV_LOG_ERROR, "new pos2: %d %d %d\n", pos, end_pos, s_index);
                if(pos >= end_pos)
                    break;
    
            code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
    
            dprintf("t=%d code=%d\n", g->count1table_select, code);
    
            g->sb_hybrid[s_index+0]=
            g->sb_hybrid[s_index+1]=
            g->sb_hybrid[s_index+2]=
            g->sb_hybrid[s_index+3]= 0;
            while(code){
                const static int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0};
    
                int pos= s_index+idxtab[code];
                code ^= 8>>idxtab[code];
    
                v = exp_table[ exponents[pos] ];
    //            v = exp_table[ (exponents[pos]&3) ] >> FFMIN(0 - (exponents[pos]>>2), 31);
    
                if(get_bits1(&s->gb))
                    v = -v;
                g->sb_hybrid[pos] = v;
    
            s_index+=4;
    
        memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*(576 - s_index));
    
    
        /* skip extension bits */
        bits_left = end_pos - get_bits_count(&s->gb);
    //av_log(NULL, AV_LOG_ERROR, "left:%d buf:%p\n", bits_left, s->in_gb.buffer);
        if (bits_left < 0) {
    
            av_log(NULL, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }
    
    
    /* Reorder short blocks from bitstream order to interleaved order. It
       would be faster to do it in parsing, but the code would be far more
       complicated */
    static void reorder_block(MPADecodeContext *s, GranuleDef *g)
    {
    
        int32_t *ptr, *dst, *ptr1;
        int32_t tmp[576];
    
    
        if (g->block_type != 2)
            return;
    
        if (g->switch_point) {
            if (s->sample_rate_index != 8) {
                ptr = g->sb_hybrid + 36;
            } else {
                ptr = g->sb_hybrid + 48;
            }
        } else {
            ptr = g->sb_hybrid;
        }
    
        for(i=g->short_start;i<13;i++) {
            len = band_size_short[s->sample_rate_index][i];
            ptr1 = ptr;
    
            dst = tmp;
            for(j=len;j>0;j--) {
                *dst++ = ptr[0*len];
                *dst++ = ptr[1*len];
                *dst++ = ptr[2*len];
                ptr++;
    
            ptr+=2*len;
            memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1));
    
        }
    }
    
    #define ISQRT2 FIXR(0.70710678118654752440)
    
    static void compute_stereo(MPADecodeContext *s,
                               GranuleDef *g0, GranuleDef *g1)
    {
        int i, j, k, l;
    
        int32_t v1, v2;
    
        int sf_max, tmp0, tmp1, sf, len, non_zero_found;
    
        int32_t (*is_tab)[16];
        int32_t *tab0, *tab1;
    
        int non_zero_found_short[3];
    
        /* intensity stereo */
        if (s->mode_ext & MODE_EXT_I_STEREO) {
            if (!s->lsf) {
                is_tab = is_table;
                sf_max = 7;
            } else {
                is_tab = is_table_lsf[g1->scalefac_compress & 1];
                sf_max = 16;
            }
    
            tab0 = g0->sb_hybrid + 576;
            tab1 = g1->sb_hybrid + 576;
    
            non_zero_found_short[0] = 0;
            non_zero_found_short[1] = 0;
            non_zero_found_short[2] = 0;
            k = (13 - g1->short_start) * 3 + g1->long_end - 3;
            for(i = 12;i >= g1->short_start;i--) {
                /* for last band, use previous scale factor */
                if (i != 11)
                    k -= 3;
                len = band_size_short[s->sample_rate_index][i];
                for(l=2;l>=0;l--) {
                    tab0 -= len;
                    tab1 -= len;
                    if (!non_zero_found_short[l]) {
                        /* test if non zero band. if so, stop doing i-stereo */
                        for(j=0;j<len;j++) {
                            if (tab1[j] != 0) {
                                non_zero_found_short[l] = 1;
                                goto found1;
                            }
                        }
                        sf = g1->scale_factors[k + l];
                        if (sf >= sf_max)
                            goto found1;
    
                        v1 = is_tab[0][sf];
                        v2 = is_tab[1][sf];
                        for(j=0;j<len;j++) {
                            tmp0 = tab0[j];
                            tab0[j] = MULL(tmp0, v1);
                            tab1[j] = MULL(tmp0, v2);
                        }
                    } else {
                    found1:
                        if (s->mode_ext & MODE_EXT_MS_STEREO) {
                            /* lower part of the spectrum : do ms stereo
                               if enabled */
                            for(j=0;j<len;j++) {
                                tmp0 = tab0[j];
                                tmp1 = tab1[j];
                                tab0[j] = MULL(tmp0 + tmp1, ISQRT2);
                                tab1[j] = MULL(tmp0 - tmp1, ISQRT2);
                            }
                        }
                    }
                }
            }
    
    
            non_zero_found = non_zero_found_short[0] |
                non_zero_found_short[1] |
    
                non_zero_found_short[2];
    
            for(i = g1->long_end - 1;i >= 0;i--) {
                len = band_size_long[s->sample_rate_index][i];
                tab0 -= len;
                tab1 -= len;
                /* test if non zero band. if so, stop doing i-stereo */
                if (!non_zero_found) {
                    for(j=0;j<len;j++) {
                        if (tab1[j] != 0) {
                            non_zero_found = 1;
                            goto found2;
                        }
                    }
                    /* for last band, use previous scale factor */
                    k = (i == 21) ? 20 : i;
                    sf = g1->scale_factors[k];
                    if (sf >= sf_max)
                        goto found2;
                    v1 = is_tab[0][sf];
                    v2 = is_tab[1][sf];
                    for(j=0;j<len;j++) {
                        tmp0 = tab0[j];
                        tab0[j] = MULL(tmp0, v1);
                        tab1[j] = MULL(tmp0, v2);
                    }
                } else {
                found2:
                    if (s->mode_ext & MODE_EXT_MS_STEREO) {
                        /* lower part of the spectrum : do ms stereo
                           if enabled */
                        for(j=0;j<len;j++) {
                            tmp0 = tab0[j];
                            tmp1 = tab1[j];
                            tab0[j] = MULL(tmp0 + tmp1, ISQRT2);
                            tab1[j] = MULL(tmp0 - tmp1, ISQRT2);
                        }
                    }
                }
            }
        } else if (s->mode_ext & MODE_EXT_MS_STEREO) {
            /* ms stereo ONLY */
            /* NOTE: the 1/sqrt(2) normalization factor is included in the
               global gain */
            tab0 = g0->sb_hybrid;
            tab1 = g1->sb_hybrid;
            for(i=0;i<576;i++) {
                tmp0 = tab0[i];
                tmp1 = tab1[i];
                tab0[i] = tmp0 + tmp1;
                tab1[i] = tmp0 - tmp1;
            }
        }
    }
    
    
    static void compute_antialias_integer(MPADecodeContext *s,
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int32_t *ptr, *csa;
        int n, i;
    
    
        /* we antialias only "long" bands */
        if (g->block_type == 2) {
            if (!g->switch_point)
                return;
            /* XXX: check this for 8000Hz case */
            n = 1;
        } else {
            n = SBLIMIT - 1;
        }
    
        ptr = g->sb_hybrid + 18;
        for(i = n;i > 0;i--) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            int tmp0, tmp1, tmp2;
            csa = &csa_table[0][0];
    #define INT_AA(j) \
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                tmp2= MULH(tmp0 + tmp1, csa[0+4*j]);\
    
                ptr[-1-j] = 4*(tmp2 - MULH(tmp1, csa[2+4*j]));\
                ptr[   j] = 4*(tmp2 + MULH(tmp0, csa[3+4*j]));
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    
            INT_AA(0)
            INT_AA(1)
            INT_AA(2)
            INT_AA(3)
            INT_AA(4)
            INT_AA(5)
            INT_AA(6)
            INT_AA(7)
    
        }
    }
    
    static void compute_antialias_float(MPADecodeContext *s,
                                  GranuleDef *g)
    {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int32_t *ptr;
        int n, i;
    
    
        /* we antialias only "long" bands */
        if (g->block_type == 2) {
            if (!g->switch_point)
                return;
            /* XXX: check this for 8000Hz case */
            n = 1;
        } else {
            n = SBLIMIT - 1;
        }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            float tmp0, tmp1;
    
            float *csa = &csa_table_float[0][0];
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    #define FLOAT_AA(j)\
            tmp0= ptr[-1-j];\
            tmp1= ptr[   j];\
            ptr[-1-j] = lrintf(tmp0 * csa[0+4*j] - tmp1 * csa[1+4*j]);\
            ptr[   j] = lrintf(tmp0 * csa[1+4*j] + tmp1 * csa[0+4*j]);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            FLOAT_AA(0)
            FLOAT_AA(1)
            FLOAT_AA(2)
            FLOAT_AA(3)
            FLOAT_AA(4)
            FLOAT_AA(5)
            FLOAT_AA(6)
            FLOAT_AA(7)