📄 layer3.c
字号:
sfbound += *sfbwidth++;
/* change table if region boundary */
if (--rcount == 0) {
if (region == 0)
rcount = channel->region1_count + 1;
else
rcount = 0; /* all remaining */
entry = &mad_huff_pair_table[channel->table_select[++region]];
table = entry->table;
linbits = entry->linbits;
startbits = entry->startbits;
if (table == 0)
return MAD_ERROR_BADHUFFTABLE;
}
if (exp != *expptr) {
exp = *expptr;
reqhits = 0;
}
++expptr;
}
if (cachesz < 21) {
unsigned int bits;
bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
cachesz += bits;
bits_left -= bits;
}
/* hcod (0..19) */
clumpsz = startbits;
pair = &table[MASK(bitcache, cachesz, clumpsz)];
while (!pair->final) {
cachesz -= clumpsz;
clumpsz = pair->ptr.bits;
pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];
}
cachesz -= pair->value.hlen;
if (linbits) {
/* x (0..14) */
value = pair->value.x;
switch (value) {
case 0:
xrptr[0] = 0;
break;
case 15:
if (cachesz < linbits + 2) {
bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
cachesz += 16;
bits_left -= 16;
}
value += MASK(bitcache, cachesz, linbits);
cachesz -= linbits;
requantized = III_requantize(value, exp);
goto x_final;
default:
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
x_final:
xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
/* y (0..14) */
value = pair->value.y;
switch (value) {
case 0:
xrptr[1] = 0;
break;
case 15:
if (cachesz < linbits + 1) {
bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
cachesz += 16;
bits_left -= 16;
}
value += MASK(bitcache, cachesz, linbits);
cachesz -= linbits;
requantized = III_requantize(value, exp);
goto y_final;
default:
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
y_final:
xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
}
else {
/* x (0..1) */
value = pair->value.x;
if (value == 0)
xrptr[0] = 0;
else {
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
/* y (0..1) */
value = pair->value.y;
if (value == 0)
xrptr[1] = 0;
else {
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
}
xrptr += 2;
}
}
if (cachesz + bits_left < 0)
return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
/* count1 */
{
union huffquad const *table;
register mad_fixed_t requantized;
table = mad_huff_quad_table[channel->flags & count1table_select];
requantized = III_requantize(1, exp);
while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
union huffquad const *quad;
/* hcod (1..6) */
if (cachesz < 10) {
bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
cachesz += 16;
bits_left -= 16;
}
quad = &table[MASK(bitcache, cachesz, 4)];
/* quad tables guaranteed to have at most one extra lookup */
if (!quad->final) {
cachesz -= 4;
quad = &table[quad->ptr.offset +
MASK(bitcache, cachesz, quad->ptr.bits)];
}
cachesz -= quad->value.hlen;
if (xrptr == sfbound) {
sfbound += *sfbwidth++;
if (exp != *expptr) {
exp = *expptr;
requantized = III_requantize(1, exp);
}
++expptr;
}
/* v (0..1) */
xrptr[0] = quad->value.v ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
/* w (0..1) */
xrptr[1] = quad->value.w ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
xrptr += 2;
if (xrptr == sfbound) {
sfbound += *sfbwidth++;
if (exp != *expptr) {
exp = *expptr;
requantized = III_requantize(1, exp);
}
++expptr;
}
/* x (0..1) */
xrptr[0] = quad->value.x ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
/* y (0..1) */
xrptr[1] = quad->value.y ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
xrptr += 2;
}
if (cachesz + bits_left < 0) {
# if 0 && defined(DEBUG)
fprintf(stderr, "huffman count1 overrun (%d bits)\n",
-(cachesz + bits_left));
# endif
/* technically the bitstream is misformatted, but apparently
some encoders are just a bit sloppy with stuffing bits */
xrptr -= 4;
}
}
assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
# if 0 && defined(DEBUG)
if (bits_left < 0)
fprintf(stderr, "read %d bits too many\n", -bits_left);
else if (cachesz + bits_left > 0)
fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);
# endif
/* rzero */
while (xrptr < &xr[576]) {
xrptr[0] = 0;
xrptr[1] = 0;
xrptr += 2;
}
return MAD_ERROR_NONE;
}
# undef MASK
# undef MASK1BIT
/*
* NAME: III_reorder()
* DESCRIPTION: reorder frequency lines of a short block into subband order
*/
static
void III_reorder(mad_fixed_t xr[576], struct channel const *channel,
unsigned char const sfbwidth[39])
{
mad_fixed_t tmp[32][3][6];
unsigned int sb, l, f, w, sbw[3], sw[3];
/* this is probably wrong for 8000 Hz mixed blocks */
sb = 0;
if (channel->flags & mixed_block_flag) {
sb = 2;
l = 0;
while (l < 36)
l += *sfbwidth++;
}
for (w = 0; w < 3; ++w) {
sbw[w] = sb;
sw[w] = 0;
}
f = *sfbwidth++;
w = 0;
for (l = 18 * sb; l < 576; ++l) {
if (f-- == 0) {
f = *sfbwidth++ - 1;
w = (w + 1) % 3;
}
tmp[sbw[w]][w][sw[w]++] = xr[l];
if (sw[w] == 6) {
sw[w] = 0;
++sbw[w];
}
}
memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));
}
/*
* NAME: III_stereo()
* DESCRIPTION: perform joint stereo processing on a granule
*/
static
enum mad_error III_stereo(mad_fixed_t xr[2][576],
struct granule const *granule,
struct mad_header *header,
unsigned char const *sfbwidth)
{
short modes[39];
unsigned int sfbi, l, n, i;
if (granule->ch[0].block_type !=
granule->ch[1].block_type ||
(granule->ch[0].flags & mixed_block_flag) !=
(granule->ch[1].flags & mixed_block_flag))
return MAD_ERROR_BADSTEREO;
for (i = 0; i < 39; ++i)
modes[i] = header->mode_extension;
/* intensity stereo */
if (header->mode_extension & I_STEREO) {
struct channel const *right_ch = &granule->ch[1];
mad_fixed_t const *right_xr = xr[1];
unsigned int is_pos;
header->flags |= MAD_FLAG_I_STEREO;
/* first determine which scalefactor bands are to be processed */
if (right_ch->block_type == 2) {
unsigned int lower, start, max, bound[3], w;
lower = start = max = bound[0] = bound[1] = bound[2] = 0;
sfbi = l = 0;
if (right_ch->flags & mixed_block_flag) {
while (l < 36) {
n = sfbwidth[sfbi++];
for (i = 0; i < n; ++i) {
if (right_xr[i]) {
lower = sfbi;
break;
}
}
right_xr += n;
l += n;
}
start = sfbi;
}
w = 0;
while (l < 576) {
n = sfbwidth[sfbi++];
for (i = 0; i < n; ++i) {
if (right_xr[i]) {
max = bound[w] = sfbi;
break;
}
}
right_xr += n;
l += n;
w = (w + 1) % 3;
}
if (max)
lower = start;
/* long blocks */
for (i = 0; i < lower; ++i)
modes[i] = header->mode_extension & ~I_STEREO;
/* short blocks */
w = 0;
for (i = start; i < max; ++i) {
if (i < bound[w])
modes[i] = header->mode_extension & ~I_STEREO;
w = (w + 1) % 3;
}
}
else { /* right_ch->block_type != 2 */
unsigned int bound;
bound = 0;
for (sfbi = l = 0; l < 576; l += n) {
n = sfbwidth[sfbi++];
for (i = 0; i < n; ++i) {
if (right_xr[i]) {
bound = sfbi;
break;
}
}
right_xr += n;
}
for (i = 0; i < bound; ++i)
modes[i] = header->mode_extension & ~I_STEREO;
}
/* now do the actual processing */
if (header->flags & MAD_FLAG_LSF_EXT) {
unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
mad_fixed_t const *lsf_scale;
/* intensity_scale */
lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];
for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
n = sfbwidth[sfbi];
if (!(modes[sfbi] & I_STEREO))
continue;
if (illegal_pos[sfbi]) {
modes[sfbi] &= ~I_STEREO;
continue;
}
is_pos = right_ch->scalefac[sfbi];
for (i = 0; i < n; ++i) {
register mad_fixed_t left;
left = xr[0][l + i];
if (is_pos == 0)
xr[1][l + i] = left;
else {
register mad_fixed_t opposite;
opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);
if (is_pos & 1) {
xr[0][l + i] = opposite;
xr[1][l + i] = left;
}
else
xr[1][l + i] = opposite;
}
}
}
}
else { /* !(header->flags & MAD_FLAG_LSF_EXT) */
for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
n = sfbwidth[sfbi];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -