shithub: aacdec

Download patch

ref: 91082ce9a12c7bceaef1b806a8cffa3781699d59
parent: 34148793ec79f0d0c46c38d3648b573d9d48bcfb
author: menno <menno>
date: Tue Nov 4 16:43:30 EST 2003

fixed MAIN decoding

--- a/libfaad/cfft.c
+++ b/libfaad/cfft.c
@@ -1,19 +1,19 @@
 /*
 ** 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
 ** 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.
-**
+** 
 ** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: cfft.c,v 1.16 2003/11/02 20:24:03 menno Exp $
+** $Id: cfft.c,v 1.17 2003/11/04 21:43:30 menno Exp $
 **/
 
 /*
@@ -153,6 +153,161 @@
     }
 }
 
+#if 0
+typedef real_t simd_complex_t[4];
+
+/*
+  complex_add_sub(c1, c2, a1, a2);
+  complex_mult(a1, c1, w0);
+  complex_mult(a2, c2, w2);
+*/
+static INLINE void complex_func(simd_complex_t a1, simd_complex_t a2,
+                                const simd_complex_t z1, const simd_complex_t z2,
+                                const simd_complex_t w1, const simd_complex_t w2)
+{
+    __asm {
+        mov eax, a1
+        mov ebx, a2
+        movups xmm0, [eax]
+        movups xmm2, [ebx]
+        movups xmm4, [eax]
+        addps xmm0, xmm2   ; xmm0 = c1
+        subps xmm4, xmm2   ; xmm4 = c2
+
+
+        ; complex mult
+        mov ecx, w1
+        movups xmm1, [ecx]
+        movups xmm2, xmm0
+        movups xmm3, xmm1
+
+        mulps xmm0, xmm1
+
+        shufps xmm2, xmm2, 0xB1
+        shufps xmm0, xmm0, 0xD8
+
+        mulps xmm2, xmm3
+
+        movhlps xmm1, xmm0
+        shufps xmm2, xmm2, 0xD8
+
+        subps xmm0, xmm1
+        movhlps xmm3, xmm2
+        addps xmm2, xmm3
+
+        unpcklps xmm0, xmm2
+        movups [eax], xmm0
+
+        ; complex mult
+        mov ecx, w2
+        movups xmm1, [ecx]
+        movups xmm2, xmm4
+        movups xmm3, xmm1
+
+        mulps xmm4, xmm1
+
+        shufps xmm2, xmm2, 0xB1
+        shufps xmm4, xmm4, 0xD8
+
+        mulps xmm2, xmm3
+
+        movhlps xmm1, xmm4
+        shufps xmm2, xmm2, 0xD8
+
+        subps xmm4, xmm1
+        movhlps xmm3, xmm2
+        addps xmm2, xmm3
+
+        unpcklps xmm4, xmm2
+        movups [ebx], xmm4
+    }
+}
+
+/* complex a = z1*z2 */
+static INLINE void complex_mult(simd_complex_t a, const simd_complex_t z1, const simd_complex_t z2)
+{
+#if 0
+    a[0] = MUL_R_C(z1[0],z2[0]) - MUL_R_C(z1[1],z2[1]);
+    a[1] = MUL_R_C(z1[1],z2[0]) + MUL_R_C(z1[0],z2[1]);
+
+    a[2] = MUL_R_C(z1[2],z2[2]) - MUL_R_C(z1[3],z2[3]);
+    a[3] = MUL_R_C(z1[3],z2[2]) + MUL_R_C(z1[2],z2[3]);
+#else
+    __asm {
+        mov eax, z1
+        mov ecx, z2
+        mov edx, a
+
+        movups xmm0, [eax]
+        movups xmm1, [ecx]
+        movaps xmm2, xmm0
+        movaps xmm3, xmm1
+
+        mulps xmm0, xmm1
+
+        shufps xmm2, xmm2, 0xB1
+        shufps xmm0, xmm0, 0xD8
+
+        mulps xmm2, xmm3
+
+        movhlps xmm1, xmm0
+        shufps xmm2, xmm2, 0xD8
+
+        subps xmm0, xmm1
+        movhlps xmm3, xmm2
+        addps xmm2, xmm3
+
+        unpcklps xmm0, xmm2
+
+        movups [edx], xmm0
+    }
+#endif
+}
+
+/* complex a = z1+z2 */
+static void complex_add(complex_t a, const complex_t z1, const complex_t z2)
+{
+    RE(a) = RE(z1) + RE(z2);
+    IM(a) = IM(z1) + IM(z2);
+}
+
+/* complex a = z1-z2 */
+static void complex_sub(complex_t a, const complex_t z1, const complex_t z2)
+{
+    RE(a) = RE(z1) - RE(z2);
+    IM(a) = IM(z1) - IM(z2);
+}
+
+/* complex a1 = z1+z2; a2 = z1-z2 */
+static INLINE void complex_add_sub(simd_complex_t a1, simd_complex_t a2,
+                            const simd_complex_t z1, const simd_complex_t z2)
+{
+#if 0
+    a1[0] = z1[0] + z2[0];
+    a1[1] = z1[1] + z2[1];
+    a1[2] = z1[2] + z2[2];
+    a1[3] = z1[3] + z2[3];
+    a2[0] = z1[0] - z2[0];
+    a2[1] = z1[1] - z2[1];
+    a2[2] = z1[2] - z2[2];
+    a2[3] = z1[3] - z2[3];
+#else
+    __asm {
+        mov eax, DWORD PTR z1
+        mov ebx, DWORD PTR z2
+        mov ecx, DWORD PTR a1
+        mov edx, DWORD PTR a2
+        movups xmm1, [eax]
+        movups xmm2, [ebx]
+        movups xmm3, [eax]
+        addps xmm1, xmm2
+        subps xmm3, xmm2
+        movups [ecx], xmm1
+        movups [edx], xmm3
+    }
+#endif
+}
+
 static void passf4(const uint16_t ido, const uint16_t l1, const complex_t *cc,
                    complex_t *ch, const complex_t *wa1, const complex_t *wa2,
                    const complex_t *wa3, const int8_t isign)
@@ -197,6 +352,94 @@
 
             for (i = 0; i < ido; i++)
             {
+                simd_complex_t c1, c2, t1, t2;
+                simd_complex_t w0 = {1,0,0,0};
+                simd_complex_t w2;
+
+                w0[2] = wa1[i][0]*isign;
+                w0[3] = wa1[i][1]*isign;
+                w2[0] = wa2[i][0]*isign;
+                w2[1] = wa2[i][1]*isign;
+                w2[2] = wa3[i][0]*isign;
+                w2[3] = wa3[i][1]*isign;
+
+                t1[0] = RE(cc[ac+i]) + RE(cc[ac+i+2*ido]);
+                t1[1] = IM(cc[ac+i]) + IM(cc[ac+i+2*ido]);
+                t1[2] = RE(cc[ac+i]) - RE(cc[ac+i+2*ido]);
+                t1[3] = IM(cc[ac+i]) - IM(cc[ac+i+2*ido]);
+                t2[0] = RE(cc[ac+i+ido]) + RE(cc[ac+i+3*ido]);
+                t2[3] = RE(cc[ac+i+ido]) - RE(cc[ac+i+3*ido]);
+                t2[1] = IM(cc[ac+i+3*ido]) + IM(cc[ac+i+ido]);
+                t2[2] = IM(cc[ac+i+3*ido]) - IM(cc[ac+i+ido]);
+
+                t2[2] *= isign;
+                t2[3] *= isign;
+
+#if 0
+                complex_add_sub(c1, c2, t1, t2);
+                complex_mult(t1, c1, w0);
+                complex_mult(t2, c2, w2);
+#else
+                complex_func(t1, t2, c1, c2, w0, w2);
+#endif
+
+                RE(ch[ah+i]) = t1[0];
+                IM(ch[ah+i]) = t1[1];
+                RE(ch[ah+i+l1*ido]) = t1[2];
+                IM(ch[ah+i+l1*ido]) = t1[3];
+                RE(ch[ah+i+2*l1*ido]) = t2[0];
+                IM(ch[ah+i+2*l1*ido]) = t2[1];
+                RE(ch[ah+i+3*l1*ido]) = t2[2];
+                IM(ch[ah+i+3*l1*ido]) = t2[3];
+            }
+        }
+    }
+}
+#else
+static void passf4(const uint16_t ido, const uint16_t l1, const complex_t *cc,
+                   complex_t *ch, const complex_t *wa1, const complex_t *wa2,
+                   const complex_t *wa3, const int8_t isign)
+{
+    uint16_t i, k, ac, ah;
+
+    if (ido == 1)
+    {
+        for (k = 0; k < l1; k++)
+        {
+            complex_t t1, t2, t3, t4;
+
+            ac = 4*k;
+            ah = k;
+
+            RE(t2) = RE(cc[ac])   + RE(cc[ac+2]);
+            RE(t1) = RE(cc[ac])   - RE(cc[ac+2]);
+            IM(t2) = IM(cc[ac])   + IM(cc[ac+2]);
+            IM(t1) = IM(cc[ac])   - IM(cc[ac+2]);
+            RE(t3) = RE(cc[ac+1]) + RE(cc[ac+3]);
+            IM(t4) = RE(cc[ac+1]) - RE(cc[ac+3]);
+            IM(t3) = IM(cc[ac+3]) + IM(cc[ac+1]);
+            RE(t4) = IM(cc[ac+3]) - IM(cc[ac+1]);
+
+            RE(ch[ah])      = RE(t2) + RE(t3);
+            RE(ch[ah+2*l1]) = RE(t2) - RE(t3);
+
+            IM(ch[ah])      = IM(t2) + IM(t3);
+            IM(ch[ah+2*l1]) = IM(t2) - IM(t3);
+
+            RE(ch[ah+l1])   = RE(t1) + RE(t4)*isign;
+            RE(ch[ah+3*l1]) = RE(t1) - RE(t4)*isign;
+
+            IM(ch[ah+l1])   = IM(t1) + IM(t4)*isign;
+            IM(ch[ah+3*l1]) = IM(t1) - IM(t4)*isign;
+        }
+    } else {
+        for (k = 0; k < l1; k++)
+        {
+            ac = 4*k*ido;
+            ah = k*ido;
+
+            for (i = 0; i < ido; i++)
+            {
                 complex_t c2, c3, c4, t1, t2, t3, t4;
 
                 RE(t2) = RE(cc[ac+i]) + RE(cc[ac+i+2*ido]);
@@ -230,6 +473,7 @@
         }
     }
 }
+#endif
 
 static void passf5(const uint16_t ido, const uint16_t l1, const complex_t *cc,
                    complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3,
--- a/libfaad/common.c
+++ b/libfaad/common.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: common.c,v 1.10 2003/11/02 20:24:03 menno Exp $
+** $Id: common.c,v 1.11 2003/11/04 21:43:30 menno Exp $
 **/
 
 /* just some common functions that could be used anywhere */
@@ -62,6 +62,20 @@
 
     if (sr_index < 12)
         return sample_rates[sr_index];
+
+    return 0;
+}
+
+uint8_t max_pred_sfb(uint8_t sr_index)
+{
+    static const uint8_t pred_sfb_max[] =
+    {
+        33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34
+    };
+
+
+    if (sr_index < 12)
+        return pred_sfb_max[sr_index];
 
     return 0;
 }
--- a/libfaad/common.h
+++ b/libfaad/common.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: common.h,v 1.35 2003/11/02 20:24:03 menno Exp $
+** $Id: common.h,v 1.36 2003/11/04 21:43:30 menno Exp $
 **/
 
 #ifndef __COMMON_H__
@@ -97,11 +97,15 @@
 #define SBR_DEC
 //#define SBR_LOW_POWER
 
+/* FIXED POINT: No MAIN decoding, forced SBR Low Power decoder */
 #ifdef FIXED_POINT
-#ifndef SBR_LOW_POWER
-#define SBR_LOW_POWER
-#endif
-#endif
+# ifdef MAIN_DEC
+#  undef MAIN_DEC
+# endif
+# ifndef SBR_LOW_POWER
+#  define SBR_LOW_POWER
+# endif
+#endif // FIXED_POINT
 
 #ifdef FIXED_POINT
 #define SBR_DIV(A, B) (((int64_t)A << REAL_BITS)/B)
@@ -308,6 +312,7 @@
 int32_t int_log2(int32_t val);
 uint32_t random_int(void);
 uint8_t get_sr_index(uint32_t samplerate);
+uint8_t max_pred_sfb(uint8_t sr_index);
 uint32_t get_sample_rate(uint8_t sr_index);
 int8_t can_decode_ot(uint8_t object_type);
 
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: decoder.c,v 1.78 2003/11/02 20:24:03 menno Exp $
+** $Id: decoder.c,v 1.79 2003/11/04 21:43:30 menno Exp $
 **/
 
 #include "common.h"
@@ -711,7 +711,6 @@
                             faacDecFrameInfo *hInfo,
                             uint8_t *buffer, uint32_t buffer_size)
 {
-    int32_t i;
     adts_header adts;
     uint8_t channels = 0, ch_ele = 0;
     uint8_t output_channels = 0;
@@ -730,9 +729,6 @@
 #ifdef MAIN_DEC
     pred_state **pred_stat;
 #endif
-#ifdef LTP_DEC
-    real_t **lt_pred_stat;
-#endif
     real_t **time_out;
 #ifdef SBR_DEC
     real_t **time_out2;
@@ -758,9 +754,6 @@
 #ifdef MAIN_DEC
     pred_stat = hDecoder->pred_stat;
 #endif
-#ifdef LTP_DEC
-    lt_pred_stat = hDecoder->lt_pred_stat;
-#endif
     window_shape_prev = hDecoder->window_shape_prev;
     time_out = hDecoder->time_out;
 #ifdef SBR_DEC
@@ -932,7 +925,7 @@
 #ifdef SBR_DEC
     if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
     {
-        uint8_t ch = 0;
+        uint8_t i, ch = 0;
         for (i = 0; i < ch_ele; i++)
         {
             /* following case can happen when forceUpSampling == 1 */
--- a/libfaad/ic_predict.c
+++ b/libfaad/ic_predict.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: ic_predict.c,v 1.16 2003/11/02 20:24:04 menno Exp $
+** $Id: ic_predict.c,v 1.17 2003/11/04 21:43:30 menno Exp $
 **/
 
 #include "common.h"
@@ -34,9 +34,9 @@
 #include "ic_predict.h"
 #include "pns.h"
 
+
 static void flt_round(real_t *pf)
 {
-    /* more stable version for clever compilers like gcc 3.x */
     int32_t flg;
     uint32_t tmp, tmp1, tmp2;
 
@@ -44,7 +44,6 @@
     flg = tmp & (uint32_t)0x00008000;
     tmp &= (uint32_t)0xffff0000;
     tmp1 = tmp;
-
     /* round 1/2 lsb toward infinity */
     if (flg)
     {
@@ -53,60 +52,99 @@
         tmp2 = tmp;                             /* add 1 lsb and elided one */
         tmp &= (uint32_t)0xff800000;       /* extract exponent and sign */
         
-        *pf = *(real_t*)&tmp1+*(real_t*)&tmp2-*(real_t*)&tmp;/* subtract elided one */
+        *pf = *(real_t*)&tmp1 + *(real_t*)&tmp2 - *(real_t*)&tmp;
     } else {
         *pf = *(real_t*)&tmp;
     }
 }
 
+static int16_t quant_pred(real_t x)
+{
+    int16_t q;
+    uint32_t *tmp = (uint32_t*)&x;
+
+    q = (int16_t)(*tmp>>16);
+
+    return q;
+}
+
+static real_t inv_quant_pred(int16_t q)
+{
+    real_t x;
+    uint32_t *tmp = (uint32_t*)&x;
+    *tmp = ((uint32_t)q)<<16;
+
+    return x;
+}
+
 static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred)
 {
+    uint32_t tmp;
+    int16_t i, j;
     real_t dr1, predictedvalue;
     real_t e0, e1;
     real_t k1, k2;
 
-    real_t *r;
-    real_t *KOR;
-    real_t *VAR;
+    real_t r[2];
+    real_t COR[2];
+    real_t VAR[2];
 
-    r   = state->r;   /* delay elements */
-    KOR = state->KOR; /* correlations */
-    VAR = state->VAR; /* variances */
+    r[0] = inv_quant_pred(state->r[0]);
+    r[1] = inv_quant_pred(state->r[1]);
+    COR[0] = inv_quant_pred(state->COR[0]);
+    COR[1] = inv_quant_pred(state->COR[1]);
+    VAR[0] = inv_quant_pred(state->VAR[0]);
+    VAR[1] = inv_quant_pred(state->VAR[1]);
 
-    if (VAR[0] <= 1)
-        k1 = 0;
-    else
-        k1 = KOR[0]/VAR[0]*B;
 
+    tmp = state->VAR[0];
+    j = (tmp >> 7);
+    i = tmp & 0x7f;
+    if (j >= 128)
+    {
+        j -= 128;
+        k1 = COR[0] * exp_table[j] * mnt_table[i];
+    } else {
+        k1 = REAL_CONST(0);
+    }
+
     if (pred)
     {
-        /* only needed for the actual predicted value, k1 is always needed */
-        if (VAR[1] <= 1)
-            k2 = 0;
-        else
-            k2 = KOR[1]/VAR[1]*B;
+        tmp = state->VAR[1];
+        j = (tmp >> 7);
+        i = tmp & 0x7f;
+        if (j >= 128)
+        {
+            j -= 128;
+            k2 = COR[1] * exp_table[j] * mnt_table[i];
+        } else {
+            k2 = REAL_CONST(0);
+        }
 
-        predictedvalue = MUL(k1, r[0]) + MUL(k2, r[1]);
+        predictedvalue  = k1*r[0] + k2*r[1];
         flt_round(&predictedvalue);
-
         *output = input + predictedvalue;
-    } else {
-        *output = input;
     }
 
     /* calculate new state data */
     e0 = *output;
-    e1 = e0 - MUL(k1, r[0]);
+    e1 = e0 - k1*r[0];
+    dr1 = k1*e0;
 
-    dr1 = MUL(k1, e0);
+    VAR[0] = ALPHA*VAR[0] + 0.5f * (r[0]*r[0] + e0*e0);
+    COR[0] = ALPHA*COR[0] + r[0]*e0;
+    VAR[1] = ALPHA*VAR[1] + 0.5f * (r[1]*r[1] + e1*e1);
+    COR[1] = ALPHA*COR[1] + r[1]*e1;
 
-    VAR[0] = MUL(ALPHA, VAR[0]) + MUL(REAL_CONST(0.5), (MUL(r[0], r[0]) + MUL(e0, e0)));
-    KOR[0] = MUL(ALPHA, KOR[0]) + MUL(r[0], e0);
-    VAR[1] = MUL(ALPHA, VAR[1]) + MUL(REAL_CONST(0.5), (MUL(r[1], r[1]) + MUL(e1, e1)));
-    KOR[1] = MUL(ALPHA, KOR[1]) + MUL(r[1], e1);
+    r[1] = A * (r[0]-dr1);
+    r[0] = A * e0;
 
-    r[1] = MUL(A, (r[0]-dr1));
-    r[0] = MUL(A, e0);
+    state->r[0] = quant_pred(r[0]);
+    state->r[1] = quant_pred(r[1]);
+    state->COR[0] = quant_pred(COR[0]);
+    state->COR[1] = quant_pred(COR[1]);
+    state->VAR[0] = quant_pred(VAR[0]);
+    state->VAR[1] = quant_pred(VAR[1]);
 }
 
 static void reset_pred_state(pred_state *state)
@@ -113,10 +151,10 @@
 {
     state->r[0]   = 0;
     state->r[1]   = 0;
-    state->KOR[0] = 0;
-    state->KOR[1] = 0;
-    state->VAR[0] = REAL_CONST(1.0);
-    state->VAR[1] = REAL_CONST(1.0);
+    state->COR[0] = 0;
+    state->COR[1] = 0;
+    state->VAR[0] = 0x3F80;
+    state->VAR[1] = 0x3F80;
 }
 
 void pns_reset_pred_state(ic_stream *ics, pred_state *state)
@@ -157,7 +195,7 @@
 
 /* intra channel prediction */
 void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
-                   uint16_t frame_len)
+                   uint16_t frame_len, uint8_t sf_index)
 {
     uint8_t sfb;
     uint16_t bin;
@@ -166,7 +204,7 @@
     {
         reset_all_predictors(state, frame_len);
     } else {
-        for (sfb = 0; sfb < ics->pred.limit; sfb++)
+        for (sfb = 0; sfb < max_pred_sfb(sf_index); sfb++)
         {
             uint16_t low  = ics->swb_offset[sfb];
             uint16_t high = ics->swb_offset[sfb+1];
@@ -174,8 +212,7 @@
             for (bin = low; bin < high; bin++)
             {
                 ic_predict(&state[bin], spec[bin], &spec[bin],
-                    (ics->predictor_data_present &&
-                    ics->pred.prediction_used[sfb]));
+                    (ics->predictor_data_present && ics->pred.prediction_used[sfb]));
             }
         }
 
--- a/libfaad/ic_predict.h
+++ b/libfaad/ic_predict.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: ic_predict.h,v 1.11 2003/11/02 20:24:04 menno Exp $
+** $Id: ic_predict.h,v 1.12 2003/11/04 21:43:30 menno Exp $
 **/
 
 #ifdef MAIN_DEC
@@ -39,11 +39,216 @@
 #define B          REAL_CONST(0.953125)
 
 
+/* used to save the prediction state */
+typedef struct {
+    real_t r[2];
+    real_t COR[2];
+    real_t VAR[2];
+} tmp_pred_state;
+
+
 void pns_reset_pred_state(ic_stream *ics, pred_state *state);
 void reset_all_predictors(pred_state *state, uint16_t frame_len);
 void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
-                   uint16_t frame_len);
+                   uint16_t frame_len, uint8_t sf_index);
 
+static const real_t mnt_table[128] = {
+    COEF_CONST(0.9531250000), COEF_CONST(0.9453125000),
+    COEF_CONST(0.9375000000), COEF_CONST(0.9296875000),
+    COEF_CONST(0.9257812500), COEF_CONST(0.9179687500),
+    COEF_CONST(0.9101562500), COEF_CONST(0.9023437500),
+    COEF_CONST(0.8984375000), COEF_CONST(0.8906250000),
+    COEF_CONST(0.8828125000), COEF_CONST(0.8789062500),
+    COEF_CONST(0.8710937500), COEF_CONST(0.8671875000),
+    COEF_CONST(0.8593750000), COEF_CONST(0.8515625000),
+    COEF_CONST(0.8476562500), COEF_CONST(0.8398437500),
+    COEF_CONST(0.8359375000), COEF_CONST(0.8281250000),
+    COEF_CONST(0.8242187500), COEF_CONST(0.8203125000),
+    COEF_CONST(0.8125000000), COEF_CONST(0.8085937500),
+    COEF_CONST(0.8007812500), COEF_CONST(0.7968750000),
+    COEF_CONST(0.7929687500), COEF_CONST(0.7851562500),
+    COEF_CONST(0.7812500000), COEF_CONST(0.7773437500),
+    COEF_CONST(0.7734375000), COEF_CONST(0.7656250000),
+    COEF_CONST(0.7617187500), COEF_CONST(0.7578125000),
+    COEF_CONST(0.7539062500), COEF_CONST(0.7500000000),
+    COEF_CONST(0.7421875000), COEF_CONST(0.7382812500),
+    COEF_CONST(0.7343750000), COEF_CONST(0.7304687500),
+    COEF_CONST(0.7265625000), COEF_CONST(0.7226562500),
+    COEF_CONST(0.7187500000), COEF_CONST(0.7148437500),
+    COEF_CONST(0.7109375000), COEF_CONST(0.7070312500),
+    COEF_CONST(0.6992187500), COEF_CONST(0.6953125000),
+    COEF_CONST(0.6914062500), COEF_CONST(0.6875000000),
+    COEF_CONST(0.6835937500), COEF_CONST(0.6796875000),
+    COEF_CONST(0.6796875000), COEF_CONST(0.6757812500),
+    COEF_CONST(0.6718750000), COEF_CONST(0.6679687500),
+    COEF_CONST(0.6640625000), COEF_CONST(0.6601562500),
+    COEF_CONST(0.6562500000), COEF_CONST(0.6523437500),
+    COEF_CONST(0.6484375000), COEF_CONST(0.6445312500),
+    COEF_CONST(0.6406250000), COEF_CONST(0.6406250000),
+    COEF_CONST(0.6367187500), COEF_CONST(0.6328125000),
+    COEF_CONST(0.6289062500), COEF_CONST(0.6250000000),
+    COEF_CONST(0.6210937500), COEF_CONST(0.6210937500),
+    COEF_CONST(0.6171875000), COEF_CONST(0.6132812500),
+    COEF_CONST(0.6093750000), COEF_CONST(0.6054687500),
+    COEF_CONST(0.6054687500), COEF_CONST(0.6015625000),
+    COEF_CONST(0.5976562500), COEF_CONST(0.5937500000),
+    COEF_CONST(0.5937500000), COEF_CONST(0.5898437500),
+    COEF_CONST(0.5859375000), COEF_CONST(0.5820312500),
+    COEF_CONST(0.5820312500), COEF_CONST(0.5781250000),
+    COEF_CONST(0.5742187500), COEF_CONST(0.5742187500),
+    COEF_CONST(0.5703125000), COEF_CONST(0.5664062500),
+    COEF_CONST(0.5664062500), COEF_CONST(0.5625000000),
+    COEF_CONST(0.5585937500), COEF_CONST(0.5585937500),
+    COEF_CONST(0.5546875000), COEF_CONST(0.5507812500),
+    COEF_CONST(0.5507812500), COEF_CONST(0.5468750000),
+    COEF_CONST(0.5429687500), COEF_CONST(0.5429687500),
+    COEF_CONST(0.5390625000), COEF_CONST(0.5390625000),
+    COEF_CONST(0.5351562500), COEF_CONST(0.5312500000),
+    COEF_CONST(0.5312500000), COEF_CONST(0.5273437500),
+    COEF_CONST(0.5273437500), COEF_CONST(0.5234375000),
+    COEF_CONST(0.5195312500), COEF_CONST(0.5195312500),
+    COEF_CONST(0.5156250000), COEF_CONST(0.5156250000),
+    COEF_CONST(0.5117187500), COEF_CONST(0.5117187500),
+    COEF_CONST(0.5078125000), COEF_CONST(0.5078125000),
+    COEF_CONST(0.5039062500), COEF_CONST(0.5039062500),
+    COEF_CONST(0.5000000000), COEF_CONST(0.4980468750),
+    COEF_CONST(0.4960937500), COEF_CONST(0.4941406250),
+    COEF_CONST(0.4921875000), COEF_CONST(0.4902343750),
+    COEF_CONST(0.4882812500), COEF_CONST(0.4863281250),
+    COEF_CONST(0.4843750000), COEF_CONST(0.4824218750),
+    COEF_CONST(0.4804687500), COEF_CONST(0.4785156250)
+};
+
+static const real_t exp_table[128] = {
+    COEF_CONST(0.50000000000000000000000000000000000000000000000000),
+    COEF_CONST(0.25000000000000000000000000000000000000000000000000),
+    COEF_CONST(0.12500000000000000000000000000000000000000000000000),
+    COEF_CONST(0.06250000000000000000000000000000000000000000000000),
+    COEF_CONST(0.03125000000000000000000000000000000000000000000000),
+    COEF_CONST(0.01562500000000000000000000000000000000000000000000),
+    COEF_CONST(0.00781250000000000000000000000000000000000000000000),
+    COEF_CONST(0.00390625000000000000000000000000000000000000000000),
+    COEF_CONST(0.00195312500000000000000000000000000000000000000000),
+    COEF_CONST(0.00097656250000000000000000000000000000000000000000),
+    COEF_CONST(0.00048828125000000000000000000000000000000000000000),
+    COEF_CONST(0.00024414062500000000000000000000000000000000000000),
+    COEF_CONST(0.00012207031250000000000000000000000000000000000000),
+    COEF_CONST(0.00006103515625000000000000000000000000000000000000),
+    COEF_CONST(0.00003051757812500000000000000000000000000000000000),
+    COEF_CONST(0.00001525878906250000000000000000000000000000000000),
+    COEF_CONST(0.00000762939453125000000000000000000000000000000000),
+    COEF_CONST(0.00000381469726562500000000000000000000000000000000),
+    COEF_CONST(0.00000190734863281250000000000000000000000000000000),
+    COEF_CONST(0.00000095367431640625000000000000000000000000000000),
+    COEF_CONST(0.00000047683715820312500000000000000000000000000000),
+    COEF_CONST(0.00000023841857910156250000000000000000000000000000),
+    COEF_CONST(0.00000011920928955078125000000000000000000000000000),
+    COEF_CONST(0.00000005960464477539062500000000000000000000000000),
+    COEF_CONST(0.00000002980232238769531300000000000000000000000000),
+    COEF_CONST(0.00000001490116119384765600000000000000000000000000),
+    COEF_CONST(0.00000000745058059692382810000000000000000000000000),
+    COEF_CONST(0.00000000372529029846191410000000000000000000000000),
+    COEF_CONST(0.00000000186264514923095700000000000000000000000000),
+    COEF_CONST(0.00000000093132257461547852000000000000000000000000),
+    COEF_CONST(0.00000000046566128730773926000000000000000000000000),
+    COEF_CONST(0.00000000023283064365386963000000000000000000000000),
+    COEF_CONST(0.00000000011641532182693481000000000000000000000000),
+    COEF_CONST(0.00000000005820766091346740700000000000000000000000),
+    COEF_CONST(0.00000000002910383045673370400000000000000000000000),
+    COEF_CONST(0.00000000001455191522836685200000000000000000000000),
+    COEF_CONST(0.00000000000727595761418342590000000000000000000000),
+    COEF_CONST(0.00000000000363797880709171300000000000000000000000),
+    COEF_CONST(0.00000000000181898940354585650000000000000000000000),
+    COEF_CONST(0.00000000000090949470177292824000000000000000000000),
+    COEF_CONST(0.00000000000045474735088646412000000000000000000000),
+    COEF_CONST(0.00000000000022737367544323206000000000000000000000),
+    COEF_CONST(0.00000000000011368683772161603000000000000000000000),
+    COEF_CONST(0.00000000000005684341886080801500000000000000000000),
+    COEF_CONST(0.00000000000002842170943040400700000000000000000000),
+    COEF_CONST(0.00000000000001421085471520200400000000000000000000),
+    COEF_CONST(0.00000000000000710542735760100190000000000000000000),
+    COEF_CONST(0.00000000000000355271367880050090000000000000000000),
+    COEF_CONST(0.00000000000000177635683940025050000000000000000000),
+    COEF_CONST(0.00000000000000088817841970012523000000000000000000),
+    COEF_CONST(0.00000000000000044408920985006262000000000000000000),
+    COEF_CONST(0.00000000000000022204460492503131000000000000000000),
+    COEF_CONST(0.00000000000000011102230246251565000000000000000000),
+    COEF_CONST(0.00000000000000005551115123125782700000000000000000),
+    COEF_CONST(0.00000000000000002775557561562891400000000000000000),
+    COEF_CONST(0.00000000000000001387778780781445700000000000000000),
+    COEF_CONST(0.00000000000000000693889390390722840000000000000000),
+    COEF_CONST(0.00000000000000000346944695195361420000000000000000),
+    COEF_CONST(0.00000000000000000173472347597680710000000000000000),
+    COEF_CONST(0.00000000000000000086736173798840355000000000000000),
+    COEF_CONST(0.00000000000000000043368086899420177000000000000000),
+    COEF_CONST(0.00000000000000000021684043449710089000000000000000),
+    COEF_CONST(0.00000000000000000010842021724855044000000000000000),
+    COEF_CONST(0.00000000000000000005421010862427522200000000000000),
+    COEF_CONST(0.00000000000000000002710505431213761100000000000000),
+    COEF_CONST(0.00000000000000000001355252715606880500000000000000),
+    COEF_CONST(0.00000000000000000000677626357803440270000000000000),
+    COEF_CONST(0.00000000000000000000338813178901720140000000000000),
+    COEF_CONST(0.00000000000000000000169406589450860070000000000000),
+    COEF_CONST(0.00000000000000000000084703294725430034000000000000),
+    COEF_CONST(0.00000000000000000000042351647362715017000000000000),
+    COEF_CONST(0.00000000000000000000021175823681357508000000000000),
+    COEF_CONST(0.00000000000000000000010587911840678754000000000000),
+    COEF_CONST(0.00000000000000000000005293955920339377100000000000),
+    COEF_CONST(0.00000000000000000000002646977960169688600000000000),
+    COEF_CONST(0.00000000000000000000001323488980084844300000000000),
+    COEF_CONST(0.00000000000000000000000661744490042422140000000000),
+    COEF_CONST(0.00000000000000000000000330872245021211070000000000),
+    COEF_CONST(0.00000000000000000000000165436122510605530000000000),
+    COEF_CONST(0.00000000000000000000000082718061255302767000000000),
+    COEF_CONST(0.00000000000000000000000041359030627651384000000000),
+    COEF_CONST(0.00000000000000000000000020679515313825692000000000),
+    COEF_CONST(0.00000000000000000000000010339757656912846000000000),
+    COEF_CONST(0.00000000000000000000000005169878828456423000000000),
+    COEF_CONST(0.00000000000000000000000002584939414228211500000000),
+    COEF_CONST(0.00000000000000000000000001292469707114105700000000),
+    COEF_CONST(0.00000000000000000000000000646234853557052870000000),
+    COEF_CONST(0.00000000000000000000000000323117426778526440000000),
+    COEF_CONST(0.00000000000000000000000000161558713389263220000000),
+    COEF_CONST(0.00000000000000000000000000080779356694631609000000),
+    COEF_CONST(0.00000000000000000000000000040389678347315804000000),
+    COEF_CONST(0.00000000000000000000000000020194839173657902000000),
+    COEF_CONST(0.00000000000000000000000000010097419586828951000000),
+    COEF_CONST(0.00000000000000000000000000005048709793414475600000),
+    COEF_CONST(0.00000000000000000000000000002524354896707237800000),
+    COEF_CONST(0.00000000000000000000000000001262177448353618900000),
+    COEF_CONST(0.00000000000000000000000000000631088724176809440000),
+    COEF_CONST(0.00000000000000000000000000000315544362088404720000),
+    COEF_CONST(0.00000000000000000000000000000157772181044202360000),
+    COEF_CONST(0.00000000000000000000000000000078886090522101181000),
+    COEF_CONST(0.00000000000000000000000000000039443045261050590000),
+    COEF_CONST(0.00000000000000000000000000000019721522630525295000),
+    COEF_CONST(0.00000000000000000000000000000009860761315262647600),
+    COEF_CONST(0.00000000000000000000000000000004930380657631323800),
+    COEF_CONST(0.00000000000000000000000000000002465190328815661900),
+    COEF_CONST(0.00000000000000000000000000000001232595164407830900),
+    COEF_CONST(0.00000000000000000000000000000000616297582203915470),
+    COEF_CONST(0.00000000000000000000000000000000308148791101957740),
+    COEF_CONST(0.00000000000000000000000000000000154074395550978870),
+    COEF_CONST(0.00000000000000000000000000000000077037197775489434),
+    COEF_CONST(0.00000000000000000000000000000000038518598887744717),
+    COEF_CONST(0.00000000000000000000000000000000019259299443872359),
+    COEF_CONST(0.00000000000000000000000000000000009629649721936179),
+    COEF_CONST(0.00000000000000000000000000000000004814824860968090),
+    COEF_CONST(0.00000000000000000000000000000000002407412430484045),
+    COEF_CONST(0.00000000000000000000000000000000001203706215242022),
+    COEF_CONST(0.00000000000000000000000000000000000601853107621011),
+    COEF_CONST(0.00000000000000000000000000000000000300926553810506),
+    COEF_CONST(0.00000000000000000000000000000000000150463276905253),
+    COEF_CONST(0.00000000000000000000000000000000000075231638452626),
+    COEF_CONST(0.00000000000000000000000000000000000037615819226313),
+    COEF_CONST(0.00000000000000000000000000000000000018807909613157),
+    COEF_CONST(0.00000000000000000000000000000000000009403954806578),
+    COEF_CONST(0.00000000000000000000000000000000000004701977403289),
+    COEF_CONST(0.00000000000000000000000000000000000002350988701645),
+    COEF_CONST(0.00000000000000000000000000000000000001175494350822),
+    COEF_CONST(0.00000000000000000000000000000000000000587747175411),
+    COEF_CONST(0.0)
+};
 
 #ifdef __cplusplus
 }
--- a/libfaad/lt_predict.c
+++ b/libfaad/lt_predict.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: lt_predict.c,v 1.15 2003/11/02 20:24:04 menno Exp $
+** $Id: lt_predict.c,v 1.16 2003/11/04 21:43:30 menno Exp $
 **/
 
 
@@ -59,25 +59,25 @@
 
 static real_t codebook[8] =
 {
-    COEF_CONST(0.570829),
-    COEF_CONST(0.696616),
-    COEF_CONST(0.813004),
-    COEF_CONST(0.911304),
-    COEF_CONST(0.984900),
-    COEF_CONST(1.067894),
-    COEF_CONST(1.194601),
-    COEF_CONST(1.369533)
+    REAL_CONST(0.570829),
+    REAL_CONST(0.696616),
+    REAL_CONST(0.813004),
+    REAL_CONST(0.911304),
+    REAL_CONST(0.984900),
+    REAL_CONST(1.067894),
+    REAL_CONST(1.194601),
+    REAL_CONST(1.369533)
 };
 
 void lt_prediction(ic_stream *ics, ltp_info *ltp, real_t *spec,
-                   real_t *lt_pred_stat, fb_info *fb, uint8_t win_shape,
+                   int16_t *lt_pred_stat, fb_info *fb, uint8_t win_shape,
                    uint8_t win_shape_prev, uint8_t sr_index,
                    uint8_t object_type, uint16_t frame_len)
 {
     uint8_t sfb;
     uint16_t bin, i, num_samples;
-    real_t *x_est;
-    real_t *X_est;
+    real_t x_est[2048];
+    real_t X_est[2048];
 
     if (ics->window_sequence != EIGHT_SHORT_SEQUENCE)
     {
@@ -85,15 +85,20 @@
         {
             num_samples = frame_len << 1;
 
-            x_est = (real_t*)malloc(num_samples*sizeof(real_t));
-            X_est = (real_t*)malloc(num_samples*sizeof(real_t));
-
             for(i = 0; i < num_samples; i++)
             {
                 /* The extra lookback M (N/2 for LD, 0 for LTP) is handled
                    in the buffer updating */
+
+#if 0
                 x_est[i] = MUL_R_C(lt_pred_stat[num_samples + i - ltp->lag],
                     codebook[ltp->coef]);
+#else
+                /* lt_pred_stat is a 16 bit int, multiplied with the fixed point real
+                   this gives a real for x_est
+                */
+                x_est[i] = lt_pred_stat[num_samples + i - ltp->lag] * codebook[ltp->coef];
+#endif
             }
 
             filter_bank_ltp(fb, ics->window_sequence, win_shape, win_shape_prev,
@@ -115,14 +120,34 @@
                     }
                 }
             }
-
-            free(x_est);
-            free(X_est);
         }
     }
 }
 
-void lt_update_state(real_t *lt_pred_stat, real_t *time, real_t *overlap,
+static int16_t real_to_int16(real_t sig_in)
+{
+    int16_t sig_out = 0;
+
+    if (sig_in > REAL_CONST(32767))
+        sig_out = 32767;
+    else if (sig_in < REAL_CONST(-32768))
+        sig_out = -32768;
+#ifndef FIXED_POINT
+    else if (sig_in > 0.0)
+        sig_out = (int16_t)(sig_in + 0.5);
+    else if (sig_in <= 0.0)
+        sig_out = (int16_t)(sig_in - 0.5);
+#else
+    else if (sig_in > 0)
+        sig_out = (int16_t)((sig_in + (1 << (REAL_BITS-1))) >> REAL_BITS);
+    else if (sig_in <= 0)
+        sig_out = (int16_t)((sig_in - (1 << (REAL_BITS-1))) >> REAL_BITS);
+#endif
+
+    return sig_out;
+}
+
+void lt_update_state(int16_t *lt_pred_stat, real_t *time, real_t *overlap,
                      uint16_t frame_len, uint8_t object_type)
 {
     uint16_t i;
@@ -145,8 +170,8 @@
         {
             lt_pred_stat[i]  /* extra 512 */  = lt_pred_stat[i + frame_len];
             lt_pred_stat[frame_len + i]       = lt_pred_stat[i + (frame_len * 2)];
-            lt_pred_stat[(frame_len * 2) + i] = time[i];
-            lt_pred_stat[(frame_len * 3) + i] = overlap[i];
+            lt_pred_stat[(frame_len * 2) + i] = real_to_int16(time[i]);
+            lt_pred_stat[(frame_len * 3) + i] = real_to_int16(overlap[i]);
         }
     } else {
 #endif
@@ -153,8 +178,8 @@
         for (i = 0; i < frame_len; i++)
         {
             lt_pred_stat[i]                   = lt_pred_stat[i + frame_len];
-            lt_pred_stat[frame_len + i]       = time[i];
-            lt_pred_stat[(frame_len * 2) + i] = overlap[i];
+            lt_pred_stat[frame_len + i]       = real_to_int16(time[i]);
+            lt_pred_stat[(frame_len * 2) + i] = real_to_int16(overlap[i]);
 #if 0 /* set to zero once upon initialisation */
             lt_pred_stat[(frame_len * 3) + i] = 0;
 #endif
--- a/libfaad/lt_predict.h
+++ b/libfaad/lt_predict.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: lt_predict.h,v 1.9 2003/11/02 20:24:04 menno Exp $
+** $Id: lt_predict.h,v 1.10 2003/11/04 21:43:30 menno Exp $
 **/
 
 #ifdef LTP_DEC
@@ -41,7 +41,7 @@
 void lt_prediction(ic_stream *ics,
                    ltp_info *ltp,
                    real_t *spec,
-                   real_t *lt_pred_stat,
+                   int16_t *lt_pred_stat,
                    fb_info *fb,
                    uint8_t win_shape,
                    uint8_t win_shape_prev,
@@ -49,11 +49,14 @@
                    uint8_t object_type,
                    uint16_t frame_len);
 
-void lt_update_state(real_t *lt_pred_stat,
+void lt_update_state(int16_t *lt_pred_stat,
                      real_t *time,
                      real_t *overlap,
                      uint16_t frame_len,
                      uint8_t object_type);
+
+
+static int16_t real_to_int16(real_t sig_in);
 
 #ifdef __cplusplus
 }
--- a/libfaad/output.c
+++ b/libfaad/output.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: output.c,v 1.24 2003/11/02 20:24:04 menno Exp $
+** $Id: output.c,v 1.25 2003/11/04 21:43:30 menno Exp $
 **/
 
 #include "common.h"
@@ -151,18 +151,51 @@
     uint8_t ch;
     uint16_t i;
     int16_t *short_sample_buffer = (int16_t*)sample_buffer;
+    int32_t *int_sample_buffer = (int32_t*)sample_buffer;
 
     /* Copy output to a standard PCM buffer */
     for (ch = 0; ch < channels; ch++)
     {
-        for(i = 0; i < frame_len; i++)
+        switch (format)
         {
-            int32_t tmp = input[ch][i];
-            tmp += (1 << (REAL_BITS-1));
-            tmp >>= REAL_BITS;
-            if (tmp > 0x7fff)       tmp = 0x7fff;
-            else if (tmp <= -32768) tmp = -32768;
-            short_sample_buffer[(i*channels)+ch] = (int16_t)tmp;
+        case FAAD_FMT_16BIT:
+            for(i = 0; i < frame_len; i++)
+            {
+                int32_t tmp = input[ch][i];
+                if (tmp > REAL_CONST(32767)) tmp = REAL_CONST(32767);
+                else if (tmp <= REAL_CONST(-32768)) tmp = REAL_CONST(-32768);
+                tmp += (1 << (REAL_BITS-1));
+                tmp >>= REAL_BITS;
+                short_sample_buffer[(i*channels)+ch] = (int16_t)tmp;
+            }
+            break;
+        case FAAD_FMT_24BIT:
+            for(i = 0; i < frame_len; i++)
+            {
+                int32_t tmp = input[ch][i];
+                if (tmp > REAL_CONST(32767)) tmp = REAL_CONST(32767);
+                else if (tmp <= REAL_CONST(-32768)) tmp = REAL_CONST(-32768);
+                tmp += (1 << (REAL_BITS-9));
+                tmp >>= (REAL_BITS-8);
+                int_sample_buffer[(i*channels)+ch] = (int32_t)tmp;
+            }
+            break;
+        case FAAD_FMT_32BIT:
+            for(i = 0; i < frame_len; i++)
+            {
+                int32_t tmp = input[ch][i];
+                if (tmp > REAL_CONST(32767)) tmp = REAL_CONST(32767);
+                else if (tmp <= REAL_CONST(-32768)) tmp = REAL_CONST(-32768);
+#if ((REAL_BITS - 16) < 0)
+                tmp += (1 >> -(REAL_BITS-16));
+                tmp <<= -(REAL_BITS-16);
+#else
+                tmp += (1 << (REAL_BITS-16));
+                tmp >>= (REAL_BITS-16);
+#endif
+                int_sample_buffer[(i*channels)+ch] = (int32_t)tmp;
+            }
+            break;
         }
     }
 
--- a/libfaad/rvlc.c
+++ b/libfaad/rvlc.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: rvlc.c,v 1.9 2003/11/02 20:24:04 menno Exp $
+** $Id: rvlc.c,v 1.10 2003/11/04 21:43:30 menno Exp $
 **/
 
 /* RVLC scalefactor decoding
@@ -283,9 +283,8 @@
                         t = rvlc_huffman_sf(ld_sf, ld_esc, -1);
                         is_position -= t;
 
-                        ics->scale_factors[g][sfb] = is_position;
+                        ics->scale_factors[g][sfb] = (uint8_t)is_position;
                     }
-
                     break;
                 case NOISE_HCB: /* noise books */
 
@@ -299,8 +298,7 @@
                         noise_energy -= t;
                     }
 
-                    ics->scale_factors[g][sfb] = noise_energy;
-
+                    ics->scale_factors[g][sfb] = (uint8_t)noise_energy;
                     break;
                 default: /* spectral books */
 
@@ -315,11 +313,10 @@
                         scale_factor -= t;
                     }
 
-                    ics->scale_factors[g][sfb] = scale_factor;
-
                     if (scale_factor < 0)
                         return 4;
 
+                    ics->scale_factors[g][sfb] = (uint8_t)scale_factor;
                     break;
                 }
 #ifdef PRINT_RVLC
--- a/libfaad/specrec.c
+++ b/libfaad/specrec.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: specrec.c,v 1.30 2003/11/02 20:24:05 menno Exp $
+** $Id: specrec.c,v 1.31 2003/11/04 21:43:30 menno Exp $
 **/
 
 /*
@@ -527,17 +527,8 @@
     if (q < IQ_TABLE_SIZE)
         return sgn * tab[q];
 
-    /* linear interpolation */
-#ifndef SMALL_IQ_TAB
-    x1 = tab[q>>3];
-    x2 = tab[(q>>3) + 1];
-    return sgn * 16.0 * (errcorr[q&7] * (x2-x1) + x1);
-#else
-    x1 = tab[q/27];
-    x2 = tab[(q/27) + 1];
-    return sgn * 81.0 * (errcorr[q%27] * (x2-x1) + x1);
+    return sgn * (real_t)pow(q, 4.0/3.0);
 #endif
-#endif
 }
 
 static void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len)
@@ -688,7 +679,8 @@
         }
 
         /* intra channel prediction */
-        ic_prediction(ics, spec_coef, hDecoder->pred_stat[sce->channel], hDecoder->frameLength);
+        ic_prediction(ics, spec_coef, hDecoder->pred_stat[sce->channel], hDecoder->frameLength,
+            hDecoder->sf_index);
 
         /* In addition, for scalefactor bands coded by perceptual
            noise substitution the predictors belonging to the
@@ -716,8 +708,8 @@
         /* allocate the state only when needed */
         if (hDecoder->lt_pred_stat[sce->channel] == NULL)
         {
-            hDecoder->lt_pred_stat[sce->channel] = (real_t*)malloc(hDecoder->frameLength*4 * sizeof(real_t));
-            memset(hDecoder->lt_pred_stat[sce->channel], 0, hDecoder->frameLength*4 * sizeof(real_t));
+            hDecoder->lt_pred_stat[sce->channel] = (int16_t*)malloc(hDecoder->frameLength*4 * sizeof(int16_t));
+            memset(hDecoder->lt_pred_stat[sce->channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
         }
 
         /* long term prediction */
@@ -839,8 +831,10 @@
         }
 
         /* intra channel prediction */
-        ic_prediction(ics1, spec_coef1, hDecoder->pred_stat[cpe->channel], hDecoder->frameLength);
-        ic_prediction(ics2, spec_coef2, hDecoder->pred_stat[cpe->paired_channel], hDecoder->frameLength);
+        ic_prediction(ics1, spec_coef1, hDecoder->pred_stat[cpe->channel], hDecoder->frameLength,
+            hDecoder->sf_index);
+        ic_prediction(ics2, spec_coef2, hDecoder->pred_stat[cpe->paired_channel], hDecoder->frameLength,
+            hDecoder->sf_index);
 
         /* In addition, for scalefactor bands coded by perceptual
            noise substitution the predictors belonging to the
@@ -877,13 +871,13 @@
         /* allocate the state only when needed */
         if (hDecoder->lt_pred_stat[cpe->channel] == NULL)
         {
-            hDecoder->lt_pred_stat[cpe->channel] = (real_t*)malloc(hDecoder->frameLength*4 * sizeof(real_t));
-            memset(hDecoder->lt_pred_stat[cpe->channel], 0, hDecoder->frameLength*4 * sizeof(real_t));
+            hDecoder->lt_pred_stat[cpe->channel] = (int16_t*)malloc(hDecoder->frameLength*4 * sizeof(int16_t));
+            memset(hDecoder->lt_pred_stat[cpe->channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
         }
         if (hDecoder->lt_pred_stat[cpe->paired_channel] == NULL)
         {
-            hDecoder->lt_pred_stat[cpe->paired_channel] = (real_t*)malloc(hDecoder->frameLength*4 * sizeof(real_t));
-            memset(hDecoder->lt_pred_stat[cpe->paired_channel], 0, hDecoder->frameLength*4 * sizeof(real_t));
+            hDecoder->lt_pred_stat[cpe->paired_channel] = (int16_t*)malloc(hDecoder->frameLength*4 * sizeof(int16_t));
+            memset(hDecoder->lt_pred_stat[cpe->paired_channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
         }
 
         /* long term prediction */
--- a/libfaad/structs.h
+++ b/libfaad/structs.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: structs.h,v 1.19 2003/11/02 20:24:05 menno Exp $
+** $Id: structs.h,v 1.20 2003/11/04 21:43:30 menno Exp $
 **/
 
 #ifndef __STRUCTS_H__
@@ -46,9 +46,9 @@
 
 /* used to save the prediction state */
 typedef struct {
-    real_t r[2];
-    real_t KOR[2];
-    real_t VAR[2];
+    int16_t r[2];
+    int16_t COR[2];
+    int16_t VAR[2];
 } pred_state;
 
 typedef struct {
@@ -244,7 +244,7 @@
     uint8_t num_sec[8]; /* number of sections in a group */
 
     uint8_t global_gain;
-    int16_t scale_factors[8][51];
+    int16_t scale_factors[8][51]; /* [0..255] */
 
     uint8_t ms_mask_present;
     uint8_t ms_used[MAX_WINDOW_GROUPS][MAX_SFB];
@@ -408,7 +408,7 @@
     pred_state *pred_stat[MAX_CHANNELS];
 #endif
 #ifdef LTP_DEC
-    real_t *lt_pred_stat[MAX_CHANNELS];
+    int16_t *lt_pred_stat[MAX_CHANNELS];
 #endif
 
 #ifndef FIXED_POINT
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through [email protected].
 **
-** $Id: syntax.c,v 1.59 2003/11/02 20:24:05 menno Exp $
+** $Id: syntax.c,v 1.60 2003/11/04 21:43:30 menno Exp $
 **/
 
 /*
@@ -695,22 +695,6 @@
     return 0;
 }
 
-static uint8_t pred_sfb_max[] =
-{
-    33,     /* 96000 */
-    33,     /* 88200 */
-    38,     /* 64000 */
-    40,     /* 48000 */
-    40,     /* 44100 */
-    40,     /* 32000 */
-    41,     /* 24000 */
-    41,     /* 22050 */
-    37,     /* 16000 */
-    37,     /* 12000 */
-    37,     /* 11025 */
-    34      /* 8000  */
-};
-
 /* Table 4.4.6 */
 static uint8_t ics_info(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
                         uint8_t common_window)
@@ -753,7 +737,7 @@
             {
                 uint8_t sfb;
 
-                ics->pred.limit = min(ics->max_sfb, pred_sfb_max[hDecoder->sf_index]);
+                ics->pred.limit = min(ics->max_sfb, max_pred_sfb(hDecoder->sf_index));
 
                 if ((ics->pred.predictor_reset = faad_get1bit(ld
                     DEBUGVAR(1,53,"ics_info(): pred.predictor_reset"))) & 1)
@@ -1410,7 +1394,7 @@
                 if (t < 0)
                     return 9;
                 scale_factor += (t - 60);
-                if (scale_factor < 0)
+                if (scale_factor < 0 || scale_factor > 255)
                     return 4;
                 ics->scale_factors[g][sfb] = scale_factor;