📄 libmp3dec.c
字号:
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 + -