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

📄 libmp3dec.c

📁 the author is LiFeng
💻 C
📖 第 1 页 / 共 5 页
字号:
        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);
                for(j=len;j>0;j--)
                *exp_ptr++ = v0;
            }
        }
    }
}

/* handle n = 0 too */
static 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,
                          int16_t *exponents, int end_pos)
{
    int s_index;
    int linbits, code, x, y, l, v, i, j, k, pos;
    GetBitContext last_gb;
    VLC *vlc;
    uint8_t *code_table;

    /* 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];
        code_table = huff_code_table[l];

        /* read huffcode and compute each couple */
        for(;j>0;j--) {
            if (get_bits_count(&s->gb) >= end_pos)
                break;
            if (code_table) {
                code = get_vlc(&s->gb, vlc);
                if (code < 0)
                    return -1;
                y = code_table[code];
                x = y >> 4;
                y = y & 0x0f;
            } else {
                x = 0;
                y = 0;
            }
            if (x) {
                if (x == 15)
                    x += get_bitsz(&s->gb, linbits);
                v = l3_unscale(x, exponents[s_index]);
                if (get_bits1(&s->gb))
                    v = -v;
            } else {
                v = 0;
            }
            g->sb_hybrid[s_index++] = v;
            if (y) {
                if (y == 15)
                    y += get_bitsz(&s->gb, linbits);
                v = l3_unscale(y, exponents[s_index]);
                if (get_bits1(&s->gb))
                    v = -v;
            } else {
                v = 0;
            }
            g->sb_hybrid[s_index++] = v;
        }
    }
            
    /* high frequencies */
    vlc = &huff_quad_vlc[g->count1table_select];
    last_gb.buffer = NULL;
    while (s_index <= 572) {
        pos = get_bits_count(&s->gb);
        if (pos >= end_pos) {
            if (pos > end_pos && last_gb.buffer != NULL) {
                /* some encoders generate an incorrect size for this
                   part. We must go back into the data */
                s_index -= 4;
                s->gb = last_gb;
            }
            break;
        }
        last_gb= s->gb;

        code = get_vlc(&s->gb, vlc);
        if (code < 0)
            return -1;
        for(i=0;i<4;i++) {
            if (code & (8 >> i)) {
                /* non zero value. Could use a hand coded function for
                   'one' value */
                v = l3_unscale(1, exponents[s_index]);
                if(get_bits1(&s->gb))
                    v = -v;
            } else {
                v = 0;
            }
            g->sb_hybrid[s_index++] = v;
        }
    }
    while (s_index < 576)
        g->sb_hybrid[s_index++] = 0;
    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)
{
    int i, j, k, len;
    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;
        for(k=0;k<3;k++) {
            dst = tmp + k;
            for(j=len;j>0;j--) {
                *dst = *ptr++;
                dst += 3;
            }
        }
        memcpy(ptr1, tmp, len * 3 * sizeof(int32_t));
    }
}

#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,
                              GranuleDef *g)
{
    int32_t *ptr, *p0, *p1, *csa;
    int n, i, j;

    /* 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--) {
        p0 = ptr - 1;
        p1 = ptr;
        csa = &csa_table[0][0];       
        for(j=0;j<4;j++) {
            int tmp0 = *p0;
            int tmp1 = *p1;
            int64_t tmp2= MUL64(tmp0 + tmp1, csa[0]);
            *p0 = FRAC_RND(tmp2 - MUL64(tmp1, csa[2]));
            *p1 = FRAC_RND(tmp2 + MUL64(tmp0, csa[3]));
            p0--; p1++;
            csa += 4;
            tmp0 = *p0;
            tmp1 = *p1;
            tmp2= MUL64(tmp0 + tmp1, csa[0]);
            *p0 = FRAC_RND(tmp2 - MUL64(tmp1, csa[2]));
            *p1 = FRAC_RND(tmp2 + MUL64(tmp0, csa[3]));
            p0--; p1++;
            csa += 4;
        }
        ptr += 18;       
    }
}

static long int lrintf(float x)
{
    return (int)(x);
}

static void compute_antialias_float(MPADecodeContext *s,
                              GranuleDef *g)
{
    int32_t *ptr, *p0, *p1;
    int n, i, j;

    /* 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--) {
        float *csa = &csa_table_float[0][0];       
        p0 = ptr - 1;
        p1 = ptr;
        for(j=0;j<4;j++) {
            float tmp0 = *p0;
            float tmp1 = *p1;
            *p0 = lrintf(tmp0 * csa[0] - tmp1 * csa[1]);
            *p1 = lrintf(tmp0 * csa[1] + tmp1 * csa[0]);
            p0--; p1++;
            csa += 4;
            tmp0 = *p0;
            tmp1 = *p1;
            *p0 = lrintf(tmp0 * csa[0] - tmp1 * csa[1]);
            *p1 = lrintf(tmp0 * csa[1] + tmp1 * csa[0]);
            p0--; p1++;
            csa += 4;
        }
        ptr += 18;       
    }
}

static void compute_imdct(MPADecodeContext *s,
                          GranuleDef *g, 
                          int32_t *sb_samples,
                          int32_t *mdct_buf)
{
    int32_t *ptr, *win, *win1, *buf, *buf2, *out_ptr, *ptr1;
    int32_t in[6];
    int32_t out[36];
    int32_t out2[12];
    int i, j, k, mdct_long_end, v, sblimit;

    /* find last non zero block */
    ptr = g->sb_hybrid + 576;
    ptr1 = g->sb_hybrid + 2 * 18;
    while (ptr >= ptr1) {
        ptr -= 6;
        v = ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5];
        if (v != 0)
            break;
    }
    sblimit = ((ptr - g->sb_hybrid) / 18) + 1;

    if (g->block_type == 2) {
        /* XXX: check for 8000 Hz */
        if (g->switch_point)
            mdct_long_end = 2;
        else
            mdct_long_end = 0;
    } else {
        mdct_long_end = sblimit;
    }

    buf = mdct_buf;
    ptr = g->sb_hybrid;
    for(j=0;j<mdct_long_end;j++) {
        imdct36(out, ptr);
        /* apply window & overlap with previous buffer */
        out_ptr = sb_samples + j;
        /* select window */
        if (g->switch_point && j < 2)
            win1 = mdct_win[0];
        else
            win1 = mdct_win[g->block_type];
        /* select frequency inversion */
        win = win1 + ((4 * 36) & -(j & 1));
        for(i=0;i<18;i++) {
            *out_ptr = MULL(out[i], win[i]) + buf[i];
            buf[i] = MULL(out[i + 18], win[i + 18]);
            out_ptr += SBLIMIT;
        }
        ptr += 18;
        buf += 18;
    }
    for(j=mdct_long_end;j<sblimit;j++) {
        for(i=0;i<6;i++) {
            out[i] = 0;
            out[6 + i] = 0;

⌨️ 快捷键说明

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