diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-12-16 18:59:50 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-12-16 18:59:50 +0000 |
commit | 94ef6649dd5f4e95337af00dcede2337ea7cfb49 (patch) | |
tree | 07d679ce92b4e4517815abc42394480eebf44904 /src/libfaad/specrec.c | |
parent | 48f4c5809db11a6df4a5e7285d5e60a2ed924e2a (diff) | |
download | xine-lib-94ef6649dd5f4e95337af00dcede2337ea7cfb49.tar.gz xine-lib-94ef6649dd5f4e95337af00dcede2337ea7cfb49.tar.bz2 |
updated libfaad
CVS patchset: 3560
CVS date: 2002/12/16 18:59:50
Diffstat (limited to 'src/libfaad/specrec.c')
-rw-r--r-- | src/libfaad/specrec.c | 199 |
1 files changed, 121 insertions, 78 deletions
diff --git a/src/libfaad/specrec.c b/src/libfaad/specrec.c index 7d97e2a76..dbb4416d2 100644 --- a/src/libfaad/specrec.c +++ b/src/libfaad/specrec.c @@ -16,7 +16,7 @@ ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** -** $Id: specrec.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $ +** $Id: specrec.c,v 1.2 2002/12/16 19:01:14 miguelfreitas Exp $ **/ /* @@ -27,10 +27,13 @@ */ #include "common.h" +#include "structs.h" +#include <string.h> #include "specrec.h" #include "syntax.h" #include "data.h" +#include "iq_table.h" #define bit_set(A, B) ((A) & (1<<(B))) @@ -48,11 +51,12 @@ in section named section. This offset depends on window_sequence and scale_factor_grouping and is needed to decode the spectral_data(). */ -uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, - uint8_t object_type, uint16_t frame_len) +uint8_t window_grouping_info(faacDecHandle hDecoder, ic_stream *ics) { uint8_t i, g; + uint8_t sf_index = hDecoder->sf_index; + switch (ics->window_sequence) { case ONLY_LONG_SEQUENCE: case LONG_START_SEQUENCE: @@ -61,12 +65,15 @@ uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, ics->num_window_groups = 1; ics->window_group_length[ics->num_window_groups-1] = 1; #ifdef LD_DEC - if (object_type == LD) + if (hDecoder->object_type == LD) { - ics->num_swb = num_swb_512_window[fs_index]; + if (hDecoder->frameLength == 512) + ics->num_swb = num_swb_512_window[sf_index]; + else /* if (hDecoder->frameLength == 480) */ + ics->num_swb = num_swb_480_window[sf_index]; } else { #endif - ics->num_swb = num_swb_1024_window[fs_index]; + ics->num_swb = num_swb_1024_window[sf_index]; #ifdef LD_DEC } #endif @@ -74,24 +81,33 @@ uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, /* preparation of sect_sfb_offset for long blocks */ /* also copy the last value! */ #ifdef LD_DEC - if (object_type == LD) + if (hDecoder->object_type == LD) { - for (i = 0; i < ics->num_swb; i++) + if (hDecoder->frameLength == 512) { - ics->sect_sfb_offset[0][i] = swb_offset_512_window[fs_index][i]; - ics->swb_offset[i] = swb_offset_512_window[fs_index][i]; + for (i = 0; i < ics->num_swb; i++) + { + ics->sect_sfb_offset[0][i] = swb_offset_512_window[sf_index][i]; + ics->swb_offset[i] = swb_offset_512_window[sf_index][i]; + } + } else /* if (hDecoder->frameLength == 480) */ { + for (i = 0; i < ics->num_swb; i++) + { + ics->sect_sfb_offset[0][i] = swb_offset_480_window[sf_index][i]; + ics->swb_offset[i] = swb_offset_480_window[sf_index][i]; + } } - ics->sect_sfb_offset[0][ics->num_swb] = frame_len; - ics->swb_offset[ics->num_swb] = frame_len; + ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength; + ics->swb_offset[ics->num_swb] = hDecoder->frameLength; } else { #endif for (i = 0; i < ics->num_swb; i++) { - ics->sect_sfb_offset[0][i] = swb_offset_1024_window[fs_index][i]; - ics->swb_offset[i] = swb_offset_1024_window[fs_index][i]; + ics->sect_sfb_offset[0][i] = swb_offset_1024_window[sf_index][i]; + ics->swb_offset[i] = swb_offset_1024_window[sf_index][i]; } - ics->sect_sfb_offset[0][ics->num_swb] = frame_len; - ics->swb_offset[ics->num_swb] = frame_len; + ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength; + ics->swb_offset[ics->num_swb] = hDecoder->frameLength; #ifdef LD_DEC } #endif @@ -100,11 +116,11 @@ uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, ics->num_windows = 8; ics->num_window_groups = 1; ics->window_group_length[ics->num_window_groups-1] = 1; - ics->num_swb = num_swb_128_window[fs_index]; + ics->num_swb = num_swb_128_window[sf_index]; for (i = 0; i < ics->num_swb; i++) - ics->swb_offset[i] = swb_offset_128_window[fs_index][i]; - ics->swb_offset[ics->num_swb] = frame_len/8; + ics->swb_offset[i] = swb_offset_128_window[sf_index][i]; + ics->swb_offset[ics->num_swb] = hDecoder->frameLength/8; for (i = 0; i < ics->num_windows-1; i++) { if (bit_set(ics->scale_factor_grouping, 6-i) == 0) @@ -127,10 +143,10 @@ uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, { if (i+1 == ics->num_swb) { - width = (frame_len/8) - swb_offset_128_window[fs_index][i]; + width = (hDecoder->frameLength/8) - swb_offset_128_window[sf_index][i]; } else { - width = swb_offset_128_window[fs_index][i+1] - - swb_offset_128_window[fs_index][i]; + width = swb_offset_128_window[sf_index][i+1] - + swb_offset_128_window[sf_index][i]; } width *= ics->window_group_length[g]; ics->sect_sfb_offset[g][sect_sfb++] = offset; @@ -166,7 +182,6 @@ uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, */ void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len) { - int8_t i; uint8_t g, sfb, win; uint16_t width, bin; real_t *start_inptr, *start_win_ptr, *win_ptr; @@ -175,17 +190,7 @@ void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len) real_t *tmp_spec_ptr, *spec_ptr; tmp_spec_ptr = tmp_spec; - for (i = frame_len/16-1; i >= 0; --i) - { - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0; - } + memset(tmp_spec_ptr, 0, frame_len*sizeof(real_t)); spec_ptr = spec_data; tmp_spec_ptr = tmp_spec; @@ -212,10 +217,12 @@ void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len) for (bin = 0; bin < width; bin += 4) { - *tmp_spec_ptr++ = *spec_ptr++; - *tmp_spec_ptr++ = *spec_ptr++; - *tmp_spec_ptr++ = *spec_ptr++; - *tmp_spec_ptr++ = *spec_ptr++; + tmp_spec_ptr[0] = spec_ptr[0]; + tmp_spec_ptr[1] = spec_ptr[1]; + tmp_spec_ptr[2] = spec_ptr[2]; + tmp_spec_ptr[3] = spec_ptr[3]; + tmp_spec_ptr += 4; + spec_ptr += 4; } win_ptr += win_inc; @@ -228,57 +235,42 @@ void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len) spec_ptr = spec_data; tmp_spec_ptr = tmp_spec; - for (i = frame_len/16 - 1; i >= 0; --i) - { - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++; - } + memcpy(spec_ptr, tmp_spec_ptr, frame_len*sizeof(real_t)); } -void build_tables(real_t *iq_table, real_t *pow2_table) +#ifndef FIXED_POINT +void build_tables(real_t *pow2_table) { uint16_t i; - /* build pow(x, 4/3) table for inverse quantization */ - for(i = 0; i < IQ_TABLE_SIZE; i++) - { - iq_table[i] = (real_t)exp(log(i) * 4.0/3.0); - } - /* build pow(2, 0.25*x) table for scalefactors */ for(i = 0; i < POW_TABLE_SIZE; i++) { - pow2_table[i] = (real_t)exp(LN2 * 0.25 * (i-100)); + pow2_table[i] = REAL_CONST(pow(2.0, 0.25 * (i-100))); } } +#endif -static INLINE real_t iquant(int16_t q, real_t *iq_table) +static INLINE real_t iquant(int16_t q) { if (q > 0) { if (q < IQ_TABLE_SIZE) return iq_table[q]; else - return MUL(iq_table[q>>3], 16); + return iq_table[q>>3] * 16; } else if (q < 0) { q = -q; if (q < IQ_TABLE_SIZE) return -iq_table[q]; else - return -MUL(iq_table[q>>3], 16); + return -iq_table[q>>3] * 16; } else { - return 0.0f; + return 0; } } -void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table, - uint16_t frame_len) +void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len) { int8_t i; int16_t *in_ptr = x_quant; @@ -286,31 +278,53 @@ void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table for(i = frame_len/8-1; i >= 0; --i) { - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); - *out_ptr++ = iquant(*in_ptr++, iq_table); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); + *out_ptr++ = iquant(*in_ptr++); } } +#ifndef FIXED_POINT static INLINE real_t get_scale_factor_gain(uint16_t scale_factor, real_t *pow2_table) { if (scale_factor < POW_TABLE_SIZE) return pow2_table[scale_factor]; else - return (real_t)exp(LN2 * 0.25 * (scale_factor - 100)); + return REAL_CONST(pow(2.0, 0.25 * (scale_factor - 100))); } +#else +static real_t pow2_table[] = +{ + COEF_CONST(0.59460355750136), + COEF_CONST(0.70710678118655), + COEF_CONST(0.84089641525371), + COEF_CONST(1.0), + COEF_CONST(1.18920711500272), + COEF_CONST(1.41421356237310), + COEF_CONST(1.68179283050743) +}; +#endif +#ifdef FIXED_POINT +void apply_scalefactors(ic_stream *ics, real_t *x_invquant, uint16_t frame_len) +#else void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table, uint16_t frame_len) +#endif { uint8_t g, sfb; uint16_t top; - real_t *fp, scale; + real_t *fp; +#ifndef FIXED_POINT + real_t scale; +#else + int32_t exp, frac; +#endif uint8_t groups = 0; uint16_t nshort = frame_len/8; @@ -328,15 +342,44 @@ void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table, { top = ics->sect_sfb_offset[g][sfb+1]; +#ifndef FIXED_POINT scale = get_scale_factor_gain(ics->scale_factors[g][sfb], pow2_table); +#else + exp = (ics->scale_factors[g][sfb] - 100) / 4; + frac = (ics->scale_factors[g][sfb] - 100) % 4; +#endif /* minimum size of a sf band is 4 and always a multiple of 4 */ - for ( ; k < top; k+=4) + for ( ; k < top; k += 4) { - *fp = MUL(*fp, scale); fp++; - *fp = MUL(*fp, scale); fp++; - *fp = MUL(*fp, scale); fp++; - *fp = MUL(*fp, scale); fp++; +#ifndef FIXED_POINT + fp[0] = MUL(fp[0],scale); + fp[1] = MUL(fp[1],scale); + fp[2] = MUL(fp[2],scale); + fp[3] = MUL(fp[3],scale); +#else + if (exp < 0) + { + fp[0] >>= -exp; + fp[1] >>= -exp; + fp[2] >>= -exp; + fp[3] >>= -exp; + } else { + fp[0] <<= exp; + fp[1] <<= exp; + fp[2] <<= exp; + fp[3] <<= exp; + } + + if (frac) + { + fp[0] = MUL_R_C(fp[0],pow2_table[frac + 3]); + fp[1] = MUL_R_C(fp[1],pow2_table[frac + 3]); + fp[2] = MUL_R_C(fp[2],pow2_table[frac + 3]); + fp[3] = MUL_R_C(fp[3],pow2_table[frac + 3]); + } +#endif + fp += 4; } } groups += ics->window_group_length[g]; |