ref: b9c91dbb598721be05a21034877deac322c5c80a
parent: c5c3fc3f9ffcd7d06e3a565ba31162193cb9d065
author: menno <menno>
date: Fri Aug 30 08:10:57 EDT 2002
Bugfix in filterbank and dequantisation
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.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: decoder.c,v 1.24 2002/08/27 18:16:12 menno Exp $
+** $Id: decoder.c,v 1.25 2002/08/30 12:10:57 menno Exp $
**/
#include <stdlib.h>
@@ -86,7 +86,11 @@
hDecoder->drc = drc_init(REAL_CONST(1.0), REAL_CONST(1.0));
/* build table for inverse quantization */
- build_tables(hDecoder->iq_table);
+#if IQ_TABLE_SIZE && POW_TABLE_SIZE
+ build_tables(hDecoder->iq_table, hDecoder->pow2_table);
+#elif !POW_TABLE_SIZE
+ build_tables(hDecoder->iq_table, NULL);
+#endif
return hDecoder;
}
@@ -445,6 +449,11 @@
real_t **lt_pred_stat = hDecoder->lt_pred_stat;
#endif
real_t *iq_table = hDecoder->iq_table;
+#if POW_TABLE_SIZE
+ real_t *pow2_table = hDecoder->pow2_table;
+#else
+ real_t *pow2_table = NULL;
+#endif
uint8_t *window_shape_prev = hDecoder->window_shape_prev;
real_t **time_out = hDecoder->time_out;
fb_info *fb = hDecoder->fb;
@@ -628,9 +637,18 @@
ics = &(syntax_elements[i]->ics2);
}
+#ifdef FIXED_POINT
/* inverse quantization and application of scalefactors */
iquant_and_apply_scalefactors(ics, spec_coef[ch], spec_data[ch],
iq_table, frame_len);
+#else
+ /* inverse quantization */
+ inverse_quantization(spec_coef[ch], spec_data[ch], iq_table,
+ frame_len);
+
+ /* apply scalefactors */
+ apply_scalefactors(ics, spec_coef[ch], pow2_table, frame_len);
+#endif
/* deinterleave short block grouping */
if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
--- a/libfaad/decoder.h
+++ b/libfaad/decoder.h
@@ -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: decoder.h,v 1.12 2002/08/27 10:24:55 menno Exp $
+** $Id: decoder.h,v 1.13 2002/08/30 12:10:57 menno Exp $
**/
#ifndef __DECODER_H__
@@ -104,6 +104,9 @@
real_t mnt_table[128];
real_t iq_table[IQ_TABLE_SIZE];
+#if POW_TABLE_SIZE
+ real_t pow2_table[POW_TABLE_SIZE];
+#endif
/* Configuration data */
faacDecConfiguration config;
--- a/libfaad/filtbank.c
+++ b/libfaad/filtbank.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: filtbank.c,v 1.17 2002/08/27 18:16:12 menno Exp $
+** $Id: filtbank.c,v 1.18 2002/08/30 12:10:57 menno Exp $
**/
#include "common.h"
@@ -211,7 +211,7 @@
case LONG_START_SEQUENCE:
imdct(fb, freq_in, transf_buf, 2*nlong);
- for (i = 0; i < 0; i++)
+ for (i = 0; i < nlong; i++)
time_out[i] = time_out[nlong+i] + MUL_R_C(transf_buf[i],window_long_prev[i]);
for (i = 0; i < nflat_ls; i++)
time_out[nlong+i] = transf_buf[nlong+i];
--- a/libfaad/specrec.c
+++ b/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.12 2002/08/27 10:24:57 menno Exp $
+** $Id: specrec.c,v 1.13 2002/08/30 12:10:57 menno Exp $
**/
/*
@@ -241,7 +241,7 @@
}
}
-void build_tables(real_t *iq_table)
+void build_tables(real_t *iq_table, real_t *pow2_table)
{
uint16_t i;
@@ -250,8 +250,18 @@
{
iq_table[i] = REAL_CONST(pow(i, 4.0/3.0));
}
+
+#ifndef FIXED_POINT
+ /* build pow(2, 0.25*x) table for scalefactors */
+ for(i = 0; i < POW_TABLE_SIZE; i++)
+ {
+ pow2_table[i] = (real_t)pow(2.0, 0.25 * (i-100));
+ }
+#endif
}
+#ifdef FIXED_POINT
+
static real_t newpow2_table[4] = {
COEF_CONST(1.0),
COEF_CONST(1.1892071), /* pow(2,.25) */
@@ -316,3 +326,93 @@
x_quant += nshort * ics->window_group_length[g];
}
}
+
+#else
+
+static INLINE real_t iquant(int16_t q, real_t *iq_table)
+{
+ if (q > 0)
+ {
+ if (q < IQ_TABLE_SIZE)
+ return iq_table[q];
+ else
+ return iq_table[q>>3] * 16;
+ } else if (q < 0) {
+ q = -q;
+ if (q < IQ_TABLE_SIZE)
+ return -iq_table[q];
+ else
+ return -iq_table[q>>3] * 16;
+ } else {
+ return 0;
+ }
+}
+
+void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table,
+ uint16_t frame_len)
+{
+ int8_t i;
+ int16_t *in_ptr = x_quant;
+ real_t *out_ptr = x_invquant;
+
+ 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);
+ }
+}
+
+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_CONST(exp(LN2 * 0.25 * (scale_factor - 100)));
+}
+
+void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
+ uint16_t frame_len)
+{
+ uint8_t g, sfb;
+ uint16_t top;
+ real_t *fp, scale;
+ uint8_t groups = 0;
+ uint16_t nshort = frame_len/8;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ uint16_t k = 0;
+
+ /* using this 128*groups doesn't hurt long blocks, because
+ long blocks only have 1 group, so that means 'groups' is
+ always 0 for long blocks
+ */
+ fp = x_invquant + (groups*nshort);
+
+ for (sfb = 0; sfb < ics->max_sfb; sfb++)
+ {
+ top = ics->sect_sfb_offset[g][sfb+1];
+
+ scale = get_scale_factor_gain(ics->scale_factors[g][sfb], pow2_table);
+
+ /* minimum size of a sf band is 4 and always a multiple of 4 */
+ for ( ; k < top; k+=4)
+ {
+ fp[0] *= scale;
+ fp[1] *= scale;
+ fp[2] *= scale;
+ fp[3] *= scale;
+ fp += 4;
+ }
+ }
+ groups += ics->window_group_length[g];
+ }
+}
+
+#endif
--- a/libfaad/specrec.h
+++ b/libfaad/specrec.h
@@ -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.h,v 1.6 2002/08/26 18:41:47 menno Exp $
+** $Id: specrec.h,v 1.7 2002/08/30 12:10:57 menno Exp $
**/
#ifndef __SPECREC_H__
@@ -29,16 +29,28 @@
#include "syntax.h"
/* !!!DON'T CHANGE IQ_TABLE_SIZE!!! */
-#define IQ_TABLE_SIZE 1026
+#define IQ_TABLE_SIZE 1026
+#ifdef FIXED_POINT
+#define POW_TABLE_SIZE 0
+#else
+#define POW_TABLE_SIZE 200
+#endif
uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index,
uint8_t object_type, uint16_t frame_len);
void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len);
-void build_tables(real_t *iq_table);
+void build_tables(real_t *iq_table, real_t *pow2_table);
+#ifdef FIXED_POINT
void iquant_and_apply_scalefactors(ic_stream *ics, real_t *x_invquant,
int16_t *x_quant, real_t *iq_table,
uint16_t frame_len);
+#else
+void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table,
+ uint16_t frame_len);
+void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
+ uint16_t frame_len);
+#endif
#ifdef __cplusplus
}