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

📄 libmp3dec.c

📁 the author is LiFeng
💻 C
📖 第 1 页 / 共 5 页
字号:

    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

static int round_sample(int sum)
{
    int sum1;
    sum1 = (sum + (1 << (OUT_SHIFT - 1))) >> OUT_SHIFT;
    if (sum1 < -32768)
        sum1 = -32768;
    else if (sum1 > 32767)
        sum1 = 32767;
    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))


#else

static int round_sample(int64_t sum) 
{
    int sum1;
    sum1 = (int)((sum + (int64_t_C(1) << (OUT_SHIFT - 1))) >> OUT_SHIFT);
    if (sum1 < -32768)
        sum1 = -32768;
    else if (sum1 > 32767)
        sum1 = 32767;
    return sum1;
}

#define MULS(ra, rb) MUL64(ra, rb)

#endif

#define SUM8(sum, op, w, p) \
{                                               \
    sum op MULS((w)[0 * 64], p[0 * 64]);\
    sum op MULS((w)[1 * 64], p[1 * 64]);\
    sum op MULS((w)[2 * 64], p[2 * 64]);\
    sum op MULS((w)[3 * 64], p[3 * 64]);\
    sum op MULS((w)[4 * 64], p[4 * 64]);\
    sum op MULS((w)[5 * 64], p[5 * 64]);\
    sum op MULS((w)[6 * 64], p[6 * 64]);\
    sum op MULS((w)[7 * 64], p[7 * 64]);\
}

#define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
{                                               \
    int tmp;\
    tmp = p[0 * 64];\
    sum1 op1 MULS((w1)[0 * 64], tmp);\
    sum2 op2 MULS((w2)[0 * 64], tmp);\
    tmp = p[1 * 64];\
    sum1 op1 MULS((w1)[1 * 64], tmp);\
    sum2 op2 MULS((w2)[1 * 64], tmp);\
    tmp = p[2 * 64];\
    sum1 op1 MULS((w1)[2 * 64], tmp);\
    sum2 op2 MULS((w2)[2 * 64], tmp);\
    tmp = p[3 * 64];\
    sum1 op1 MULS((w1)[3 * 64], tmp);\
    sum2 op2 MULS((w2)[3 * 64], tmp);\
    tmp = p[4 * 64];\
    sum1 op1 MULS((w1)[4 * 64], tmp);\
    sum2 op2 MULS((w2)[4 * 64], tmp);\
    tmp = p[5 * 64];\
    sum1 op1 MULS((w1)[5 * 64], tmp);\
    sum2 op2 MULS((w2)[5 * 64], tmp);\
    tmp = p[6 * 64];\
    sum1 op1 MULS((w1)[6 * 64], tmp);\
    sum2 op2 MULS((w2)[6 * 64], tmp);\
    tmp = p[7 * 64];\
    sum1 op1 MULS((w1)[7 * 64], tmp);\
    sum2 op2 MULS((w2)[7 * 64], tmp);\
}


/* 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_t *samples, int incr, 
                         int32_t sb_samples[SBLIMIT])
{
    int32_t tmp[32];
    register MPA_INT *synth_buf;
    register const MPA_INT *w, *w2, *p;
    int j, offset, v;
    int16_t *samples2;
#if FRAC_BITS <= 15
    int sum, sum2;
#else
    int64_t sum, sum2;
#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));

    samples2 = samples + 31 * incr;
    w = window;
    w2 = window + 31;

    sum = 0;
    p = synth_buf + 16;
    SUM8(sum, +=, w, p);
    p = synth_buf + 48;
    SUM8(sum, -=, w + 32, p);
    *samples = round_sample(sum);
    samples += incr;
    w++;

    /* we calculate two samples at the same time to avoid one memory
       access per two sample */
    for(j=1;j<16;j++) {
        sum = 0;
        sum2 = 0;
        p = synth_buf + 16 + j;
        SUM8P2(sum, +=, sum2, -=, w, w2, p);
        p = synth_buf + 48 - j;
        SUM8P2(sum, -=, sum2, -=, w + 32, w2 + 32, p);

        *samples = round_sample(sum);
        samples += incr;
        *samples2 = round_sample(sum2);
        samples2 -= incr;
        w++;
        w2--;
    }
    
    p = synth_buf + 32;
    sum = 0;
    SUM8(sum, -=, w + 32, p);
    *samples = round_sample(sum);

    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_t 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_t 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;

        t2 = tmp[i + 1];
        t3 = tmp[i + 3];
        s1 = MULL(t3 + t2, icos36[j]);
        s3 = MULL(t3 - t2, icos36[8 - j]);
        
        t0 = MULL(s0 + s1, icos72[9 + 8 - j]);
        t1 = MULL(s0 - s1, icos72[8 - j]);
        out[18 + 9 + j] = t0;
        out[18 + 8 - j] = t0;
        out[9 + j] = -t1;
        out[8 - j] = t1;
        
        t0 = MULL(s2 + s3, icos72[9+j]);
        t1 = MULL(s2 - s3, icos72[j]);
        out[18 + 9 + (8 - j)] = t0;
        out[18 + j] = t0;
        out[9 + (8 - j)] = -t1;
        out[j] = t1;
        i += 4;
    }

    s0 = tmp[16];
    s1 = MULL(tmp[17], icos36[4]);
    t0 = MULL(s0 + s1, icos72[9 + 4]);
    t1 = MULL(s0 - s1, icos72[4]);
    out[18 + 9 + 4] = t0;
    out[18 + 8 - 4] = t0;
    out[9 + 4] = -t1;
    out[8 - 4] = t1;
}

/* fast header check for resync */
static int check_header(uint32_t header)
{
    /* header */
    if ((header & 0xffe00000) != 0xffe00000)
	return -1;
    /* layer check */
    if (((header >> 17) & 3) == 0)
	return -1;
    /* bit rate */
    if (((header >> 12) & 0xf) == 0xf)
	return -1;
    /* frequency */
    if (((header >> 10) & 3) == 3)
	return -1;
    return 0;
}

/* header + layer + bitrate + freq + lsf/mpeg25 */
#define SAME_HEADER_MASK \
   (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19))

/* 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)
{
    int sample_rate, frame_size, mpeg25, padding;
    int sample_rate_index, bitrate_index;
    if (header & (1<<20)) {
        s->lsf = (header & (1<<19)) ? 0 : 1;
        mpeg25 = 0;
    } else {
        s->lsf = 1;
        mpeg25 = 1;
    }
    
    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;
    s->sample_rate = sample_rate;

    bitrate_index = (header >> 12) & 0xf;
    padding = (header >> 9) & 1;
    s->mode = (header >> 6) & 3;
    s->mode_ext = (header >> 4) & 3;

    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;

⌨️ 快捷键说明

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