summaryrefslogtreecommitdiff
path: root/src/libfaad/pns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfaad/pns.c')
-rw-r--r--src/libfaad/pns.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/libfaad/pns.c b/src/libfaad/pns.c
index e7a0168e4..911b9cdb0 100644
--- a/src/libfaad/pns.c
+++ b/src/libfaad/pns.c
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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
@@ -16,7 +16,13 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: pns.c,v 1.3 2003/04/12 14:58:47 miguelfreitas Exp $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+**
+** $Id: pns.c,v 1.4 2003/12/30 02:00:10 miguelfreitas Exp $
**/
#include "common.h"
@@ -27,7 +33,7 @@
#ifdef FIXED_POINT
-#define DIV(A, B) (((int64_t)A << COEF_BITS)/B)
+#define DIV(A, B) (((int64_t)A << REAL_BITS)/B)
#define step(shift) \
if ((0x40000000l >> shift) + root <= value) \
@@ -39,6 +45,7 @@
}
/* fixed point square root approximation */
+/* !!!! ONLY WORKS FOR EVEN %REAL_BITS% !!!! */
real_t fp_sqrt(real_t value)
{
real_t root = 0;
@@ -51,7 +58,7 @@ real_t fp_sqrt(real_t value)
if (root < value)
++root;
- root <<= (COEF_BITS/2);
+ root <<= (REAL_BITS/2);
return root;
}
@@ -73,13 +80,14 @@ static real_t pow2_table[] =
value. A suitable random number generator can be realized using one
multiplication/accumulation per random value.
*/
-static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size)
+static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size,
+ uint8_t sub)
{
#ifndef FIXED_POINT
uint16_t i;
real_t energy = 0.0;
- real_t scale = 1.0/(real_t)size * ISQRT_MEAN_NRG;
+ real_t scale = (real_t)1.0/(real_t)size;
for (i = 0; i < size; i++)
{
@@ -88,7 +96,7 @@ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t
energy += tmp*tmp;
}
- scale = 1.0/(real_t)sqrt(energy);
+ scale = (real_t)1.0/(real_t)sqrt(energy);
scale *= (real_t)pow(2.0, 0.25 * scale_factor);
for (i = 0; i < size; i++)
{
@@ -101,36 +109,40 @@ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t
for (i = 0; i < size; i++)
{
- real_t tmp = ISQRT_MEAN_NRG * (int32_t)random_int();
- tmp = MUL_C_C(COEF_CONST(1)/size, tmp);
+ /* this can be replaced by a 16 bit random generator!!!! */
+ real_t tmp = (int32_t)random_int();
+ if (tmp < 0)
+ tmp = -(tmp & ((1<<(REAL_BITS-1))-1));
+ else
+ tmp = (tmp & ((1<<(REAL_BITS-1))-1));
- energy += MUL_C_C(tmp,tmp);
+ energy += MUL_R(tmp,tmp);
- /* convert COEF to REAL */
- spec[i] = (tmp >> -(REAL_BITS-COEF_BITS));
+ spec[i] = tmp;
}
energy = fp_sqrt(energy);
if (energy > 0)
{
- scale = DIV(COEF_CONST(1),energy);
-
- scale >>= -(REAL_BITS-COEF_BITS);
+ scale = DIV(REAL_CONST(1),energy);
exp = scale_factor / 4;
frac = scale_factor % 4;
+ /* IMDCT pre-scaling */
+ exp -= sub;
+
if (exp < 0)
scale >>= -exp;
else
scale <<= exp;
if (frac)
- scale = MUL_R_C(scale, pow2_table[frac + 3]);
+ scale = MUL_C(scale, pow2_table[frac + 3]);
for (i = 0; i < size; i++)
{
- spec[i] = MUL(spec[i], scale);
+ spec[i] = MUL_R(spec[i], scale);
}
}
#endif
@@ -138,7 +150,7 @@ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t
void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
real_t *spec_left, real_t *spec_right, uint16_t frame_len,
- uint8_t channel_pair)
+ uint8_t channel_pair, uint8_t object_type)
{
uint8_t g, sfb, b;
uint16_t size, offs;
@@ -146,6 +158,21 @@ void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
uint8_t group = 0;
uint16_t nshort = frame_len >> 3;
+ uint8_t sub = 0;
+
+#ifdef FIXED_POINT
+ /* IMDCT scaling */
+ if (object_type == LD)
+ {
+ sub = 9 /*9*/;
+ } else {
+ if (ics_left->window_sequence == EIGHT_SHORT_SEQUENCE)
+ sub = 7 /*7*/;
+ else
+ sub = 10 /*10*/;
+ }
+#endif
+
for (g = 0; g < ics_left->num_window_groups; g++)
{
/* Do perceptual noise substitution decoding */
@@ -173,7 +200,7 @@ void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
/* Generate random vector */
gen_rand_vector(&spec_left[(group*nshort)+offs],
- ics_left->scale_factors[g][sfb], size);
+ ics_left->scale_factors[g][sfb], size, sub);
}
/* From the spec:
@@ -217,7 +244,7 @@ void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
/* Generate random vector */
gen_rand_vector(&spec_right[(group*nshort)+offs],
- ics_right->scale_factors[g][sfb], size);
+ ics_right->scale_factors[g][sfb], size, sub);
}
}
}