author | harlekin <harlekin> | 2002-04-19 16:08:55 (UTC) |
---|---|---|
committer | harlekin <harlekin> | 2002-04-19 16:08:55 (UTC) |
commit | 7ea4abeb652e6787e57a938e1ca028d25fd249ce (patch) (side-by-side diff) | |
tree | ee08f2d9d6aaa8adb1c5f07f4124da8a61eb8cd5 /core/multimedia/opieplayer/libmad/layer3.c | |
parent | caa7ced77b9014526607f9f65c58aabe7e0ba631 (diff) | |
download | opie-7ea4abeb652e6787e57a938e1ca028d25fd249ce.zip opie-7ea4abeb652e6787e57a938e1ca028d25fd249ce.tar.gz opie-7ea4abeb652e6787e57a938e1ca028d25fd249ce.tar.bz2 |
new libmad version, less cpu usage
Diffstat (limited to 'core/multimedia/opieplayer/libmad/layer3.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmad/layer3.c | 150 |
1 files changed, 80 insertions, 70 deletions
diff --git a/core/multimedia/opieplayer/libmad/layer3.c b/core/multimedia/opieplayer/libmad/layer3.c index 194fc7e..03f13fe 100644 --- a/core/multimedia/opieplayer/libmad/layer3.c +++ b/core/multimedia/opieplayer/libmad/layer3.c @@ -1,14 +1,14 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * @@ -18,48 +18,56 @@ * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include <stdlib.h> # include <string.h> -# include <assert.h> + +# ifdef HAVE_ASSERT_H +# include <assert.h> +# endif # ifdef HAVE_LIMITS_H # include <limits.h> # else # define CHAR_BIT 8 # endif # include "fixed.h" # include "bit.h" # include "stream.h" # include "frame.h" # include "huffman.h" # include "layer3.h" /* --- Layer III ----------------------------------------------------------- */ enum { count1table_select = 0x01, scalefac_scale = 0x02, preflag = 0x04, mixed_block_flag = 0x08 }; +enum { + I_STEREO = 0x1, + MS_STEREO = 0x2 +}; + struct sideinfo { unsigned int main_data_begin; unsigned int private_bits; unsigned char scfsi[2]; struct granule { struct channel { /* from side info */ unsigned short part2_3_length; unsigned short big_values; unsigned short global_gain; @@ -494,25 +502,25 @@ mad_fixed_t const is_lsf_table[2][15] = { /* * NAME: III_sideinfo() * DESCRIPTION: decode frame side information from a bitstream */ static enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, int lsf, struct sideinfo *si, unsigned int *data_bitlen, unsigned int *priv_bitlen) { unsigned int ngr, gr, ch, i; - enum mad_error result = 0; + enum mad_error result = MAD_ERROR_NONE; *data_bitlen = 0; *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); si->private_bits = mad_bit_read(ptr, *priv_bitlen); ngr = 1; if (!lsf) { ngr = 2; for (ch = 0; ch < nch; ++ch) @@ -593,25 +601,25 @@ unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, struct channel *gr1ch, int mode_extension) { struct mad_bitptr start; unsigned int scalefac_compress, index, slen[4], part, n, i; unsigned char const *nsfb; start = *ptr; scalefac_compress = channel->scalefac_compress; index = (channel->block_type == 2) ? ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; - if (!((mode_extension & 0x1) && gr1ch)) { + if (!((mode_extension & I_STEREO) && gr1ch)) { if (scalefac_compress < 400) { slen[0] = (scalefac_compress >> 4) / 5; slen[1] = (scalefac_compress >> 4) % 5; slen[2] = (scalefac_compress % 16) >> 2; slen[3] = scalefac_compress % 4; nsfb = nsfb_table[0][index]; } else if (scalefac_compress < 500) { scalefac_compress -= 400; slen[0] = (scalefac_compress >> 2) / 5; @@ -634,25 +642,25 @@ unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, nsfb = nsfb_table[2][index]; } n = 0; for (part = 0; part < 4; ++part) { for (i = 0; i < nsfb[part]; ++i) channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); } while (n < 39) channel->scalefac[n++] = 0; } - else { /* (mode_extension & 0x1) && gr1ch (i.e. ch == 1) */ + else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ scalefac_compress >>= 1; if (scalefac_compress < 180) { slen[0] = scalefac_compress / 36; slen[1] = (scalefac_compress % 36) / 6; slen[2] = (scalefac_compress % 36) % 6; slen[3] = 0; nsfb = nsfb_table[3][index]; } else if (scalefac_compress < 244) { scalefac_compress -= 180; @@ -766,24 +774,46 @@ unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, else { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } channel->scalefac[21] = 0; } return mad_bit_length(&start, ptr); } /* + * The Layer III formula for requantization and scaling is defined by + * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: + * + * long blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210)) * + * 2^-(scalefac_multiplier * + * (scalefac_l[sfb] + preflag * pretab[sfb])) + * + * short blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * + * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) + * + * where: + * scalefac_multiplier = (scalefac_scale + 1) / 2 + * + * The routines III_exponents() and III_requantize() facilitate this + * calculation. + */ + +/* * NAME: III_exponents() * DESCRIPTION: calculate scalefactor exponents */ static void III_exponents(struct channel const *channel, unsigned char const *sfbwidth, signed int exponents[39]) { signed int gain; unsigned int scalefac_multiplier, sfbi; gain = (signed int) channel->global_gain - 210; scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; @@ -847,54 +877,40 @@ void III_exponents(struct channel const *channel, /* * NAME: III_requantize() * DESCRIPTION: requantize one (positive) value */ static mad_fixed_t III_requantize(unsigned int value, signed int exp) { mad_fixed_t requantized; signed int frac; struct fixedfloat const *power; - /* - * long blocks: - * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * - * 2^((1/4) * (global_gain - 210)) * - * 2^-(scalefac_multiplier * - * (scalefac_l[sfb] + preflag * pretab[sfb])) - * - * short blocks: - * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * - * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * - * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) - * - * where: - * scalefac_multiplier = (scalefac_scale + 1) / 2 - */ - - frac = exp % 4; + frac = exp % 4; /* assumes sign(frac) == sign(exp) */ exp /= 4; power = &rq_table[value]; requantized = power->mantissa; exp += power->exponent; if (exp < 0) { if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) { /* underflow */ requantized = 0; } - else + else { + requantized += 1L << (-exp - 1); requantized >>= -exp; + } } else { if (exp >= 5) { /* overflow */ # if defined(DEBUG) fprintf(stderr, "requantize overflow (%f * 2^%d)\n", mad_f_todouble(requantized), exp); # endif requantized = MAD_F_MAX; } else requantized <<= exp; @@ -1242,105 +1258,102 @@ enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], 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 0; + 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, sfbi, f, w, sbw[3], sw[3]; + unsigned int sb, l, f, w, sbw[3], sw[3]; /* this is probably wrong for 8000 Hz mixed blocks */ - if (channel->flags & mixed_block_flag) - sb = 2, sfbi = 3 * 3; - else - sb = 0, sfbi = 0; + 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[sfbi]; + 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]; } - - if (--f == 0) { - if (++w == 3) - w = 0; - - f = sfbwidth[++sfbi]; - } } 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; - enum { - i_stereo = 0x1, - ms_stereo = 0x2 - }; - 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) { + 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; @@ -1378,74 +1391,74 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], 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; + 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; + 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; + 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)) + if (!(modes[sfbi] & I_STEREO)) continue; if (illegal_pos[sfbi]) { - modes[sfbi] &= ~i_stereo; + 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; @@ -1459,111 +1472,108 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], 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]; - if (!(modes[sfbi] & i_stereo)) + if (!(modes[sfbi] & I_STEREO)) continue; is_pos = right_ch->scalefac[sfbi]; if (is_pos >= 7) { /* illegal intensity position */ - modes[sfbi] &= ~i_stereo; + modes[sfbi] &= ~I_STEREO; continue; } for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]); xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]); } } } } /* middle/side stereo */ - if (header->mode_extension & ms_stereo) { + if (header->mode_extension & MS_STEREO) { register mad_fixed_t invsqrt2; header->flags |= MAD_FLAG_MS_STEREO; invsqrt2 = root_table[3 + -2]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (modes[sfbi] != ms_stereo) + if (modes[sfbi] != MS_STEREO) continue; for (i = 0; i < n; ++i) { register mad_fixed_t m, s; m = xr[0][l + i]; s = xr[1][l + i]; xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ } } } - return 0; + return MAD_ERROR_NONE; } /* * NAME: III_aliasreduce() * DESCRIPTION: perform frequency line alias reduction */ static void III_aliasreduce(mad_fixed_t xr[576], int lines) { mad_fixed_t const *bound; int i; bound = &xr[lines]; for (xr += 18; xr < bound; xr += 18) { for (i = 0; i < 8; ++i) { - register mad_fixed_t *aptr, *bptr, a, b; + register mad_fixed_t a, b; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; - aptr = &xr[-1 - i]; - bptr = &xr[ i]; - - a = *aptr; - b = *bptr; + a = xr[-1 - i]; + b = xr[ i]; # if defined(ASO_ZEROCHECK) if (a | b) { # endif MAD_F_ML0(hi, lo, a, cs[i]); MAD_F_MLA(hi, lo, -b, ca[i]); - *aptr = MAD_F_MLZ(hi, lo); + xr[-1 - i] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, b, cs[i]); MAD_F_MLA(hi, lo, a, ca[i]); - *bptr = MAD_F_MLZ(hi, lo); + xr[ i] = MAD_F_MLZ(hi, lo); # if defined(ASO_ZEROCHECK) } # endif } } } # if defined(ASO_IMDCT) void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int); # else /* * NAME: imdct36 @@ -2132,26 +2142,26 @@ void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) } # else for (i = 1; i < 18; i += 2) sample[i][sb] = -sample[i][sb]; # endif } /* * NAME: III_decode() * DESCRIPTION: decode frame main_data */ static -int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, - struct sideinfo *si, unsigned int nch) +enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, + struct sideinfo *si, unsigned int nch) { struct mad_header *header = &frame->header; unsigned int sfreqi, ngr, gr; { unsigned int sfreq; sfreq = header->samplerate; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreq *= 2; /* 48000 => 0, 44100 => 1, 32000 => 2, @@ -2160,72 +2170,72 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, ((sfreq >> 15) & 0x0001) - 8; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreqi += 3; } /* scalefactors, Huffman decoding, requantization */ ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; - unsigned char const *sfbwidth = 0; + unsigned char const *sfbwidth[2]; mad_fixed_t xr[2][576]; unsigned int ch; enum mad_error error; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; unsigned int part2_length; - sfbwidth = sfbwidth_table[sfreqi].l; + sfbwidth[ch] = sfbwidth_table[sfreqi].l; if (channel->block_type == 2) { - sfbwidth = (channel->flags & mixed_block_flag) ? + sfbwidth[ch] = (channel->flags & mixed_block_flag) ? sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; } if (header->flags & MAD_FLAG_LSF_EXT) { part2_length = III_scalefactors_lsf(ptr, channel, ch == 0 ? 0 : &si->gr[1].ch[1], header->mode_extension); } else { part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], gr == 0 ? 0 : si->scfsi[ch]); } - error = III_huffdecode(ptr, xr[ch], channel, sfbwidth, part2_length); + error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); if (error) return error; } /* joint stereo processing */ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { - error = III_stereo(xr, granule, header, sfbwidth); + error = III_stereo(xr, granule, header, sfbwidth[0]); if (error) return error; } /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ for (ch = 0; ch < nch; ++ch) { struct channel const *channel = &granule->ch[ch]; mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; unsigned int sb, l, i, sblimit; mad_fixed_t output[36]; if (channel->block_type == 2) { - III_reorder(xr[ch], channel, sfbwidth_table[sfreqi].s); + III_reorder(xr[ch], channel, sfbwidth[ch]); # if !defined(OPT_STRICT) /* * According to ISO/IEC 11172-3, "Alias reduction is not applied for * granules with block_type == 2 (short block)." However, other * sources suggest alias reduction should indeed be performed on the * lower two subbands of mixed blocks. Most other implementations do * this, so by default we will too. */ if (channel->flags & mixed_block_flag) III_aliasreduce(xr[ch], 36); # endif @@ -2291,25 +2301,25 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, /* remaining (zero) subbands */ for (sb = sblimit; sb < 32; ++sb) { III_overlap_z((*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } } - return 0; + return MAD_ERROR_NONE; } /* * NAME: layer->III() * DESCRIPTION: decode a single Layer III frame */ int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; unsigned int nch, priv_bitlen, next_md_begin = 0; unsigned int si_len, data_bitlen, md_len; unsigned int frame_space, frame_used, frame_free; |