shithub: aacdec

Download patch

ref: 01565e17da503b6b50fa0a575932598cfbbb81b4
parent: 1117181826387b1043fd5ad975df2005fc6feb8d
author: menno <menno>
date: Sat Mar 16 08:38:37 EST 2002

Delay fixed in LD decoding
Small performance updates
More compile options - can now be compiled as LC only decoder for example

--- a/libfaad/common.h
+++ b/libfaad/common.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: common.h,v 1.2 2002/02/20 13:05:57 menno Exp $
+** $Id: common.h,v 1.3 2002/03/16 13:38:37 menno Exp $
 **/
 
 #ifndef __COMMON_H__
@@ -51,7 +51,14 @@
 #define M_PI_2 1.57079632679489661923
 #endif
 
+#ifndef LN2
+#define LN2 0.6931471805599453
+#endif
 
+#ifndef LN05
+#define LN05 -LN2
+#endif
+
 /* COMPILE TIME DEFINITIONS */
 
 /* use double precision */
@@ -61,6 +68,20 @@
    otherwise recurrence relations are used [no memory usage, lower speed] */
 #define USE_TWIDDLE_TABLE
 
+/* Allow decoding of MAIN profile AAC */
+#define MAIN_DEC
+/* Allow decoding of LTP profile AAC */
+#define LTP_DEC
+/* Allow decoding of LD profile AAC */
+#define LD_DEC
+
+/* LD can't do without LTP */
+#ifdef LD_DEC
+#ifndef LTP_DEC
+#define LTP_DEC
+#endif
+#endif
+
 /* END COMPILE TIME DEFINITIONS */
 
 
@@ -110,7 +131,8 @@
 
     #define sin sinf
     #define cos cosf
-    #define pow powf
+    #define log logf
+    #define exp expf
     #define floor floorf
     #define sqrt sqrtf
 
@@ -124,8 +146,11 @@
 #ifdef HAVE_COSF
 #  define cos cosf
 #endif
-#ifdef HAVE_POWF
-#  define pow powf
+#ifdef HAVE_LOGF
+#  define log logf
+#endif
+#ifdef HAVE_EXPF
+#  define exp expf
 #endif
 #ifdef HAVE_FLOORF
 #  define floor floorf
--- a/libfaad/data.c
+++ b/libfaad/data.c
@@ -16,16 +16,18 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: data.c,v 1.3 2002/02/25 19:58:33 menno Exp $
+** $Id: data.c,v 1.4 2002/03/16 13:38:37 menno Exp $
 **/
 
 #include "common.h"
 #include "data.h"
 
+#ifdef LD_DEC
 extern uint8_t num_swb_512_window[] =
 {
     0, 0, 0, 35, 35, 36, 30, 30, 0, 0, 0, 0
 };
+#endif
 
 extern uint8_t num_swb_1024_window[] =
 {
@@ -71,6 +73,7 @@
     768, 800, 832, 864, 896, 928, 1024
 };
 
+#ifdef LD_DEC
 static uint16_t swb_offset_512_48[] =
 {
     0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 68, 76, 84,
@@ -77,6 +80,7 @@
     92, 100, 112, 124, 136, 148, 164, 184, 208, 236, 268, 300, 332, 364, 396,
     428, 460, 512
 };
+#endif
 
 static uint16_t swb_offset_128_48[] =
 {
@@ -91,6 +95,7 @@
     768, 800, 832, 864, 896, 928, 960, 992, 1024
 };
 
+#ifdef LD_DEC
 static uint16_t swb_offset_512_32[] =
 {
     0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80,
@@ -97,6 +102,7 @@
     88, 96, 108, 120, 132, 144, 160, 176, 192, 212, 236, 260, 288, 320, 352,
     384, 416, 448, 480, 512
 };
+#endif
 
 static uint16_t swb_offset_1024_24[] =
 {
@@ -106,6 +112,7 @@
     768, 832, 896, 960, 1024
 };
 
+#ifdef LD_DEC
 static uint16_t swb_offset_512_24[] =
 {
     0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68,
@@ -112,6 +119,7 @@
     80, 92, 104, 120, 140, 164, 192, 224, 256, 288, 320, 352, 384, 416,
     448, 480, 512
 };
+#endif
 
 static uint16_t swb_offset_128_24[] =
 {
@@ -158,6 +166,7 @@
     swb_offset_1024_8        /* 8000  */
 };
 
+#ifdef LD_DEC
 extern uint16_t *swb_offset_512_window[] =
 {
     0,                       /* 96000 */
@@ -173,6 +182,7 @@
     0,                       /* 11025 */
     0                        /* 8000  */
 };
+#endif
 
 extern uint16_t *swb_offset_128_window[] =
 {
--- a/libfaad/data.h
+++ b/libfaad/data.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: data.h,v 1.3 2002/02/25 19:58:33 menno Exp $
+** $Id: data.h,v 1.4 2002/03/16 13:38:37 menno Exp $
 **/
 
 #ifndef __DATA_H__
@@ -27,10 +27,14 @@
 #endif
 
 extern uint8_t num_swb_1024_window[];
+#ifdef LD_DEC
 extern uint8_t num_swb_512_window[];
+#endif
 extern uint8_t num_swb_128_window[];
 extern uint16_t *swb_offset_1024_window[];
+#ifdef LD_DEC
 extern uint16_t *swb_offset_512_window[];
+#endif
 extern uint16_t *swb_offset_128_window[];
 extern uint8_t pred_sfb_max[];
 extern uint32_t sample_rates[];
--- 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.11 2002/02/25 20:46:00 menno Exp $
+** $Id: decoder.c,v 1.12 2002/03/16 13:38:37 menno Exp $
 **/
 
 #include <stdlib.h>
@@ -69,11 +69,15 @@
     for (i = 0; i < MAX_CHANNELS; i++)
     {
         hDecoder->window_shape_prev[i] = 0;
-        hDecoder->ltp_lag[i] = 0;
         hDecoder->time_state[i] = NULL;
         hDecoder->time_out[i] = NULL;
+#ifdef MAIN_DEC
         hDecoder->pred_stat[i] = NULL;
+#endif
+#ifdef LTP_DEC
+        hDecoder->ltp_lag[i] = 0;
         hDecoder->lt_pred_stat[i] = NULL;
+#endif
     }
 
     init_drc(&hDecoder->drc, 1.0f, 1.0f);
@@ -80,9 +84,7 @@
     filter_bank_init(&hDecoder->fb);
 #if IQ_TABLE_SIZE && POW_TABLE_SIZE
     build_tables(hDecoder->iq_table, hDecoder->pow2_table);
-#elif !IQ_TABLE_SIZE && POW_TABLE_SIZE
-    build_tables(NULL, hDecoder->pow2_table);
-#elif IQ_TABLE_SIZE && !POW_TABLE_SIZE
+#elif !POW_TABLE_SIZE
     build_tables(hDecoder->iq_table, NULL);
 #endif
 
@@ -198,7 +200,9 @@
 
     rc = AudioSpecificConfig(pBuffer, samplerate, channels,
         &hDecoder->sf_index, &hDecoder->object_type);
+#ifdef LD_DEC
     if (hDecoder->object_type != LD)
+#endif
         hDecoder->object_type--; /* For AAC differs from MPEG-4 */
     if (rc != 0)
     {
@@ -217,8 +221,12 @@
     {
         if (hDecoder->time_state[i]) free(hDecoder->time_state[i]);
         if (hDecoder->time_out[i]) free(hDecoder->time_out[i]);
+#ifdef MAIN_DEC
         if (hDecoder->pred_stat[i]) free(hDecoder->pred_stat[i]);
+#endif
+#ifdef LTP_DEC
         if (hDecoder->lt_pred_stat[i]) free(hDecoder->lt_pred_stat[i]);
+#endif
     }
 
     filter_bank_end(&hDecoder->fb);
@@ -286,13 +294,13 @@
     uint8_t sf_index       =  hDecoder->sf_index;
     uint8_t object_type    =  hDecoder->object_type;
     uint8_t channelConfiguration = hDecoder->channelConfiguration;
+#ifdef MAIN_DEC
     pred_state **pred_stat =  hDecoder->pred_stat;
+#endif
+#ifdef LTP_DEC
     real_t **lt_pred_stat  =  hDecoder->lt_pred_stat;
-#if IQ_TABLE_SIZE
-    real_t *iq_table       =  hDecoder->iq_table;
-#else
-    real_t *iq_table       =  NULL;
 #endif
+    real_t *iq_table       =  hDecoder->iq_table;
 #if POW_TABLE_SIZE
     real_t *pow2_table     =  hDecoder->pow2_table;
 #else
@@ -304,7 +312,9 @@
     fb_info *fb            = &hDecoder->fb;
     drc_info *drc          = &hDecoder->drc;
     uint8_t outputFormat   =  hDecoder->config.outputFormat;
+#ifdef LTP_DEC
     uint16_t *ltp_lag      =  hDecoder->ltp_lag;
+#endif
 
     program_config pce;
     element *syntax_elements[MAX_SYNTAX_ELEMENTS];
@@ -312,7 +322,11 @@
     real_t *spec_coef[MAX_CHANNELS];
 
     /* frame length is different for Low Delay AAC */
-    uint16_t frame_len = (object_type == LD) ? 512 : 1024;
+    uint16_t frame_len =
+#ifdef LD_DEC
+        (object_type == LD) ? 512 :
+#endif
+        1024;
 
     void *sample_buffer;
 
@@ -340,8 +354,10 @@
     dbg_count = 0;
 #endif
 
+#ifdef LD_DEC
     if (object_type != LD)
     {
+#endif
         /* Table 4.4.3: raw_data_block() */
         while ((id_syn_ele = (uint8_t)faad_getbits(ld, LEN_SE_ID
             DEBUGVAR(1,4,"faacDecDecode(): id_syn_ele"))) != ID_END)
@@ -372,6 +388,7 @@
             }
             ele++;
         }
+#ifdef LD_DEC
     } else {
         /* Table 262: er_raw_data_block() */
         switch (channelConfiguration)
@@ -440,6 +457,8 @@
         }
 #endif
     }
+#endif
+
     /* no more bit reading after this */
     faad_byte_align(ld);
     hInfo->bytesconsumed = bit2byte(faad_get_processed_bits(ld));
@@ -526,6 +545,7 @@
         if (!right_channel)
             is_decode(ics, icsr, spec_coef[ch], spec_coef[pch]);
 
+#ifdef MAIN_DEC
         /* MAIN object type prediction */
         if (object_type == MAIN)
         {
@@ -544,7 +564,16 @@
                corresponding spectral coefficients are reset.
             */
             pns_reset_pred_state(ics, pred_stat[ch]);
-        } else if ((object_type == LTP) || (object_type == LD)) {
+        }
+#endif
+#ifdef LTP_DEC
+        else if ((object_type == LTP)
+#ifdef LD_DEC
+            || (object_type == LD)
+#endif
+            )
+        {
+#ifdef LD_DEC
             if (object_type == LD)
             {
                 if (ltp->data_present)
@@ -555,6 +584,7 @@
                         ltp_lag[ch] = ltp->lag;
                 }
             }
+#endif
 
             /* allocate the state only when needed */
             if (lt_pred_stat[ch] == NULL)
@@ -568,6 +598,7 @@
                 ics->window_shape, window_shape_prev[ch],
                 sf_index, object_type, frame_len);
         }
+#endif
 
         /* tns decoding */
         tns_decode_frame(ics, &(ics->tns), sf_index, object_type, spec_coef[ch]);
@@ -605,11 +636,17 @@
         /* save window shape for next frame */
         window_shape_prev[ch] = ics->window_shape;
 
-        if (((object_type == LTP) || (object_type == LD)) && (lt_pred_stat[ch] != NULL))
+#ifdef LTP_DEC
+        if ((object_type == LTP)
+#ifdef LD_DEC
+            || (object_type == LD)
+#endif
+            )
         {
             lt_update_state(lt_pred_stat[ch], time_out[ch], time_state[ch],
                 frame_len, object_type);
         }
+#endif
     }
 
     sample_buffer = output_to_PCM(time_out, sample_buffer, channels,
@@ -616,8 +653,19 @@
         frame_len, outputFormat);
 
     hDecoder->frame++;
-    if (hDecoder->frame <= 1)
-        hInfo->samples = 0;
+#ifdef LD_DEC
+    if (object_type != LD)
+    {
+#endif
+        if (hDecoder->frame <= 1)
+            hInfo->samples = 0;
+#ifdef LD_DEC
+    } else {
+        /* LD encoders will give lower delay */
+        if (hDecoder->frame <= 0)
+            hInfo->samples = 0;
+    }
+#endif
 
     /* cleanup */
     for (ch = 0; ch < channels; ch++)
--- 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.4 2002/02/25 19:58:33 menno Exp $
+** $Id: decoder.h,v 1.5 2002/03/16 13:38:37 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -77,7 +77,9 @@
     void *sample_buffer;
 
     uint8_t window_shape_prev[MAX_CHANNELS];
+#ifdef LTP_DEC
     uint16_t ltp_lag[MAX_CHANNELS];
+#endif
     fb_info fb;
     drc_info drc;
 
@@ -84,15 +86,17 @@
     real_t *time_state[MAX_CHANNELS];
     real_t *time_out[MAX_CHANNELS];
 
+#ifdef MAIN_DEC
     pred_state *pred_stat[MAX_CHANNELS];
+#endif
+#ifdef LTP_DEC
     real_t *lt_pred_stat[MAX_CHANNELS];
+#endif
 
     real_t exp_table[256];
     real_t mnt_table[128];
 
-#if IQ_TABLE_SIZE
     real_t iq_table[IQ_TABLE_SIZE];
-#endif
 #if POW_TABLE_SIZE
     real_t pow2_table[POW_TABLE_SIZE];
 #endif
--- a/libfaad/drc.c
+++ b/libfaad/drc.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: drc.c,v 1.3 2002/02/20 13:05:57 menno Exp $
+** $Id: drc.c,v 1.4 2002/03/16 13:38:37 menno Exp $
 **/
 
 #include "common.h"
@@ -53,9 +53,9 @@
 
         /* Decode DRC gain factor */
         if (drc->dyn_rng_sgn[bd])  /* compress */
-            factor = (real_t)pow(2.0, (-drc->ctrl1 * drc->dyn_rng_ctl[bd]/24.0));
+            factor = (real_t)exp(LN2 * (-drc->ctrl1 * drc->dyn_rng_ctl[bd]/24.0));
         else /* boost */
-            factor = (real_t)pow(2.0, (drc->ctrl2 * drc->dyn_rng_ctl[bd]/24.0));
+            factor = (real_t)exp(LN2 * (drc->ctrl2 * drc->dyn_rng_ctl[bd]/24.0));
 
         /* Level alignment between different programs (if desired) */
         /* If program reference normalization is done in the digital domain,
@@ -65,7 +65,7 @@
            modification avoids problems with reduced DAC SNR (if signal is
            attenuated) or clipping (if signal is boosted)
          */
-        factor *= (real_t)pow(0.5, ((DRC_REF_LEVEL - drc->prog_ref_level)/24.0));
+        factor *= (real_t)exp(LN05 * ((DRC_REF_LEVEL - drc->prog_ref_level)/24.0));
 
         /* Apply gain factor */
         for (i = bottom; i < top; i++)
--- 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.4 2002/02/25 19:58:33 menno Exp $
+** $Id: filtbank.c,v 1.5 2002/03/16 13:38:37 menno Exp $
 **/
 
 #include "common.h"
@@ -33,6 +33,7 @@
 {
     uint16_t i;
 
+#ifdef LD_DEC
     /* LD */
     mdct_init(&(fb->mdct1024), 1024);
 
@@ -50,6 +51,7 @@
         fb->ld_window[1][i] = (real_t)sin((i-3*(BLOCK_LEN_LD>>3)+0.5) * M_PI / (BLOCK_LEN_LD>>1));
     for (; i < BLOCK_LEN_LD; i++)
         fb->ld_window[1][i] = 1.0;
+#endif
 
     /* normal */
     mdct_init(&(fb->mdct256), 256);
@@ -70,13 +72,17 @@
 void filter_bank_end(fb_info *fb)
 {
     mdct_end(&(fb->mdct256));
+#ifdef LD_DEC
     mdct_end(&(fb->mdct1024));
+#endif
     mdct_end(&(fb->mdct2048));
 
     if (fb->long_window[0]) free(fb->long_window[0]);
     if (fb->short_window[0]) free(fb->short_window[0]);
+#ifdef LD_DEC
     if (fb->ld_window[0]) free(fb->ld_window[0]);
     if (fb->ld_window[1]) free(fb->ld_window[1]);
+#endif
 }
 
 static INLINE void vcopy(real_t *src, real_t *dest, uint16_t vlen)
@@ -171,13 +177,15 @@
     switch (len)
     {
     case 2048:
-        IMDCT_long(&(fb->mdct2048), in_data, out_data);
+        IMDCT_2048(&(fb->mdct2048), in_data, out_data);
         return;
+#ifdef LD_DEC
     case 1024:
-        IMDCT_LD(&(fb->mdct1024), in_data, out_data);
+        IMDCT_1024(&(fb->mdct1024), in_data, out_data);
         return;
+#endif
     case 256:
-        IMDCT_short(&(fb->mdct256), in_data, out_data);
+        IMDCT_256(&(fb->mdct256), in_data, out_data);
         return;
     }
 }
@@ -187,13 +195,15 @@
     switch (len)
     {
     case 2048:
-        MDCT_long(&(fb->mdct2048), in_data, out_data);
+        MDCT_2048(&(fb->mdct2048), in_data, out_data);
         return;
+#ifdef LD_DEC
     case 1024:
-        MDCT_LD(&(fb->mdct1024), in_data, out_data);
+        MDCT_1024(&(fb->mdct1024), in_data, out_data);
         return;
+#endif
     case 256:
-        MDCT_short(&(fb->mdct256), in_data, out_data);
+        MDCT_256(&(fb->mdct256), in_data, out_data);
         return;
     }
 }
@@ -212,7 +222,11 @@
 
     real_t *fp;
     int8_t win;
-    uint16_t nlong = (object_type == LD) ? 512 : 1024;
+    uint16_t nlong =
+#ifdef LD_DEC
+        (object_type == LD) ? 512 :
+#endif
+        1024;
     uint16_t nshort = 128;
 
     uint16_t nflat_ls = (nlong-nshort)/2;
@@ -219,16 +233,20 @@
 
     transf_buf = malloc(2*nlong*sizeof(real_t));
 
+#ifdef LD_DEC
     if (object_type == LD)
     {
         window_long       = fb->ld_window[window_shape];
         window_long_prev  = fb->ld_window[window_shape_prev];
     } else {
+#endif
         window_long       = fb->long_window[window_shape];
         window_long_prev  = fb->long_window[window_shape_prev];
         window_short      = fb->short_window[window_shape];
         window_short_prev = fb->short_window[window_shape_prev];
+#ifdef LD_DEC
     }
+#endif
 
     /* pointer to previous window function */
     window_short_prev_ptr = window_short_prev;
@@ -348,22 +366,30 @@
     real_t *window_short_prev;
     real_t *window_short_prev_ptr;
 
-    uint16_t nlong = (object_type == LD) ? 512 : 1024;
+    uint16_t nlong =
+#ifdef LD_DEC
+        (object_type == LD) ? 512 :
+#endif
+        1024;
     uint16_t nshort = 128;
     uint16_t nflat_ls = (nlong-nshort)/2;
 
     windowed_buf = malloc(nlong*2*sizeof(real_t));
 
+#ifdef LD_DEC
     if (object_type == LD)
     {
         window_long       = fb->ld_window[window_shape];
         window_long_prev  = fb->ld_window[window_shape_prev];
     } else {
+#endif
         window_long       = fb->long_window[window_shape];
         window_long_prev  = fb->long_window[window_shape_prev];
         window_short      = fb->short_window[window_shape];
         window_short_prev = fb->short_window[window_shape_prev];
+#ifdef LD_DEC
     }
+#endif
 
     window_short_prev_ptr = window_short_prev;
   
--- a/libfaad/filtbank.h
+++ b/libfaad/filtbank.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: filtbank.h,v 1.4 2002/02/25 19:58:33 menno Exp $
+** $Id: filtbank.h,v 1.5 2002/03/16 13:38:37 menno Exp $
 **/
 
 #ifndef __FILTBANK_H__
@@ -37,10 +37,14 @@
 {
     real_t *long_window[2];
     real_t *short_window[2];
+#ifdef LD_DEC
     real_t *ld_window[2];
+#endif
 
     mdct_info mdct256;
+#ifdef LD_DEC
     mdct_info mdct1024;
+#endif
     mdct_info mdct2048;
 } fb_info;
 
--- a/libfaad/ic_predict.c
+++ b/libfaad/ic_predict.c
@@ -16,10 +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: ic_predict.c,v 1.2 2002/02/18 10:01:05 menno Exp $
+** $Id: ic_predict.c,v 1.3 2002/03/16 13:38:37 menno Exp $
 **/
 
 #include "common.h"
+
+#ifdef MAIN_DEC
+
 #include "syntax.h"
 #include "ic_predict.h"
 #include "pns.h"
@@ -172,3 +175,5 @@
         }
     }
 }
+
+#endif
--- a/libfaad/ic_predict.h
+++ b/libfaad/ic_predict.h
@@ -16,9 +16,11 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: ic_predict.h,v 1.2 2002/02/18 10:01:05 menno Exp $
+** $Id: ic_predict.h,v 1.3 2002/03/16 13:38:37 menno Exp $
 **/
 
+#ifdef MAIN_DEC
+
 #ifndef __IC_PREDICT_H__
 #define __IC_PREDICT_H__
 
@@ -47,4 +49,6 @@
 #ifdef __cplusplus
 }
 #endif
+#endif
+
 #endif
--- a/libfaad/is.c
+++ b/libfaad/is.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: is.c,v 1.3 2002/02/20 13:05:57 menno Exp $
+** $Id: is.c,v 1.4 2002/03/16 13:38:37 menno Exp $
 **/
 
 #include "common.h"
@@ -50,7 +50,7 @@
 
                     scale = is_intensity(icsr, g, sfb) *
                         invert_intensity(ics, g, sfb) *
-                        (real_t)pow(0.5, (0.25*icsr->scale_factors[g][sfb]));
+                        (real_t)exp(LN05 * (0.25*icsr->scale_factors[g][sfb]));
 
                     /* Scale from left to right channel,
                        do not touch left channel */
--- a/libfaad/lt_predict.c
+++ b/libfaad/lt_predict.c
@@ -16,10 +16,14 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: lt_predict.c,v 1.3 2002/02/25 19:58:33 menno Exp $
+** $Id: lt_predict.c,v 1.4 2002/03/16 13:38:37 menno Exp $
 **/
 
+
 #include "common.h"
+
+#ifdef LTP_DEC
+
 #include <stdlib.h>
 #include "syntax.h"
 #include "lt_predict.h"
@@ -100,6 +104,7 @@
      *
      * For the LD object type an extra 512 samples lookback is accomodated here.
      */
+#ifdef LD_DEC
     if (object_type == LD)
     {
         for (i = 0; i < frame_len; i++)
@@ -110,6 +115,7 @@
             lt_pred_stat[(frame_len * 3) + i] = overlap[i];
         }
     } else {
+#endif
         for (i = 0; i < frame_len; i++)
         {
             lt_pred_stat[i]                   = lt_pred_stat[i + frame_len];
@@ -119,5 +125,9 @@
             lt_pred_stat[(frame_len * 3) + i] = 0;
 #endif
         }
+#ifdef LD_DEC
     }
-}
\ No newline at end of file
+#endif
+}
+
+#endif
--- a/libfaad/lt_predict.h
+++ b/libfaad/lt_predict.h
@@ -16,9 +16,11 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: lt_predict.h,v 1.3 2002/02/25 19:58:33 menno Exp $
+** $Id: lt_predict.h,v 1.4 2002/03/16 13:38:37 menno Exp $
 **/
 
+#ifdef LTP_DEC
+
 #ifndef __LT_PREDICT_H__
 #define __LT_PREDICT_H__
 
@@ -48,4 +50,6 @@
 #ifdef __cplusplus
 }
 #endif
+#endif
+
 #endif
--- a/libfaad/mdct.c
+++ b/libfaad/mdct.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: mdct.c,v 1.4 2002/02/25 19:58:33 menno Exp $
+** $Id: mdct.c,v 1.5 2002/03/16 13:38:36 menno Exp $
 **/
 
 /*
@@ -75,7 +75,7 @@
 #endif
 }
 
-void MDCT_long(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
+void MDCT_2048(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
 {
     fftw_complex FFTarray[512];
     real_t tempr, tempi, fac;
@@ -172,7 +172,8 @@
     }
 }
 
-void MDCT_LD(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
+#ifdef LD_DEC
+void MDCT_1024(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
 {
     fftw_complex FFTarray[256];
     real_t tempr, tempi, fac;
@@ -268,8 +269,9 @@
 #endif
     }
 }
+#endif
 
-void MDCT_short(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
+void MDCT_256(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
 {
     fftw_complex FFTarray[64];    /* the array for in-place FFT */
     real_t tempr, tempi, fac;
@@ -365,7 +367,7 @@
     }
 }
 
-void IMDCT_long(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
+void IMDCT_2048(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
 {
     fftw_complex FFTarray[512];    /* the array for in-place FFT */
     real_t tempr, tempi, fac;
@@ -460,7 +462,8 @@
     }
 }
 
-void IMDCT_LD(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
+#ifdef LD_DEC
+void IMDCT_1024(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
 {
     fftw_complex FFTarray[256];    /* the array for in-place FFT */
     real_t tempr, tempi, fac;
@@ -554,8 +557,9 @@
 #endif
     }
 }
+#endif
 
-void IMDCT_short(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
+void IMDCT_256(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data)
 {
     fftw_complex FFTarray[64];    /* the array for in-place FFT */
     real_t tempr, tempi, fac;
--- a/libfaad/mdct.h
+++ b/libfaad/mdct.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: mdct.h,v 1.4 2002/02/25 19:58:33 menno Exp $
+** $Id: mdct.h,v 1.5 2002/03/16 13:38:36 menno Exp $
 **/
 
 #ifndef __MDCT_H__
@@ -56,13 +56,17 @@
 void mdct_init(mdct_info *mdct, uint16_t len);
 void mdct_end(mdct_info *mdct);
 
-void IMDCT_long(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
-void IMDCT_LD(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
-void IMDCT_short(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
+void IMDCT_2048(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
+#ifdef LD_DEC
+void IMDCT_1024(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
+#endif
+void IMDCT_256(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
 
-void MDCT_long(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
-void MDCT_LD(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
-void MDCT_short(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
+void MDCT_2048(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
+#ifdef LD_DEC
+void MDCT_1024(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
+#endif
+void MDCT_256(mdct_info *mdct, fftw_real *in_data, fftw_real *out_data);
 
 static void make_fft_order(uint16_t *unscrambled, uint16_t len);
 
--- a/libfaad/mp4.c
+++ b/libfaad/mp4.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: mp4.c,v 1.3 2002/02/25 19:58:33 menno Exp $
+** $Id: mp4.c,v 1.4 2002/03/16 13:38:36 menno Exp $
 **/
 
 #include "common.h"
@@ -52,7 +52,11 @@
     0, /* ER AAC scalable */
     0, /* ER TwinVQ */
     0, /* ER BSAC */
+#ifdef LD_DEC
     1, /* ER AAC LD */     /* !!! Supported, but only with ER turned off !!! */
+#else
+    0, /* ER AAC LD */
+#endif
     0, /* ER CELP */
     0, /* ER HVXC */
     0, /* ER HILN */
@@ -114,6 +118,7 @@
         ObjectTypeIndex == 6 || ObjectTypeIndex == 7)
     {
         return GASpecificConfig(&ld, channels, ObjectTypeIndex);
+#ifdef LD_DEC
     } else if (ObjectTypeIndex == 23) { /* ER AAC LD */
         uint8_t result = GASpecificConfig(&ld, channels, ObjectTypeIndex);
         uint8_t ep_config = (uint8_t)faad_getbits(&ld, 2
@@ -122,6 +127,7 @@
             return -5;
 
         return result;
+#endif
     } else {
         return -4;
     }
--- a/libfaad/output.c
+++ b/libfaad/output.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: output.c,v 1.5 2002/02/25 19:58:33 menno Exp $
+** $Id: output.c,v 1.6 2002/03/16 13:38:36 menno Exp $
 **/
 
 #include "common.h"
@@ -45,6 +45,7 @@
     uint8_t ch;
     uint16_t i;
 
+    uint8_t   *p = (uint8_t*)sample_buffer;
     int16_t   *short_sample_buffer = (int16_t*)sample_buffer;
     int32_t   *int_sample_buffer = (int32_t*)sample_buffer;
     float32_t *float_sample_buffer = (float32_t*)sample_buffer;
--- a/libfaad/pns.c
+++ b/libfaad/pns.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: pns.c,v 1.4 2002/02/20 13:05:57 menno Exp $
+** $Id: pns.c,v 1.5 2002/03/16 13:38:36 menno Exp $
 **/
 
 #include "common.h"
@@ -69,7 +69,7 @@
        scale = 1.0f/(size * (real_t)sqrt(MEAN_NRG));
     */
     scale = 1.0f/(real_t)sqrt(size * MEAN_NRG);
-    scale *= (real_t)pow(2.0, 0.25*scale_factor);
+    scale *= (real_t)exp(LN2 * 0.25 * scale_factor);
 
     /* Scale random vector to desired target energy */
     for (i = 0; i < size; 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.5 2002/02/25 19:58:33 menno Exp $
+** $Id: specrec.c,v 1.6 2002/03/16 13:38:36 menno Exp $
 **/
 
 /*
@@ -60,15 +60,20 @@
         ics->num_windows = 1;
         ics->num_window_groups = 1;
         ics->window_group_length[ics->num_window_groups-1] = 1;
+#ifdef LD_DEC
         if (object_type == LD)
         {
             ics->num_swb = num_swb_512_window[fs_index];
         } else {
+#endif
             ics->num_swb = num_swb_1024_window[fs_index];
+#ifdef LD_DEC
         }
+#endif
 
         /* preparation of sect_sfb_offset for long blocks */
         /* also copy the last value! */
+#ifdef LD_DEC
         if (object_type == LD)
         {
             for (i = 0; i < ics->num_swb + 1; i++)
@@ -77,12 +82,15 @@
                 ics->swb_offset[i] = swb_offset_512_window[fs_index][i];
             }
         } else {
+#endif
             for (i = 0; i < ics->num_swb + 1; 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];
             }
+#ifdef LD_DEC
         }
+#endif
         return 0;
     case EIGHT_SHORT_SEQUENCE:
         ics->num_windows = 8;
@@ -227,16 +235,16 @@
 {
     uint16_t i;
 
-    /* build pow() table for inverse quantization */
+    /* build pow(x, 4/3) table for inverse quantization */
     for(i = 0; i < IQ_TABLE_SIZE; i++)
     {
-        iq_table[i] = (real_t)pow(i, 4.0/3.0);
+        iq_table[i] = (real_t)exp(log(i) * 4.0/3.0);
     }
 
-    /* build pow(2, 0.25) table for scalefactors */
+    /* 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));
+        pow2_table[i] = (real_t)exp(LN2 * 0.25 * (i-100));
     }
 }
 
@@ -247,13 +255,13 @@
         if (q < IQ_TABLE_SIZE)
             return iq_table[q];
         else
-            return (real_t)pow(q, 4.0/3.0);
+            return iq_table[q>>3]*16;
     } else if (q < 0) {
         q = -q;
         if (q < IQ_TABLE_SIZE)
             return -iq_table[q];
         else
-            return -(real_t)pow(q, 4.0/3.0);
+          return -iq_table[q>>3]*16;
     } else {
         return 0.0f;
     }
@@ -284,7 +292,7 @@
     if (scale_factor < POW_TABLE_SIZE)
         return pow2_table[scale_factor];
     else
-        return (real_t)pow(2.0, 0.25 * (scale_factor - 100));
+        return (real_t)exp(LN2 * 0.25 * (scale_factor - 100));
 }
 
 void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table)
--- 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.3 2002/02/25 19:58:33 menno Exp $
+** $Id: specrec.h,v 1.4 2002/03/16 13:38:36 menno Exp $
 **/
 
 #ifndef __SPECREC_H__
@@ -28,7 +28,9 @@
 
 #include "syntax.h"
 
-#define IQ_TABLE_SIZE   200
+/* !!!DON'T CHANGE IQ_TABLE_SIZE!!! */
+#define IQ_TABLE_SIZE   1026
+
 #define POW_TABLE_SIZE  200
 
 
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.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: syntax.c,v 1.8 2002/02/25 19:58:33 menno Exp $
+** $Id: syntax.c,v 1.9 2002/03/16 13:38:36 menno Exp $
 **/
 
 /*
@@ -335,7 +335,9 @@
                     ics->pred.prediction_used[sfb] = faad_get1bit(ld
                         DEBUGVAR(1,55,"ics_info(): pred.prediction_used"));
                 }
-            } else { /* Long Term Prediction */
+            }
+#ifdef LTP_DEC
+            else { /* Long Term Prediction */
                 if ((ics->ltp.data_present = faad_get1bit(ld
                     DEBUGVAR(1,50,"ics_info(): ltp.data_present"))) & 1)
                 {
@@ -350,6 +352,7 @@
                     }
                 }
             }
+#endif
         }
     }
 
@@ -432,7 +435,11 @@
                                      uint8_t object_type)
 {
     uint8_t result;
-    uint16_t frame_len = (object_type == LD) ? 512 : 1024;
+    uint16_t frame_len =
+#ifdef LD_DEC
+        (object_type == LD) ? 512 :
+#endif
+        1024;
 
     ics->global_gain = (uint8_t)faad_getbits(ld, 8
         DEBUGVAR(1,67,"individual_channel_stream(): global_gain"));
@@ -662,6 +669,7 @@
     }
 }
 
+#ifdef LTP_DEC
 /* Table 4.4.28 */
 /*
    The limit MAX_LTP_SFB is not defined in 14496-3, this is a bug in the document
@@ -672,6 +680,7 @@
 {
     uint8_t sfb, w;
 
+#ifdef LD_DEC
     if (object_type == LD)
     {
         ltp->lag_update = (uint8_t)faad_getbits(ld, 1
@@ -683,9 +692,12 @@
                 DEBUGVAR(1,81,"ltp_data(): lag"));
         }
     } else {
+#endif
         ltp->lag = (uint16_t)faad_getbits(ld, 11
             DEBUGVAR(1,81,"ltp_data(): lag"));
+#ifdef LD_DEC
     }
+#endif
     ltp->coef = (uint8_t)faad_getbits(ld, 3
         DEBUGVAR(1,82,"ltp_data(): coef"));
 
@@ -715,6 +727,7 @@
         }
     }
 }
+#endif
 
 /* defines whether a huffman codebook is unsigned or not */
 /* Table 4.6.2 */
--- a/libfaad/tns.c
+++ b/libfaad/tns.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: tns.c,v 1.5 2002/02/27 17:38:34 menno Exp $
+** $Id: tns.c,v 1.6 2002/03/16 13:38:36 menno Exp $
 **/
 
 #include "common.h"
@@ -264,7 +264,9 @@
     uint8_t i;
 
     i = (ics->window_sequence == EIGHT_SHORT_SEQUENCE) ? 1 : 0;
+#ifdef LD_DEC
     i = (object_type == LD) ? 4 : i;
+#endif
 
     return tns_max_bands_table[sr_index][i];
 }
@@ -287,9 +289,13 @@
         switch (object_type)
         {
         case MAIN:
+            return 20;
         case LTP:
+            return 20;
+#ifdef LD_DEC
         case LD:
             return 20;
+#endif
         case LC:
         case SSR:
             return 12;