shithub: aacdec

Download patch

ref: e8edc600fe786cd49fe4a9bd0771f154ded463bd
parent: 2569c47767a3ea4a308d510ea1ac296573e0ffa2
author: menno <menno>
date: Thu Oct 9 16:04:25 EDT 2003

some small changes...
- less memory usage
- no more mallocing on every frame

--- a/libfaad/bits.h
+++ b/libfaad/bits.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: bits.h,v 1.22 2003/09/09 18:09:51 menno Exp $
+** $Id: bits.h,v 1.23 2003/10/09 20:04:24 menno Exp $
 **/
 
 #ifndef __BITS_H__
--- a/libfaad/cfft.h
+++ b/libfaad/cfft.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: cfft.h,v 1.7 2003/09/09 18:09:51 menno Exp $
+** $Id: cfft.h,v 1.8 2003/10/09 20:04:24 menno Exp $
 **/
 
 #ifndef __CFFT_H__
@@ -31,6 +31,14 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+typedef struct
+{
+    uint16_t n;
+    uint16_t ifac[15];
+    complex_t *work;
+    complex_t *tab;
+} cfft_info;
 
 
 void cfftf(cfft_info *cfft, complex_t *c);
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: common.c,v 1.7 2003/09/09 18:09:51 menno Exp $
+** $Id: common.c,v 1.8 2003/10/09 20:04:24 menno Exp $
 **/
 
 /* just some common functions that could be used anywhere */
@@ -116,6 +116,7 @@
 
     return -1;
 }
+
 
 static const  uint8_t    Parity [256] = {  // parity
 	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: common.h,v 1.31 2003/09/09 18:09:51 menno Exp $
+** $Id: common.h,v 1.32 2003/10/09 20:04:24 menno Exp $
 **/
 
 #ifndef __COMMON_H__
@@ -41,7 +41,6 @@
 #define min(a, b) (((a) < (b)) ? (a) : (b))
 #endif
 
-
 /* COMPILE TIME DEFINITIONS */
 
 /* use double precision */
@@ -49,6 +48,11 @@
 /* use fixed point reals */
 //#define FIXED_POINT
 
+#ifdef _WIN32_WCE
+#define FIXED_POINT
+#endif
+
+
 #define ERROR_RESILIENCE
 
 
@@ -60,6 +64,8 @@
 #define LTP_DEC
 /* Allow decoding of LD profile AAC */
 #define LD_DEC
+/* Allow decoding of Digital Radio Mondiale (DRM) */
+//#define DRM
 
 /* LD can't do without LTP */
 #ifdef LD_DEC
@@ -94,7 +100,7 @@
 #else
 #define qmf_t real_t
 #define QMF_RE(A) (A)
-#define QMF_IM(A) 0
+#define QMF_IM(A)
 #endif
 
 
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.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 Mpeg4AAClicense@nero.com.
 **
-** $Id: decoder.c,v 1.73 2003/10/05 15:22:10 menno Exp $
+** $Id: decoder.c,v 1.74 2003/10/09 20:04:24 menno Exp $
 **/
 
 #include "common.h"
@@ -34,20 +34,9 @@
 #include "decoder.h"
 #include "mp4.h"
 #include "syntax.h"
-#include "tns.h"
-#include "pns.h"
-#include "is.h"
-#include "ms.h"
-#include "ic_predict.h"
-#include "lt_predict.h"
-#include "drc.h"
 #include "error.h"
 #include "output.h"
 #include "dither.h"
-#ifdef SSR_DEC
-#include "ssr.h"
-#include "ssr_fb.h"
-#endif
 #ifdef SBR_DEC
 #include "sbr_dec.h"
 #endif
@@ -102,6 +91,7 @@
     hDecoder->config.outputFormat  = FAAD_FMT_16BIT;
     hDecoder->config.defObjectType = MAIN;
     hDecoder->config.defSampleRate = 44100; /* Default: 44.1kHz */
+    hDecoder->config.downMatrix = 0;
     hDecoder->adts_header_present = 0;
     hDecoder->adif_header_present = 0;
 #ifdef ERROR_RESILIENCE
@@ -377,7 +367,6 @@
     return 0;
 }
 
-#ifdef DRM
 int8_t FAADAPI faacDecInitDRM(faacDecHandle hDecoder, uint32_t samplerate,
                               uint8_t channels)
 {
@@ -385,9 +374,11 @@
     hDecoder->config.defObjectType = DRM_ER_LC;
 
     hDecoder->config.defSampleRate = samplerate;
+#ifdef ERROR_RESILIENCE // This shoudl always be defined for DRM
     hDecoder->aacSectionDataResilienceFlag = 1; /* VCB11 */
     hDecoder->aacScalefactorDataResilienceFlag = 0; /* no RVLC */
     hDecoder->aacSpectralDataResilienceFlag = 1; /* HCR */
+#endif
     hDecoder->frameLength = 960;
     hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate);
     hDecoder->object_type = hDecoder->config.defObjectType;
@@ -398,6 +389,7 @@
         hDecoder->channelConfiguration = 1;
 
 #ifdef SBR_DEC
+#ifdef DRM
     if (channels == DRMCH_SBR_LC_STEREO)
         hDecoder->lcstereo_flag = 1;
     else
@@ -412,6 +404,7 @@
     sbrDecodeEnd(hDecoder->sbr[0]);
     hDecoder->sbr[0] = NULL;
 #endif
+#endif
 
     /* must be done before frameLength is divided by 2 for LD */
     hDecoder->fb = filter_bank_init(hDecoder->frameLength);
@@ -423,7 +416,6 @@
 
     return 0;
 }
-#endif
 
 void FAADAPI faacDecClose(faacDecHandle hDecoder)
 {
@@ -699,7 +691,6 @@
                             uint8_t *buffer, uint32_t buffer_size)
 {
     int32_t i;
-    uint8_t ch;
     adts_header adts;
     uint8_t channels = 0, ch_ele = 0;
     uint8_t output_channels = 0;
@@ -707,8 +698,8 @@
     uint32_t bitsconsumed;
 #ifdef DRM
     uint8_t *revbuffer;
-    uint8_t *prevbufstart;
-    uint8_t *pbufend;
+    uint8_t *prevbufstart;   
+    uint8_t *pbufend;   
 #endif
 
     /* local copy of globals */
@@ -736,9 +727,6 @@
     program_config *pce;
 
     void *sample_buffer;
-    element *syntax_elements[MAX_SYNTAX_ELEMENTS];
-    element **elements;
-    real_t *spec_coef[MAX_CHANNELS];
 
     /* safety checks */
     if ((hDecoder == NULL) || (hInfo == NULL) || (buffer == NULL) || (ld == NULL))
@@ -804,11 +792,8 @@
     dbg_count = 0;
 #endif
 
-    elements = syntax_elements;
-
     /* decode the complete bitstream */
-    elements = raw_data_block(hDecoder, hInfo, ld, syntax_elements,
-        spec_coef, pce, drc);
+    raw_data_block(hDecoder, hInfo, ld, pce, drc);
 
     ch_ele = hDecoder->fr_ch_ele;
     channels = hDecoder->fr_channels;
@@ -912,202 +897,27 @@
         return NULL;
     }
 
+    /* allocate the buffer for the final samples */
     if (hDecoder->sample_buffer == NULL)
     {
+        static const uint8_t str[] = { sizeof(int16_t), sizeof(int32_t), sizeof(int32_t),
+            sizeof(float32_t), sizeof(double), sizeof(int16_t), sizeof(int16_t),
+            sizeof(int16_t), sizeof(int16_t), 0, 0, 0
+        };
+        uint8_t stride = str[outputFormat-1];
 #ifdef SBR_DEC
         if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
-        {
-            if (hDecoder->config.outputFormat == FAAD_FMT_DOUBLE)
-                hDecoder->sample_buffer = malloc(2*frame_len*channels*sizeof(double));
-            else
-                hDecoder->sample_buffer = malloc(2*frame_len*channels*sizeof(real_t));
-        } else {
+            stride = 2 * stride;
 #endif
-            if (hDecoder->config.outputFormat == FAAD_FMT_DOUBLE)
-                hDecoder->sample_buffer = malloc(frame_len*channels*sizeof(double));
-            else
-                hDecoder->sample_buffer = malloc(frame_len*channels*sizeof(real_t));
-#ifdef SBR_DEC
-        }
-#endif
+        hDecoder->sample_buffer = malloc(frame_len*channels*stride);
     }
 
     sample_buffer = hDecoder->sample_buffer;
 
-
-    /* Because for ms, is and pns both channels spectral coefficients are needed
-       we have to restart running through all channels here.
-    */
-    for (ch = 0; ch < channels; ch++)
-    {
-        int16_t pch = -1;
-        uint8_t right_channel;
-        ic_stream *ics, *icsr;
-        ltp_info *ltp;
-
-        /* find the syntax element to which this channel belongs */
-        if (syntax_elements[hDecoder->channel_element[ch]]->channel == ch)
-        {
-            ics = &(syntax_elements[hDecoder->channel_element[ch]]->ics1);
-            icsr = &(syntax_elements[hDecoder->channel_element[ch]]->ics2);
-            ltp = &(ics->ltp);
-            pch = syntax_elements[hDecoder->channel_element[ch]]->paired_channel;
-            right_channel = 0;
-        } else if (syntax_elements[hDecoder->channel_element[ch]]->paired_channel == ch) {
-            ics = &(syntax_elements[hDecoder->channel_element[ch]]->ics2);
-            if (syntax_elements[hDecoder->channel_element[ch]]->common_window)
-                ltp = &(ics->ltp2);
-            else
-                ltp = &(ics->ltp);
-            right_channel = 1;
-        }
-
-        /* pns decoding */
-        if ((!right_channel) && (pch != -1) && (ics->ms_mask_present))
-            pns_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len, 1, object_type);
-        else if ((pch == -1) || ((pch != -1) && (!ics->ms_mask_present)))
-            pns_decode(ics, NULL, spec_coef[ch], NULL, frame_len, 0, object_type);
-
-        if (!right_channel && (pch != -1))
-        {
-            /* mid/side decoding */
-            ms_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len);
-
-            /* intensity stereo decoding */
-            is_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len);
-        }
-
-#ifdef MAIN_DEC
-        /* MAIN object type prediction */
-        if (object_type == MAIN)
-        {
-            /* allocate the state only when needed */
-            if (pred_stat[ch] == NULL)
-            {
-                pred_stat[ch] = (pred_state*)malloc(frame_len * sizeof(pred_state));
-                reset_all_predictors(pred_stat[ch], frame_len);
-            }
-
-            /* intra channel prediction */
-            ic_prediction(ics, spec_coef[ch], pred_stat[ch], frame_len);
-
-            /* In addition, for scalefactor bands coded by perceptual
-               noise substitution the predictors belonging to the
-               corresponding spectral coefficients are reset.
-            */
-            pns_reset_pred_state(ics, pred_stat[ch]);
-        }
-#endif
-#ifdef LTP_DEC
-        if ((object_type == LTP)
-#ifdef ERROR_RESILIENCE
-            || (object_type == ER_LTP)
-#endif
-#ifdef LD_DEC
-            || (object_type == LD)
-#endif
-            )
-        {
-#ifdef LD_DEC
-            if (object_type == LD)
-            {
-                if (ltp->data_present)
-                {
-                    if (ltp->lag_update)
-                        ltp_lag[ch] = ltp->lag;
-                }
-                ltp->lag = ltp_lag[ch];
-            }
-#endif
-
-            /* allocate the state only when needed */
-            if (lt_pred_stat[ch] == NULL)
-            {
-                lt_pred_stat[ch] = (real_t*)malloc(frame_len*4 * sizeof(real_t));
-                memset(lt_pred_stat[ch], 0, frame_len*4 * sizeof(real_t));
-            }
-
-            /* long term prediction */
-            lt_prediction(ics, ltp, spec_coef[ch], lt_pred_stat[ch], fb,
-                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], frame_len);
-
-        /* drc decoding */
-        if (drc->present)
-        {
-            if (!drc->exclude_mask[ch] || !drc->excluded_chns_present)
-                drc_decode(drc, spec_coef[ch]);
-        }
-
-        if (time_out[ch] == NULL)
-        {
-            time_out[ch] = (real_t*)malloc(frame_len*2*sizeof(real_t));
-            memset(time_out[ch], 0, frame_len*2*sizeof(real_t));
-        }
 #ifdef SBR_DEC
-        if (time_out2[ch] == NULL)
-        {
-            time_out2[ch] = (real_t*)malloc(frame_len*2*sizeof(real_t));
-            memset(time_out2[ch], 0, frame_len*2*sizeof(real_t));
-        }
-#endif
-
-        /* filter bank */
-#ifdef SSR_DEC
-        if (object_type != SSR)
-        {
-#endif
-            ifilter_bank(fb, ics->window_sequence, ics->window_shape,
-                window_shape_prev[ch], spec_coef[ch],
-                time_out[ch], object_type, frame_len);
-#ifdef SSR_DEC
-        } else {
-            if (ssr_overlap[ch] == NULL)
-            {
-                ssr_overlap[ch] = (real_t*)malloc(2*frame_len*sizeof(real_t));
-                memset(ssr_overlap[ch], 0, 2*frame_len*sizeof(real_t));
-            }
-            if (prev_fmd[ch] == NULL)
-            {
-                uint16_t k;
-                prev_fmd[ch] = (real_t*)malloc(2*frame_len*sizeof(real_t));
-                for (k = 0; k < 2*frame_len; k++)
-                    prev_fmd[ch][k] = REAL_CONST(-1);
-            }
-
-            ssr_decode(&(ics->ssr), fb, ics->window_sequence, ics->window_shape,
-                window_shape_prev[ch], spec_coef[ch], time_out[ch],
-                ssr_overlap[ch], hDecoder->ipqf_buffer[ch], prev_fmd[ch], frame_len);
-        }
-#endif
-        /* save window shape for next frame */
-        window_shape_prev[ch] = ics->window_shape;
-
-#ifdef LTP_DEC
-        if ((object_type == LTP)
-#ifdef ERROR_RESILIENCE
-            || (object_type == ER_LTP)
-#endif
-#ifdef LD_DEC
-            || (object_type == LD)
-#endif
-            )
-        {
-            lt_update_state(lt_pred_stat[ch], time_out[ch], time_out[ch]+frame_len,
-                frame_len, object_type);
-        }
-#endif
-    }
-
-#ifdef SBR_DEC
     if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
     {
+        uint8_t ch = 0;
         for (i = 0; i < ch_ele; i++)
         {
             /* following case can happen when forceUpSampling == 1 */
@@ -1120,25 +930,40 @@
                     );
                 hDecoder->sbr[i]->data = NULL;
                 hDecoder->sbr[i]->data_size = 0;
+                hDecoder->sbr[i]->id_aac = hDecoder->element_id[i];
             }
 
-            if (syntax_elements[i]->paired_channel != -1)
+            /* Allocate space for SBR output */
+            if (hDecoder->time_out2[ch] == NULL)
             {
-                memcpy(time_out2[syntax_elements[i]->channel],
-                    time_out[syntax_elements[i]->channel], frame_len*sizeof(real_t));
-                memcpy(time_out2[syntax_elements[i]->paired_channel],
-                    time_out[syntax_elements[i]->paired_channel], frame_len*sizeof(real_t));
+                hDecoder->time_out2[ch] = (real_t*)malloc(hDecoder->frameLength*2*sizeof(real_t));
+                memset(hDecoder->time_out2[ch], 0, hDecoder->frameLength*2*sizeof(real_t));
+            }
+
+            if (hDecoder->sbr[i]->id_aac == ID_CPE)
+            {
+                /* space for 2 channels needed */
+                if (hDecoder->time_out2[ch+1] == NULL)
+                {
+                    hDecoder->time_out2[ch+1] = (real_t*)malloc(hDecoder->frameLength*2*sizeof(real_t));
+                    memset(hDecoder->time_out2[ch+1], 0, hDecoder->frameLength*2*sizeof(real_t));
+                }
+
+                memcpy(time_out2[ch],
+                    time_out[ch], frame_len*sizeof(real_t));
+                memcpy(time_out2[ch+1],
+                    time_out[ch+1], frame_len*sizeof(real_t));
                 sbrDecodeFrame(hDecoder->sbr[i],
-                    time_out2[syntax_elements[i]->channel],
-                    time_out2[syntax_elements[i]->paired_channel], ID_CPE,
+                    time_out2[ch], time_out2[ch+1],
                     hDecoder->postSeekResetFlag, hDecoder->forceUpSampling);
+                ch += 2;
             } else {
-                memcpy(time_out2[syntax_elements[i]->channel],
-                    time_out[syntax_elements[i]->channel], frame_len*sizeof(real_t));
+                memcpy(time_out2[ch],
+                    time_out[ch], frame_len*sizeof(real_t));
                 sbrDecodeFrame(hDecoder->sbr[i],
-                    time_out2[syntax_elements[i]->channel],
-                    NULL, ID_SCE,
+                    time_out2[ch], NULL,
                     hDecoder->postSeekResetFlag, hDecoder->forceUpSampling);
+                ch++;
             }
         }
         frame_len *= 2;
@@ -1181,16 +1006,6 @@
 #endif
 
     /* cleanup */
-    for (ch = 0; ch < channels; ch++)
-    {
-        if (spec_coef[ch]) free(spec_coef[ch]);
-    }
-
-    for (i = 0; i < ch_ele; i++)
-    {
-        if (syntax_elements[i]) free(syntax_elements[i]);
-    }
-
 #ifdef ANALYSIS
     fflush(stdout);
 #endif
@@ -1203,16 +1018,6 @@
     if (ld) free(ld);
 
     /* cleanup */
-    for (ch = 0; ch < channels; ch++)
-    {
-        if (spec_coef[ch]) free(spec_coef[ch]);
-    }
-
-    for (i = 0; i < ch_ele; i++)
-    {
-        if (syntax_elements[i]) free(syntax_elements[i]);
-    }
-
 #ifdef ANALYSIS
     fflush(stdout);
 #endif
--- a/libfaad/decoder.h
+++ b/libfaad/decoder.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: decoder.h,v 1.28 2003/09/24 08:05:44 menno Exp $
+** $Id: decoder.h,v 1.29 2003/10/09 20:04:24 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -117,16 +117,6 @@
                             faacDecFrameInfo *hInfo,
                             uint8_t *buffer,
                             uint32_t buffer_size);
-
-element *decode_sce_lfe(faacDecHandle hDecoder,
-                        faacDecFrameInfo *hInfo, bitfile *ld,
-                        real_t **spec_coef, uint8_t id_syn_ele);
-element *decode_cpe(faacDecHandle hDecoder,
-                    faacDecFrameInfo *hInfo, bitfile *ld,
-                    real_t **spec_coef, uint8_t id_syn_ele);
-element **raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
-                         bitfile *ld, element **elements,
-                         real_t **spec_coef, program_config *pce, drc_info *drc);
 
 #ifdef _WIN32
   #pragma pack(pop)
--- a/libfaad/fixed.h
+++ b/libfaad/fixed.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: fixed.h,v 1.10 2003/09/09 18:09:51 menno Exp $
+** $Id: fixed.h,v 1.11 2003/10/09 20:04:24 menno Exp $
 **/
 
 #ifndef __FIXED_H__
@@ -93,6 +93,30 @@
         or eax,edx
 #endif
     }
+}
+
+#elif 0 //defined(_WIN32_WCE) && defined(ARM)
+
+/* multiply real with real */
+static INLINE MUL(real_t A, real_t B)
+{
+    __emit(0xe0c23190); // smull  r3, r2, r0, r1
+    __emit(0xe1b03723); // movs   r3, r3, lsr #14
+    __emit(0xe0a30902); // adc    r0, r3, r2, lsl #18
+}
+/* multiply coef with coef */
+static INLINE MUL_C_C(real_t A, real_t B)
+{
+    __emit(0xe0c23190); // smull  r3, r2, r0, r1
+    __emit(0xe1b03e23); // movs   r3, r3, lsr #28
+    __emit(0xe0a30202); // adc    r0, r3, r2, lsl #4
+}
+/* multiply real with coef */
+static INLINE MUL_R_C(real_t A, real_t B)
+{
+    __emit(0xe0c23190); // smull  r3, r2, r0, r1
+    __emit(0xe1b03e23); // movs   r3, r3, lsr #28
+    __emit(0xe0a30202); // adc    r0, r3, r2, lsl #4
 }
 
 #elif defined(__GNUC__) && defined (__arm__)
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: lt_predict.c,v 1.12 2003/09/09 18:09:52 menno Exp $
+** $Id: lt_predict.c,v 1.13 2003/10/09 20:04:24 menno Exp $
 **/
 
 
@@ -36,6 +36,26 @@
 #include "lt_predict.h"
 #include "filtbank.h"
 #include "tns.h"
+
+/* check if the object type is an object type that can have LTP */
+uint8_t is_ltp_ot(uint8_t object_type)
+{
+#ifdef LTP_DEC
+    if ((object_type == LTP)
+#ifdef ERROR_RESILIENCE
+        || (object_type == ER_LTP)
+#endif
+#ifdef LD_DEC
+        || (object_type == LD)
+#endif
+        )
+    {
+        return 1;
+    }
+#endif
+
+    return 0;
+}
 
 static real_t codebook[8] =
 {
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: lt_predict.h,v 1.6 2003/09/09 18:09:52 menno Exp $
+** $Id: lt_predict.h,v 1.7 2003/10/09 20:04:24 menno Exp $
 **/
 
 #ifdef LTP_DEC
@@ -35,6 +35,8 @@
 #endif
 
 #include "filtbank.h"
+
+uint8_t is_ltp_ot(uint8_t object_type);
 
 void lt_prediction(ic_stream *ics,
                    ltp_info *ltp,
--- a/libfaad/mp4.c
+++ b/libfaad/mp4.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4.c,v 1.19 2003/09/18 13:38:38 menno Exp $
+** $Id: mp4.c,v 1.24 2003/11/12 20:47:58 menno Exp $
 **/
 
 #include "common.h"
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: output.c,v 1.21 2003/09/09 18:09:52 menno Exp $
+** $Id: output.c,v 1.22 2003/10/09 20:04:25 menno Exp $
 **/
 
 #include "common.h"
@@ -55,20 +55,18 @@
 static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample,
                                 uint8_t downMatrix, uint8_t *internal_channel)
 {
-    if (downMatrix)
+    if (!downMatrix)
+        return input[internal_channel[channel]][sample];
+
+    if (channel == 0)
     {
-        if (channel == 0)
-        {
-            return DM_MUL * (input[internal_channel[1]][sample] +
-                input[internal_channel[0]][sample]/(real_t)sqrt(2.) +
-                input[internal_channel[3]][sample]/(real_t)sqrt(2.));
-        } else {
-            return DM_MUL * (input[internal_channel[2]][sample] +
-                input[internal_channel[0]][sample]/(real_t)sqrt(2.) +
-                input[internal_channel[4]][sample]/(real_t)sqrt(2.));
-        }
+        return DM_MUL * (input[internal_channel[1]][sample] +
+            input[internal_channel[0]][sample]/(real_t)sqrt(2.) +
+            input[internal_channel[3]][sample]/(real_t)sqrt(2.));
     } else {
-        return input[internal_channel[channel]][sample];
+        return DM_MUL * (input[internal_channel[2]][sample] +
+            input[internal_channel[0]][sample]/(real_t)sqrt(2.) +
+            input[internal_channel[4]][sample]/(real_t)sqrt(2.));
     }
 }
 
--- a/libfaad/sbr_dct.c
+++ b/libfaad/sbr_dct.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_dct.c,v 1.4 2003/09/24 11:52:12 menno Exp $
+** $Id: sbr_dct.c,v 1.5 2003/10/09 20:04:25 menno Exp $
 **/
 
 #include "common.h"
@@ -1099,6 +1099,21 @@
 void DCT4_64(real_t *y, real_t *x)
 {
     int16_t i0;
+    static real_t t2[64];
+
+    t2[0] = x[0];
+    for (i0=0; i0<31; i0++)
+    {
+        t2[2*i0+1] = x[2*i0+1] - x[2*i0+2];
+        t2[2*i0+2] = x[2*i0+1] + x[2*i0+2];
+    }
+    t2[63] = x[63];
+
+    DCT4_64_kernel(y, t2);
+}
+
+void DCT4_64_kernel(real_t *y, real_t *t2)
+{
     real_t f2;
     real_t f3;
     real_t f4;
@@ -1837,18 +1852,10 @@
     real_t f799;
     real_t f800;
     real_t f801;
-    static real_t t2[64];
 
-    t2[0] = x[0];
-    for (i0=0; i0<31; i0++)
-    {
-        t2[2*i0+1] = x[2*i0+1] - x[2*i0+2];
-        t2[2*i0+2] = x[2*i0+1] + x[2*i0+2];
-    }
-    t2[63] = x[63];
     f2 = 0.7071067811865476 * t2[32];
-    f3 = x[0] - f2;
-    f4 = x[0] + f2;
+    f3 = t2[0] - f2;
+    f4 = t2[0] + f2;
     f5 = t2[16] + t2[48];
     f6 = 1.3065629648763766 * t2[16];
     f7 = (-0.9238795325112866) * f5;
@@ -2312,8 +2319,8 @@
     f465 = 0.7071067811865474 * f463;
     f466 = 0.7071067811865474 * f464;
     f467 = 0.7071067811865476 * t2[31];
-    f468 = x[63] - f467;
-    f469 = x[63] + f467;
+    f468 = t2[63] - f467;
+    f469 = t2[63] + f467;
     f470 = t2[47] + t2[15];
     f471 = 1.3065629648763766 * t2[47];
     f472 = (-0.9238795325112866) * f470;
--- a/libfaad/sbr_dct.h
+++ b/libfaad/sbr_dct.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_dct.h,v 1.3 2003/09/24 11:52:12 menno Exp $
+** $Id: sbr_dct.h,v 1.4 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SBR_DCT_H__
@@ -35,6 +35,7 @@
 void DCT3_32_unscaled(real_t *y, real_t *x);
 void DCT2_64_unscaled(real_t *y, real_t *x);
 void DCT4_64(real_t *y, real_t *x);
+void DCT4_64_kernel(real_t *y, real_t *t2);
 
 
 #ifdef __cplusplus
--- a/libfaad/sbr_dec.c
+++ b/libfaad/sbr_dec.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_dec.c,v 1.12 2003/09/25 12:04:31 menno Exp $
+** $Id: sbr_dec.c,v 1.13 2003/10/09 20:04:25 menno Exp $
 **/
 
 
@@ -111,10 +111,10 @@
             qmfs_end(sbr->qmfs[1]);
         }
 
-        if (sbr->Xcodec[0]) free(sbr->Xcodec[0]);
-        if (sbr->Xsbr[0]) free(sbr->Xsbr[0]);
-        if (sbr->Xcodec[1]) free(sbr->Xcodec[1]);
-        if (sbr->Xsbr[1]) free(sbr->Xsbr[1]);
+        //if (sbr->Xcodec[0]) free(sbr->Xcodec[0]);
+        //if (sbr->Xsbr[0]) free(sbr->Xsbr[0]);
+        //if (sbr->Xcodec[1]) free(sbr->Xcodec[1]);
+        //if (sbr->Xsbr[1]) free(sbr->Xsbr[1]);
 
         for (j = 0; j < 5; j++)
         {
@@ -157,7 +157,7 @@
 }
 
 void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
-                    real_t *right_channel, uint8_t id_aac,
+                    real_t *right_channel,
                     uint8_t just_seeked, uint8_t upsample_only)
 {
     int16_t i, k, l;
@@ -166,7 +166,7 @@
     uint8_t ch, channels, ret;
     real_t *ch_buf;
 
-    qmf_t X[32*64];
+    qmf_t X[32][64];
 #ifdef SBR_LOW_POWER
     real_t deg[64];
 #endif
@@ -173,8 +173,7 @@
 
     bitfile *ld = NULL;
 
-    sbr->id_aac = id_aac;
-    channels = (id_aac == ID_SCE) ? 1 : 2;
+    channels = (sbr->id_aac == ID_SCE) ? 1 : 2;
 
     if (sbr->data == NULL || sbr->data_size == 0)
     {
@@ -185,7 +184,7 @@
         /* initialise and read the bitstream */
         faad_initbits(ld, sbr->data, sbr->data_size);
 
-        ret = sbr_extension_data(ld, sbr, id_aac);
+        ret = sbr_extension_data(ld, sbr, sbr->id_aac);
 
         ret = ld->error ? ld->error : ret;
         faad_endbits(ld);
@@ -227,9 +226,6 @@
                 sbr->Q_temp_prev[ch][j] = malloc(64*sizeof(real_t));
             }
 
-            sbr->Xsbr[ch] = malloc((sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t));
-            sbr->Xcodec[ch] = malloc((sbr->numTimeSlotsRate+sbr->tHFGen)*32 * sizeof(qmf_t));
-
             memset(sbr->Xsbr[ch], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t));
             memset(sbr->Xcodec[ch], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*32 * sizeof(qmf_t));
         }
@@ -239,20 +235,6 @@
         else
             ch_buf = right_channel;
 
-#if 0
-        for (i = 0; i < sbr->tHFAdj; i++)
-        {
-            int8_t j;
-            for (j = sbr->kx_prev; j < sbr->kx; j++)
-            {
-                QMF_RE(sbr->Xcodec[ch][i*32 + j]) = 0;
-#ifndef SBR_LOW_POWER
-                QMF_IM(sbr->Xcodec[ch][i*32 + j]) = 0;
-#endif
-            }
-        }
-#endif
-
         /* subband analysis */
         if (dont_process)
             sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], ch_buf, sbr->Xcodec[ch], sbr->tHFGen, 32);
@@ -274,7 +256,7 @@
             {
                 for (k = 0; k < sbr->kx; k++)
                 {
-                    QMF_RE(sbr->Xsbr[ch][(sbr->tHFAdj + l)*64 + k]) = 0;
+                    QMF_RE(sbr->Xsbr[ch][sbr->tHFAdj + l][k]) = 0;
                 }
             }
 #endif
@@ -295,16 +277,16 @@
             {
                 for (k = 0; k < 32; k++)
                 {
-                    QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+                    QMF_RE(X[l][k]) = QMF_RE(sbr->Xcodec[ch][l + sbr->tHFAdj][k]);
 #ifndef SBR_LOW_POWER
-                    QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+                    QMF_IM(X[l][k]) = QMF_IM(sbr->Xcodec[ch][l + sbr->tHFAdj][k]);
 #endif
                 }
                 for (k = 32; k < 64; k++)
                 {
-                    QMF_RE(X[l * 64 + k]) = 0;
+                    QMF_RE(X[l][k]) = 0;
 #ifndef SBR_LOW_POWER
-                    QMF_IM(X[l * 64 + k]) = 0;
+                    QMF_IM(X[l][k]) = 0;
 #endif
                 }
             }
@@ -325,20 +307,20 @@
 
                 for (k = 0; k < xover_band; k++)
                 {
-                    QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+                    QMF_RE(X[l][k]) = QMF_RE(sbr->Xcodec[ch][l + sbr->tHFAdj][k]);
 #ifndef SBR_LOW_POWER
-                    QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+                    QMF_IM(X[l][k]) = QMF_IM(sbr->Xcodec[ch][l + sbr->tHFAdj][k]);
 #endif
                 }
                 for (k = xover_band; k < 64; k++)
                 {
-                    QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xsbr[ch][(l + sbr->tHFAdj)*64 + k]);
+                    QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]);
 #ifndef SBR_LOW_POWER
-                    QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xsbr[ch][(l + sbr->tHFAdj)*64 + k]);
+                    QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]);
 #endif
                 }
 #ifdef SBR_LOW_POWER
-                QMF_RE(X[l * 64 + xover_band - 1]) += QMF_RE(sbr->Xsbr[ch][(l + sbr->tHFAdj)*64 + xover_band - 1]);
+                QMF_RE(X[l][xover_band - 1]) += QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][xover_band - 1]);
 #endif
 #ifdef DRM
                 if (sbr->Is_DRM_SBR)
@@ -345,8 +327,8 @@
                 {
                     for (k = xover_band; k < xover_band + 4; k++)
                     {
-                        QMF_RE(X[l * 64 + k]) += QMF_RE(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
-                        QMF_IM(X[l * 64 + k]) += QMF_IM(sbr->Xcodec[ch][(l + sbr->tHFAdj)*32 + k]);
+                        QMF_RE(X[l][k]) += QMF_RE(sbr->Xcodec[ch][l + sbr->tHFAdj][k]);
+                        QMF_IM(X[l][k]) += QMF_IM(sbr->Xcodec[ch][l + sbr->tHFAdj][k]);
                     }
                 }
 #endif
@@ -354,29 +336,12 @@
         }
 
         /* subband synthesis */
-        sbr_qmf_synthesis_64(sbr, sbr->qmfs[ch], (const complex_t*)X, ch_buf);
+        sbr_qmf_synthesis_64(sbr, sbr->qmfs[ch], X, ch_buf);
 
-        for (i = 0; i < 32; i++)
+        for (i = 0; i < sbr->tHFGen; i++)
         {
-            int8_t j;
-            for (j = 0; j < sbr->tHFGen; j++)
-            {
-                QMF_RE(sbr->Xcodec[ch][j*32 + i]) = QMF_RE(sbr->Xcodec[ch][(j+sbr->numTimeSlotsRate)*32 + i]);
-#ifndef SBR_LOW_POWER
-                QMF_IM(sbr->Xcodec[ch][j*32 + i]) = QMF_IM(sbr->Xcodec[ch][(j+sbr->numTimeSlotsRate)*32 + i]);
-#endif
-            }
-        }
-        for (i = 0; i < 64; i++)
-        {
-            int8_t j;
-            for (j = 0; j < sbr->tHFGen; j++)
-            {
-                QMF_RE(sbr->Xsbr[ch][j*64 + i]) = QMF_RE(sbr->Xsbr[ch][(j+sbr->numTimeSlotsRate)*64 + i]);
-#ifndef SBR_LOW_POWER
-                QMF_IM(sbr->Xsbr[ch][j*64 + i]) = QMF_IM(sbr->Xsbr[ch][(j+sbr->numTimeSlotsRate)*64 + i]);
-#endif
-            }
+            memmove(sbr->Xcodec[ch][i], sbr->Xcodec[ch][i+sbr->numTimeSlotsRate], 32 * sizeof(qmf_t));
+            memmove(sbr->Xsbr[ch][i], sbr->Xsbr[ch][i+sbr->numTimeSlotsRate], 64 * sizeof(qmf_t));
         }
     }
 
--- a/libfaad/sbr_dec.h
+++ b/libfaad/sbr_dec.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_dec.h,v 1.7 2003/09/25 12:04:31 menno Exp $
+** $Id: sbr_dec.h,v 1.8 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SBR_DEC_H__
@@ -138,8 +138,8 @@
     qmfa_info *qmfa[2];
     qmfs_info *qmfs[2];
 
-    qmf_t *Xsbr[2];
-    qmf_t *Xcodec[2];
+    qmf_t Xsbr[2][40][64];
+    qmf_t Xcodec[2][40][32];
 
 #ifdef DRM
 	int8_t lcstereo_flag;
@@ -200,7 +200,7 @@
 void sbrDecodeEnd(sbr_info *sbr);
 
 void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
-                    real_t *right_channel, uint8_t id_aac,
+                    real_t *right_channel,
                     uint8_t just_seeked, uint8_t upsample_only);
 
 
--- a/libfaad/sbr_e_nf.c
+++ b/libfaad/sbr_e_nf.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_e_nf.c,v 1.4 2003/09/09 18:37:32 menno Exp $
+** $Id: sbr_e_nf.c,v 1.5 2003/10/09 20:04:25 menno Exp $
 **/
 
 #include "common.h"
@@ -186,6 +186,12 @@
             r_temp = (real_t)pow(2, sbr->E[1][k][l]*amp1 - 12);
 
             sbr->E_orig[1][k][l] = l_temp / ((real_t)1.0 + r_temp);
+
+            /*
+               E_orig[1]: integer
+               r_temp: fixed point
+               fixed point multiplication gives integer
+             */
             sbr->E_orig[0][k][l] = MUL(r_temp, sbr->E_orig[1][k][l]);
         }
     }
--- a/libfaad/sbr_fbt.c
+++ b/libfaad/sbr_fbt.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_fbt.c,v 1.3 2003/09/09 18:37:32 menno Exp $
+** $Id: sbr_fbt.c,v 1.4 2003/10/09 20:04:25 menno Exp $
 **/
 
 /* Calculate frequency band tables */
@@ -187,10 +187,8 @@
     uint8_t k;
     uint8_t dk;
     uint32_t nrBands, k2Achieved;
-    int32_t k2Diff, vDk[64];
+    int32_t k2Diff, vDk[64] = {0};
 
-    memset(vDk, 0, 64*sizeof(int32_t));
-
     /* mft only defined for k2 > k0 */
     if (k2 <= k0)
     {
@@ -247,7 +245,6 @@
 #endif
 }
 
-
 /*
    This function finds the number of bands using this formula:
     bands * log(a1/a0)/log(2.0) + 0.5
@@ -260,6 +257,10 @@
     return (int32_t)(bands * log((float)a1/(float)a0)/div + 0.5);
 }
 
+static real_t find_initial_power(uint8_t bands, uint8_t a0, uint8_t a1)
+{
+    return pow((real_t)a1/(real_t)a0, 1.0/(real_t)bands);
+}
 
 /*
    version for bs_freq_scale > 0
@@ -269,18 +270,13 @@
 {
     uint8_t k, bands, twoRegions;
     uint8_t k1;
-    uint32_t nrBand0, nrBand1;
-    int32_t vDk0[64], vDk1[64];
-    int32_t vk0[64], vk1[64];
+    uint8_t nrBand0, nrBand1;
+    int32_t vDk0[64] = {0}, vDk1[64] = {0};
+    int32_t vk0[64] = {0}, vk1[64] = {0};
     uint8_t temp1[] = { 6, 5, 4 };
+    real_t q, qk;
+    int32_t A_1;
 
-    /* without memset code enters infinite loop,
-       so there must be some wrong table access */
-    memset(vDk0, 0, 64*sizeof(int32_t));
-    memset(vDk1, 0, 64*sizeof(int32_t));
-    memset(vk0, 0, 64*sizeof(int32_t));
-    memset(vk1, 0, 64*sizeof(int32_t));
-
     /* mft only defined for k2 > k0 */
     if (k2 <= k0)
     {
@@ -302,11 +298,15 @@
     nrBand0 = 2 * find_bands(0, bands, k0, k1);
     nrBand0 = min(nrBand0, 63);
 
+    q = find_initial_power(nrBand0, k0, k1);
+    qk = REAL_CONST(k0);
+    A_1 = (int32_t)(qk + .5);
     for (k = 0; k <= nrBand0; k++)
     {
-        /* diverging power series */
-        vDk0[k] = (int32_t)(k0 * pow((float)k1/(float)k0, (k+1)/(float)nrBand0)+0.5) -
-            (int32_t)(k0 * pow((float)k1/(float)k0, k/(float)nrBand0)+0.5);
+        int32_t A_0 = A_1;
+        qk *= q;
+        A_1 = (int32_t)(qk + 0.5);
+        vDk0[k] = A_1 - A_0;
     }
 
     /* needed? */
@@ -331,10 +331,15 @@
     nrBand1 = 2 * find_bands(1 /* warped */, bands, k1, k2);
     nrBand1 = min(nrBand1, 63);
 
+    q = find_initial_power(nrBand1, k1, k2);
+    qk = REAL_CONST(k1);
+    A_1 = (int32_t)(qk + .5);
     for (k = 0; k <= nrBand1 - 1; k++)
     {
-        vDk1[k] = (int32_t)(k1 * pow((float)k2/(float)k1, (k+1)/(float)nrBand1)+0.5) -
-            (int32_t)(k1 * pow((float)k2/(float)k1, k/(float)nrBand1)+0.5);
+        int32_t A_0 = A_1;
+        qk *= q;
+        A_1 = (int32_t)(qk + 0.5);
+        vDk1[k] = A_1 - A_0;
     }
 
     if (vDk1[0] < vDk0[nrBand0 - 1])
@@ -448,8 +453,8 @@
         if (k == 0)
         {
             i = 0;
-        } else { /* is this accurate? */
-            //i = i + (int32_t)((sbr->N_low - i)/(sbr->N_Q + 1 - k));
+        } else {
+            /* i = i + (int32_t)((sbr->N_low - i)/(sbr->N_Q + 1 - k)); */
             i = i + (sbr->N_low - i)/(sbr->N_Q + 1 - k);
         }
         sbr->f_table_noise[k] = sbr->f_table_res[LO_RES][i];
@@ -498,8 +503,6 @@
 #endif
     uint8_t k, s;
     int8_t nrLim;
-    int32_t limTable[100 /*TODO*/];
-    uint8_t patchBorders[64/*??*/];
 #if 0
     real_t limBands;
 #endif
@@ -510,7 +513,8 @@
 
     for (s = 1; s < 4; s++)
     {
-        memset(limTable, 0, 100*sizeof(int32_t));
+        int32_t limTable[100 /*TODO*/] = {0};
+        uint8_t patchBorders[64/*??*/] = {0};
 
 #if 0
         limBands = limiterBandsPerOctave[s - 1];
--- a/libfaad/sbr_hfadj.c
+++ b/libfaad/sbr_hfadj.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_hfadj.c,v 1.4 2003/09/09 18:37:32 menno Exp $
+** $Id: sbr_hfadj.c,v 1.5 2003/10/09 20:04:25 menno Exp $
 **/
 
 /* High Frequency adjustment */
@@ -37,16 +37,14 @@
 
 #include "sbr_noise.h"
 
-void hf_adjustment(sbr_info *sbr, qmf_t *Xsbr
+void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[40][64]
 #ifdef SBR_LOW_POWER
                    ,real_t *deg /* aliasing degree */
 #endif
                    ,uint8_t ch)
 {
-    sbr_hfadj_info adj;
+    sbr_hfadj_info adj = {0};
 
-    memset(&adj, 0, sizeof(sbr_hfadj_info));
-
     map_noise_data(sbr, &adj, ch);
     map_sinusoids(sbr, &adj, ch);
 
@@ -188,7 +186,7 @@
     }
 }
 
-static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr,
+static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[40][64],
                                       uint8_t ch)
 {
     uint8_t m, l, j, k, k_l, k_h, p;
@@ -211,9 +209,9 @@
 
                 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
                 {
-                    nrg += MUL(QMF_RE(Xsbr[(i<<6) + m + sbr->kx]), QMF_RE(Xsbr[(i<<6) + m + sbr->kx]))
+                    nrg += MUL(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx]))
 #ifndef SBR_LOW_POWER
-                        + MUL(QMF_IM(Xsbr[(i<<6) + m + sbr->kx]), QMF_IM(Xsbr[(i<<6) + m + sbr->kx]))
+                        + MUL(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx]))
 #endif
                         ;
                 }
@@ -246,9 +244,9 @@
                     {
                         for (j = k_l; j < k_h; j++)
                         {
-                            nrg += MUL(QMF_RE(Xsbr[(i<<6) + j]), QMF_RE(Xsbr[(i<<6) + j]))
+                            nrg += MUL(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j]))
 #ifndef SBR_LOW_POWER
-                                + MUL(QMF_IM(Xsbr[(i<<6) + j]), QMF_IM(Xsbr[(i<<6) + j]))
+                                + MUL(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j]))
 #endif
                                 ;
                         }
@@ -264,6 +262,7 @@
     }
 }
 
+
 #define EPS (1e-12)
 
 #define ONE (1)
@@ -497,7 +496,7 @@
 #endif
 
 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
-                        qmf_t *Xsbr, uint8_t ch)
+                        qmf_t Xsbr[40][64], uint8_t ch)
 {
     static real_t h_smooth[] = {
         COEF_CONST(0.03183050093751), COEF_CONST(0.11516383427084),
@@ -590,12 +589,12 @@
 
                 /* the smoothed gain values are applied to Xsbr */
                 /* V is defined, not calculated */
-                QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]))
+                QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
                     + MUL_R_C(Q_filt, RE(V[fIndexNoise]));
                 if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42)
-                    QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) = 16428320;
+                    QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320;
 #ifndef SBR_LOW_POWER
-                QMF_IM(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_IM(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]))
+                QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
                     + MUL_R_C(Q_filt, IM(V[fIndexNoise]));
 #endif
 
@@ -604,11 +603,11 @@
                 {
                     int8_t rev = ((m + sbr->kx) & 1) ? -1 : 1;
                     QMF_RE(psi) = MUL(adj->S_M_boost[l][m], phi_re[fIndexSine]);
-                    QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) += QMF_RE(psi);
+                    QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi);
 
 #ifndef SBR_LOW_POWER
                     QMF_IM(psi) = rev * MUL(adj->S_M_boost[l][m], phi_im[fIndexSine]);
-                    QMF_IM(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) += QMF_IM(psi);
+                    QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi);
 #else
                     i_min1 = (fIndexSine - 1) & 3;
                     i_plus1 = (fIndexSine + 1) & 3;
@@ -615,23 +614,23 @@
 
                     if (m == 0)
                     {
-                        QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx - 1]) -=
+                        QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) -=
                             (rev * MUL_R_C(MUL(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815)));
-                        QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
+                        QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
                             (rev * MUL_R_C(MUL(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815)));
                     }
                     if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16))
                     {
-                        QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
+                        QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
                             (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
-                        QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
+                        QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
                             (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815)));
                     }
                     if ((m == sbr->M - 1) && (sinusoids < 16) && (m + sbr->kx + 1 < 63))
                     {
-                        QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
+                        QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
                             (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
-                        QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx + 1]) -=
+                        QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) -=
                             (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_min1]), COEF_CONST(0.00815)));
                     }
 
--- a/libfaad/sbr_hfadj.h
+++ b/libfaad/sbr_hfadj.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_hfadj.h,v 1.2 2003/09/09 18:09:52 menno Exp $
+** $Id: sbr_hfadj.h,v 1.3 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SBR_HFADJ_H__
@@ -46,7 +46,7 @@
 } sbr_hfadj_info;
 
 
-void hf_adjustment(sbr_info *sbr, qmf_t *Xsbr
+void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[40][64]
 #ifdef SBR_LOW_POWER
                    ,real_t *deg
 #endif
@@ -56,7 +56,7 @@
 static void map_envelope_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
 static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
 static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
-static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr,
+static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[40][64],
                                       uint8_t ch);
 static void additional_component_levels(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
@@ -64,7 +64,7 @@
 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
 #endif
-static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr, uint8_t ch);
+static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[40][64], uint8_t ch);
 
 
 #ifdef __cplusplus
--- a/libfaad/sbr_hfgen.c
+++ b/libfaad/sbr_hfgen.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_hfgen.c,v 1.6 2003/09/25 12:04:31 menno Exp $
+** $Id: sbr_hfgen.c,v 1.7 2003/10/09 20:04:25 menno Exp $
 **/
 
 /* High Frequency generation */
@@ -36,8 +36,8 @@
 #include "sbr_hfgen.h"
 #include "sbr_fbt.h"
 
-void hf_generation(sbr_info *sbr, const qmf_t *Xlow,
-                   qmf_t *Xhigh
+void hf_generation(sbr_info *sbr, const qmf_t Xlow[40][32],
+                   qmf_t Xhigh[40][64]
 #ifdef SBR_LOW_POWER
                    ,real_t *deg
 #endif
@@ -123,34 +123,34 @@
 
 				for (l = first; l < last; l++)
                 {
-                    QMF_RE(Xhigh[((l + offset)<<6) + k]) = QMF_RE(Xlow[((l + offset)<<5) + p]);
+                    QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]);
 #ifndef SBR_LOW_POWER
-                    QMF_IM(Xhigh[((l + offset)<<6) + k]) = QMF_IM(Xlow[((l + offset)<<5) + p]);
+                    QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]);
 #endif
 
 #ifdef SBR_LOW_POWER
-                    QMF_RE(Xhigh[((l + offset)<<6) + k]) += (
-                        MUL(RE(a0), QMF_RE(Xlow[((l - 1 + offset)<<5) + p])) +
-                        MUL(RE(a1), QMF_RE(Xlow[((l - 2 + offset)<<5) + p])));
+                    QMF_RE(Xhigh[l + offset][k]) += (
+                        MUL(RE(a0), QMF_RE(Xlow[l - 1 + offset][p])) +
+                        MUL(RE(a1), QMF_RE(Xlow[l - 2 + offset][p])));
 #else
-                    QMF_RE(Xhigh[((l + offset)<<6) + k]) += (
-                        RE(a0) * QMF_RE(Xlow[((l - 1 + offset)<<5) + p]) -
-                        IM(a0) * QMF_IM(Xlow[((l - 1 + offset)<<5) + p]) +
-                        RE(a1) * QMF_RE(Xlow[((l - 2 + offset)<<5) + p]) -
-                        IM(a1) * QMF_IM(Xlow[((l - 2 + offset)<<5) + p]));
-                    QMF_IM(Xhigh[((l + offset)<<6) + k]) += (
-                        IM(a0) * QMF_RE(Xlow[((l - 1 + offset)<<5) + p]) +
-                        RE(a0) * QMF_IM(Xlow[((l - 1 + offset)<<5) + p]) +
-                        IM(a1) * QMF_RE(Xlow[((l - 2 + offset)<<5) + p]) +
-                        RE(a1) * QMF_IM(Xlow[((l - 2 + offset)<<5) + p]));
+                    QMF_RE(Xhigh[l + offset][k]) += (
+                        RE(a0) * QMF_RE(Xlow[l - 1 + offset][p]) -
+                        IM(a0) * QMF_IM(Xlow[l - 1 + offset][p]) +
+                        RE(a1) * QMF_RE(Xlow[l - 2 + offset][p]) -
+                        IM(a1) * QMF_IM(Xlow[l - 2 + offset][p]));
+                    QMF_IM(Xhigh[l + offset][k]) += (
+                        IM(a0) * QMF_RE(Xlow[l - 1 + offset][p]) +
+                        RE(a0) * QMF_IM(Xlow[l - 1 + offset][p]) +
+                        IM(a1) * QMF_RE(Xlow[l - 2 + offset][p]) +
+                        RE(a1) * QMF_IM(Xlow[l - 2 + offset][p]));
 #endif
                 }
             } else {
                 for (l = first; l < last; l++)
                 {
-                    QMF_RE(Xhigh[((l + offset)<<6) + k]) = QMF_RE(Xlow[((l + offset)<<5) + p]);
+                    QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]);
 #ifndef SBR_LOW_POWER
-                    QMF_IM(Xhigh[((l + offset)<<6) + k]) = QMF_IM(Xlow[((l + offset)<<5) + p]);
+                    QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]);
 #endif
                 }
             }
@@ -176,12 +176,12 @@
 #define SBR_ABS(A) ((A) < 0) ? -(A) : (A)
 
 #ifdef SBR_LOW_POWER
-static void auto_correlation(sbr_info *sbr, acorr_coef *ac, const qmf_t *buffer,
+static void auto_correlation(sbr_info *sbr, acorr_coef *ac, const qmf_t buffer[40][32],
                              uint8_t bd, uint8_t len)
 {
-    int8_t j, jminus1, jminus2;
+    int8_t j;
     uint8_t offset;
-    real_t r01, i01, r11;
+    real_t r01, r11;
     const real_t rel = 1 / (1 + 1e-6f);
 
 #ifdef DRM
@@ -195,20 +195,17 @@
 
     memset(ac, 0, sizeof(acorr_coef));
 
-    r01 = QMF_RE(buffer[(offset-1)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]);
-    r11 = QMF_RE(buffer[(offset-2)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]);
+    r01 = QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]);
+    r11 = QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]);
 
     for (j = offset; j < len + offset; j++)
     {
-        jminus1 = j - 1;
-        jminus2 = j - 2;
-
         RE(ac->r12) += r01;
-        r01 = QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
+        r01 = QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]);
         RE(ac->r01) += r01;
-        RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
+        RE(ac->r02) += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]);
         RE(ac->r22) += r11;
-        r11 = QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
+        r11 = QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]);
         RE(ac->r11) += r11;
     }
 
@@ -215,10 +212,10 @@
     ac->det = MUL(RE(ac->r11), RE(ac->r22)) - MUL_R_C(MUL(RE(ac->r12), RE(ac->r12)), rel);
 }
 #else
-static void auto_correlation(sbr_info *sbr, acorr_coef *ac, const qmf_t *buffer,
+static void auto_correlation(sbr_info *sbr, acorr_coef *ac, const qmf_t buffer[40][32],
                              uint8_t bd, uint8_t len)
 {
-    int8_t j, jminus1, jminus2;
+    int8_t j;
     uint8_t offset;
     real_t r01, i01, r11;
     const real_t rel = 1 / (1 + 1e-6f);
@@ -234,33 +231,30 @@
 
     memset(ac, 0, sizeof(acorr_coef));
 
-    r01 = QMF_RE(buffer[(offset-1)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]) +
-        QMF_IM(buffer[(offset-1)*32 + bd]) * QMF_IM(buffer[(offset-2)*32 + bd]);
-    i01 = QMF_IM(buffer[(offset-1)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]) -
-        QMF_RE(buffer[(offset-1)*32 + bd]) * QMF_IM(buffer[(offset-2)*32 + bd]);
-    r11 = QMF_RE(buffer[(offset-2)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]) +
-        QMF_IM(buffer[(offset-2)*32 + bd]) * QMF_IM(buffer[(offset-2)*32 + bd]);
+    r01 = QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]) +
+        QMF_IM(buffer[offset-1][bd]) * QMF_IM(buffer[offset-2][bd]);
+    i01 = QMF_IM(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]) -
+        QMF_RE(buffer[offset-1][bd]) * QMF_IM(buffer[offset-2][bd]);
+    r11 = QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]) +
+        QMF_IM(buffer[offset-2][bd]) * QMF_IM(buffer[offset-2][bd]);
 
     for (j = offset; j < len + offset; j++)
     {
-        jminus1 = j - 1;
-        jminus2 = j - 2;
-
         RE(ac->r12) += r01;
         IM(ac->r12) += i01;
-        r01 = QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
-            QMF_IM(buffer[j*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);
+        r01 = QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]) +
+            QMF_IM(buffer[j][bd]) * QMF_IM(buffer[j-1][bd]);
         RE(ac->r01) += r01;
-        i01 = QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) -
-            QMF_RE(buffer[j*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);
+        i01 = QMF_IM(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]) -
+            QMF_RE(buffer[j][bd]) * QMF_IM(buffer[j-1][bd]);
         IM(ac->r01) += i01;
-        RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
-            QMF_IM(buffer[j*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
-        IM(ac->r02) += QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) -
-            QMF_RE(buffer[j*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
+        RE(ac->r02) += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]) +
+            QMF_IM(buffer[j][bd]) * QMF_IM(buffer[j-2][bd]);
+        IM(ac->r02) += QMF_IM(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]) -
+            QMF_RE(buffer[j][bd]) * QMF_IM(buffer[j-2][bd]);
         RE(ac->r22) += r11;
-        r11 = QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
-            QMF_IM(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);
+        r11 = QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]) +
+            QMF_IM(buffer[j-1][bd]) * QMF_IM(buffer[j-1][bd]);
         RE(ac->r11) += r11;
     }
 
@@ -268,7 +262,7 @@
 }
 #endif
 
-static void calc_prediction_coef(sbr_info *sbr, const qmf_t *Xlow,
+static void calc_prediction_coef(sbr_info *sbr, const qmf_t Xlow[40][32],
                                  complex_t *alpha_0, complex_t *alpha_1
 #ifdef SBR_LOW_POWER
                                  , real_t *rxx
--- a/libfaad/sbr_hfgen.h
+++ b/libfaad/sbr_hfgen.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_hfgen.h,v 1.3 2003/09/30 08:07:47 menno Exp $
+** $Id: sbr_hfgen.h,v 1.4 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SBR_HFGEN_H__
@@ -32,14 +32,14 @@
 extern "C" {
 #endif
 
-void hf_generation(sbr_info *sbr, const qmf_t *Xlow,
-                   qmf_t *Xhigh
+void hf_generation(sbr_info *sbr, const qmf_t Xlow[40][32],
+                   qmf_t Xhigh[40][64]
 #ifdef SBR_LOW_POWER
                    ,real_t *deg
 #endif
                    ,uint8_t ch);
 
-static void calc_prediction_coef(sbr_info *sbr, const qmf_t *Xlow,
+static void calc_prediction_coef(sbr_info *sbr, const qmf_t Xlow[40][32],
                                  complex_t *alpha_0, complex_t *alpha_1
 #ifdef SBR_LOW_POWER
                                  , real_t *rxx
--- a/libfaad/sbr_qmf.c
+++ b/libfaad/sbr_qmf.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_qmf.c,v 1.13 2003/09/30 12:43:05 menno Exp $
+** $Id: sbr_qmf.c,v 1.14 2003/10/09 20:04:25 menno Exp $
 **/
 
 #include "common.h"
@@ -60,7 +60,7 @@
 }
 
 void sbr_qmf_analysis_32(sbr_info *sbr, qmfa_info *qmfa, const real_t *input,
-                         qmf_t *X, uint8_t offset, uint8_t kx)
+                         qmf_t X[40][32], uint8_t offset, uint8_t kx)
 {
     uint8_t l;
     real_t u[64];
@@ -114,15 +114,16 @@
             if (n < kx)
             {
 #ifdef FIXED_POINT
-                QMF_RE(X[((l + offset)<<5) + n]) = u[n] << 1;
+                QMF_RE(X[l + offset][n]) = u[n] << 1;
 #else
-                QMF_RE(X[((l + offset)<<5) + n]) = 2. * u[n];
+                QMF_RE(X[l + offset][n]) = 2. * u[n];
 #endif
             } else {
-                QMF_RE(X[((l + offset)<<5) + n]) = 0;
+                QMF_RE(X[l + offset][n]) = 0;
             }
         }
 #else
+#if 0
         x[0] = u[0];
         x[63] = u[32];
         for (n = 2; n < 64; n += 2)
@@ -132,21 +133,32 @@
         }
 
         DCT4_64(y, x);
+#else
+        x[0] = u[0];
+        for (n = 0; n < 31; n++)
+        {
+            x[2*n+1] = u[n+1] + u[63-n];
+            x[2*n+2] = u[n+1] - u[63-n];
+        }
+        x[63] = u[32];
 
+        DCT4_64_kernel(y, x);
+#endif
+
         for (n = 0; n < 32; n++)
         {
             if (n < kx)
             {
 #ifdef FIXED_POINT
-                QMF_RE(X[((l + offset)<<5) + n]) = y[n] << 1;
-                QMF_IM(X[((l + offset)<<5) + n]) = -y[63-n] << 1;
+                QMF_RE(X[l + offset][n]) = y[n] << 1;
+                QMF_IM(X[l + offset][n]) = -y[63-n] << 1;
 #else
-                QMF_RE(X[((l + offset)<<5) + n]) = 2. * y[n];
-                QMF_IM(X[((l + offset)<<5) + n]) = -2. * y[63-n];
+                QMF_RE(X[l + offset][n]) = 2. * y[n];
+                QMF_IM(X[l + offset][n]) = -2. * y[63-n];
 #endif
             } else {
-                QMF_RE(X[((l + offset)<<5) + n]) = 0;
-                QMF_IM(X[((l + offset)<<5) + n]) = 0;
+                QMF_RE(X[l + offset][n]) = 0;
+                QMF_IM(X[l + offset][n]) = 0;
             }
         }
 #endif
@@ -181,7 +193,7 @@
 }
 
 #ifdef SBR_LOW_POWER
-void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, const qmf_t *X,
+void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, const qmf_t X[32][64],
                           real_t *output)
 {
     uint8_t l;
@@ -207,9 +219,9 @@
         for (k = 0; k < 64; k++)
         {
 #ifdef FIXED_POINT
-            x[k] = QMF_RE(X[(l<<6) + k]);
+            x[k] = QMF_RE(X[l][k]);
 #else
-            x[k] = QMF_RE(X[(l<<6) + k]) / 32.;
+            x[k] = QMF_RE(X[l][k]) / 32.;
 #endif
         }
 
@@ -245,13 +257,14 @@
     }
 }
 #else
-void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, const qmf_t *X,
+void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, const qmf_t X[32][64],
                           real_t *output)
 {
-    uint8_t l;
-    int16_t n, k;
     real_t x1[64], x2[64];
     real_t *outptr = output;
+    real_t scale = 1.f/64.f;
+    int16_t n, k;
+    uint8_t l;
 
 
     /* qmf subsample l */
@@ -268,21 +281,28 @@
         qmfs->v_index = (qmfs->v_index + 1) & 0x1;
 
         /* calculate 128 samples */
-        for (k = 0; k < 64; k++)
+        x1[0] = scale*QMF_RE(X[l][0]);
+        x2[63] = scale*QMF_IM(X[l][0]);
+        for (k = 0; k < 31; k++)
         {
-            x1[k]      = QMF_RE(X[(l<<6) + k])/64.;
-            x2[63 - k] = QMF_IM(X[(l<<6) + k])/64.;
+            x1[2*k+1] = scale*(QMF_RE(X[l][2*k+1]) - QMF_RE(X[l][2*k+2]));
+            x1[2*k+2] = scale*(QMF_RE(X[l][2*k+1]) + QMF_RE(X[l][2*k+2]));
+
+            x2[61 - 2*k] = scale*(QMF_IM(X[l][2*k+2]) - QMF_IM(X[l][2*k+1]));
+            x2[62 - 2*k] = scale*(QMF_IM(X[l][2*k+2]) + QMF_IM(X[l][2*k+1]));
         }
+        x1[63] = scale*QMF_RE(X[l][63]);
+        x2[0] = scale*QMF_IM(X[l][63]);
 
-        DCT4_64(x1, x1);
-        DCT4_64(x2, x2);
+        DCT4_64_kernel(x1, x1);
+        DCT4_64_kernel(x2, x2);
 
-        for (n = 0; n < 64; n+=2)
+        for (n = 0; n < 32; n++)
         {
-            v0[n]      =  x2[n]   - x1[n];
-            v0[n+1]    = -x2[n+1] - x1[n+1];
-            v1[63-n]   =  x2[n]   + x1[n];
-            v1[63-n-1] = -x2[n+1] + x1[n+1];
+            v0[   2*n]   =  x2[2*n]   - x1[2*n];
+            v1[63-2*n]   =  x2[2*n]   + x1[2*n];
+            v0[   2*n+1] = -x2[2*n+1] - x1[2*n+1];
+            v1[62-2*n]   = -x2[2*n+1] + x1[2*n+1];
         }
 
         /* calculate 64 output samples and window */
--- a/libfaad/sbr_qmf.h
+++ b/libfaad/sbr_qmf.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_qmf.h,v 1.7 2003/09/22 13:15:38 menno Exp $
+** $Id: sbr_qmf.h,v 1.8 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SBR_QMF_H__
@@ -38,12 +38,10 @@
 void qmfs_end(qmfs_info *qmfs);
 
 void sbr_qmf_analysis_32(sbr_info *sbr, qmfa_info *qmfa, const real_t *input,
-                         qmf_t *X, uint8_t offset, uint8_t kx);
-void sbr_qmf_analysis_64(qmfa_info *qmfa, const real_t *input,
-                         qmf_t *X, uint8_t maxband, uint8_t offset);
+                         qmf_t X[40][32], uint8_t offset, uint8_t kx);
 void sbr_qmf_synthesis_32(qmfs_info *qmfs, const qmf_t *X,
                           real_t *output);
-void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, const qmf_t *X,
+void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, const qmf_t X[32][64],
                           real_t *output);
 
 
--- a/libfaad/sbr_qmf_c.h
+++ b/libfaad/sbr_qmf_c.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_qmf_c.h,v 1.2 2003/09/25 12:40:19 menno Exp $
+** $Id: sbr_qmf_c.h,v 1.6 2003/11/04 21:43:30 menno Exp $
 **/
 
 #ifndef __SBR_QMF_C_H__
--- a/libfaad/sbr_syntax.c
+++ b/libfaad/sbr_syntax.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 Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_syntax.c,v 1.11 2003/09/30 16:32:02 menno Exp $
+** $Id: sbr_syntax.c,v 1.12 2003/10/09 20:04:25 menno Exp $
 **/
 
 #include "common.h"
@@ -78,7 +78,7 @@
 }
 
 /* table 2 */
-uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
+uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr)
 {
     uint8_t result;
 #ifdef DRM
@@ -106,7 +106,7 @@
     if (sbr->Is_DRM_SBR)
     {
         /* Check CRC, get number of bits for check */
-        if (id_aac == ID_SCE)
+        if (sbr->id_aac == ID_SCE)
         {
             if (sbr->lcstereo_flag)
             {
@@ -138,7 +138,7 @@
 #endif
 
     if (sbr->bs_header_flag)
-        sbr_header(ld, sbr, id_aac);
+        sbr_header(ld, sbr);
 
     /* TODO: Reset? */
     sbr_reset(sbr);
@@ -181,7 +181,7 @@
             return result;
     }
 
-    if ((result = sbr_data(ld, sbr, id_aac)) > 0)
+    if ((result = sbr_data(ld, sbr)) > 0)
         return result;
 
     /* no error */
@@ -189,7 +189,7 @@
 }
 
 /* table 3 */
-static void sbr_header(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
+static void sbr_header(bitfile *ld, sbr_info *sbr)
 {
     uint8_t bs_header_extra_1, bs_header_extra_2;
 
@@ -290,7 +290,7 @@
 }
 
 /* table 4 */
-static uint8_t sbr_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
+static uint8_t sbr_data(bitfile *ld, sbr_info *sbr)
 {
     uint8_t result;
 #if 0
@@ -305,19 +305,19 @@
         sbr->rate = 2;
 #endif
 
-    switch (id_aac)
+    switch (sbr->id_aac)
     {
     case ID_SCE:
-        if ((result = sbr_single_channel_element(ld, sbr)) > 0)
-            return result;
+		if ((result = sbr_single_channel_element(ld, sbr)) > 0)
+			return result;
         break;
     case ID_CPE:
-        if ((result = sbr_channel_pair_element(ld, sbr)) > 0)
-            return result;
+		if ((result = sbr_channel_pair_element(ld, sbr)) > 0)
+			return result;
         break;
     }
 
-    return 0;
+	return 0;
 }
 
 /* table 5 */
--- a/libfaad/sbr_syntax.h
+++ b/libfaad/sbr_syntax.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_syntax.h,v 1.7 2003/09/09 18:09:52 menno Exp $
+** $Id: sbr_syntax.h,v 1.8 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SBR_SYNTAX_H__
@@ -59,9 +59,9 @@
 #define NOISE_FLOOR_OFFSET 6.0
 
 
-uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac);
-static void sbr_header(bitfile *ld, sbr_info *sbr, uint8_t id_aac);
-static uint8_t sbr_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac);
+uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr);
+static void sbr_header(bitfile *ld, sbr_info *sbr);
+static uint8_t sbr_data(bitfile *ld, sbr_info *sbr);
 static uint8_t sbr_single_channel_element(bitfile *ld, sbr_info *sbr);
 static uint8_t sbr_channel_pair_element(bitfile *ld, sbr_info *sbr);
 static uint8_t sbr_grid(bitfile *ld, sbr_info *sbr, uint8_t ch);
--- a/libfaad/sbr_tf_grid.c
+++ b/libfaad/sbr_tf_grid.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 Mpeg4AAClicense@nero.com.
 **
-** $Id: sbr_tf_grid.c,v 1.4 2003/09/30 16:32:02 menno Exp $
+** $Id: sbr_tf_grid.c,v 1.5 2003/10/09 20:04:25 menno Exp $
 **/
 
 /* Time/Frequency grid */
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: specrec.c,v 1.27 2003/09/30 12:43:05 menno Exp $
+** $Id: specrec.c,v 1.28 2003/10/09 20:04:25 menno Exp $
 **/
 
 /*
@@ -39,6 +39,16 @@
 #include "specrec.h"
 #include "syntax.h"
 #include "iq_table.h"
+#include "ms.h"
+#include "is.h"
+#include "pns.h"
+#include "tns.h"
+#include "lt_predict.h"
+#include "ic_predict.h"
+#ifdef SSR_DEC
+#include "ssr.h"
+#include "ssr_fb.h"
+#endif
 
 #ifdef LD_DEC
 static uint8_t num_swb_512_window[] =
@@ -410,15 +420,13 @@
   - Within a scalefactor window band, the coefficients are in ascending
     spectral order.
 */
-void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len)
+static void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len)
 {
     uint8_t g, sfb, win;
     uint16_t width, bin, k, gindex;
 
-    real_t tmp_spec[1024];
+    real_t tmp_spec[1024] = {0};
 
-    memset(tmp_spec, 0, frame_len*sizeof(real_t));
-
     k = 0;
     gindex = 0;
 
@@ -470,8 +478,6 @@
 #ifdef FIXED_POINT
     int16_t sgn = 1;
 
-    if (q == 0) return 0;
-
     if (q < 0)
     {
         q = -q;
@@ -478,19 +484,17 @@
         sgn = -1;
     }
 
-    if (q >= IQ_TABLE_SIZE)
-        return 0; /* sgn * tab[q>>3] * 16; */
-
-    return sgn * tab[q];
+    if (q < IQ_TABLE_SIZE)
+        return sgn * tab[q];
+    
+    return 0; /* sgn * tab[q>>3] * 16; */
 #else
-    int16_t sgn = 1;
+    real_t sgn = REAL_CONST(1.0);
 
-    if (q == 0) return 0;
-
     if (q < 0)
     {
         q = -q;
-        sgn = -1;
+        sgn = REAL_CONST(-1.0);
     }
 
     if (q < IQ_TABLE_SIZE)
@@ -500,7 +504,7 @@
 #endif
 }
 
-void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len)
+static void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len)
 {
     int16_t i;
     real_t *tab = iq_table;
@@ -535,8 +539,8 @@
 };
 #endif
 
-void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant,
-                        uint16_t frame_len)
+static void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics,
+                               real_t *x_invquant, uint16_t frame_len)
 {
     uint8_t g, sfb;
     uint16_t top;
@@ -616,4 +620,334 @@
         }
         groups += ics->window_group_length[g];
     }
+}
+
+void reconstruct_single_channel(faacDecHandle hDecoder, ic_stream *ics,
+                                element *sce, int16_t *spec_data)
+{
+    real_t spec_coef[1024];
+
+    /* inverse quantization */
+    inverse_quantization(spec_coef, spec_data, hDecoder->frameLength);
+
+    /* apply scalefactors */
+    apply_scalefactors(hDecoder, ics, spec_coef, hDecoder->frameLength);
+
+    /* deinterleave short block grouping */
+    if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+        quant_to_spec(ics, spec_coef, hDecoder->frameLength);
+
+
+    /* pns decoding */
+    pns_decode(ics, NULL, spec_coef, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+
+#ifdef MAIN_DEC
+    /* MAIN object type prediction */
+    if (hDecoder->object_type == MAIN)
+    {
+        /* allocate the state only when needed */
+        if (hDecoder->pred_stat[sce->channel] == NULL)
+        {
+            hDecoder->pred_stat[sce->channel] = (pred_state*)malloc(hDecoder->frameLength * sizeof(pred_state));
+            reset_all_predictors(hDecoder->pred_stat[sce->channel], hDecoder->frameLength);
+        }
+
+        /* intra channel prediction */
+        ic_prediction(ics, spec_coef, hDecoder->pred_stat[sce->channel], hDecoder->frameLength);
+
+        /* In addition, for scalefactor bands coded by perceptual
+           noise substitution the predictors belonging to the
+           corresponding spectral coefficients are reset.
+        */
+        pns_reset_pred_state(ics, hDecoder->pred_stat[sce->channel]);
+    }
+#endif
+
+#ifdef LTP_DEC
+    if (is_ltp_ot(hDecoder->object_type))
+    {
+#ifdef LD_DEC
+        if (hDecoder->object_type == LD)
+        {
+            if (ics->ltp.data_present)
+            {
+                if (ics->ltp.lag_update)
+                    hDecoder->ltp_lag[sce->channel] = ics->ltp.lag;
+            }
+            ics->ltp.lag = hDecoder->ltp_lag[sce->channel];
+        }
+#endif
+
+        /* 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));
+        }
+
+        /* long term prediction */
+        lt_prediction(ics, &(ics->ltp), spec_coef, hDecoder->lt_pred_stat[sce->channel], hDecoder->fb,
+            ics->window_shape, hDecoder->window_shape_prev[sce->channel],
+            hDecoder->sf_index, hDecoder->object_type, hDecoder->frameLength);
+    }
+#endif
+
+    /* tns decoding */
+    tns_decode_frame(ics, &(ics->tns), hDecoder->sf_index, hDecoder->object_type,
+        spec_coef, hDecoder->frameLength);
+
+    /* drc decoding */
+    if (hDecoder->drc->present)
+    {
+        if (!hDecoder->drc->exclude_mask[sce->channel] || !hDecoder->drc->excluded_chns_present)
+            drc_decode(hDecoder->drc, spec_coef);
+    }
+
+    if (hDecoder->time_out[sce->channel] == NULL)
+    {
+        hDecoder->time_out[sce->channel] = (real_t*)malloc(hDecoder->frameLength*2*sizeof(real_t));
+        memset(hDecoder->time_out[sce->channel], 0, hDecoder->frameLength*2*sizeof(real_t));
+    }
+
+    /* filter bank */
+#ifdef SSR_DEC
+    if (hDecoder->object_type != SSR)
+    {
+#endif
+        ifilter_bank(hDecoder->fb, ics->window_sequence, ics->window_shape,
+            hDecoder->window_shape_prev[sce->channel], spec_coef,
+            hDecoder->time_out[sce->channel], hDecoder->object_type, hDecoder->frameLength);
+#ifdef SSR_DEC
+    } else {
+        if (hDecoder->ssr_overlap[sce->channel] == NULL)
+        {
+            hDecoder->ssr_overlap[sce->channel] = (real_t*)malloc(2*hDecoder->frameLength*sizeof(real_t));
+            memset(hDecoder->ssr_overlap[sce->channel], 0, 2*hDecoder->frameLength*sizeof(real_t));
+        }
+        if (hDecoder->prev_fmd[sce->channel] == NULL)
+        {
+            uint16_t k;
+            hDecoder->prev_fmd[sce->channel] = (real_t*)malloc(2*hDecoder->frameLength*sizeof(real_t));
+            for (k = 0; k < 2*hDecoder->frameLength; k++)
+                hDecoder->prev_fmd[sce->channel][k] = REAL_CONST(-1);
+        }
+
+        ssr_decode(&(ics->ssr), hDecoder->fb, ics->window_sequence, ics->window_shape,
+            hDecoder->window_shape_prev[sce->channel], spec_coef, hDecoder->time_out[sce->channel],
+            hDecoder->ssr_overlap[sce->channel], hDecoder->ipqf_buffer[sce->channel], hDecoder->prev_fmd[sce->channel],
+            hDecoder->frameLength);
+    }
+#endif
+
+    /* save window shape for next frame */
+    hDecoder->window_shape_prev[sce->channel] = ics->window_shape;
+
+#ifdef LTP_DEC
+    if (is_ltp_ot(hDecoder->object_type))
+    {
+        lt_update_state(hDecoder->lt_pred_stat[sce->channel], hDecoder->time_out[sce->channel],
+            hDecoder->time_out[sce->channel]+hDecoder->frameLength, hDecoder->frameLength, hDecoder->object_type);
+    }
+#endif
+}
+
+void reconstruct_channel_pair(faacDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
+                              element *cpe, int16_t *spec_data1, int16_t *spec_data2)
+{
+    real_t spec_coef1[1024];
+    real_t spec_coef2[1024];
+
+    /* inverse quantization */
+    inverse_quantization(spec_coef1, spec_data1, hDecoder->frameLength);
+    inverse_quantization(spec_coef2, spec_data2, hDecoder->frameLength);
+
+    /* apply scalefactors */
+    apply_scalefactors(hDecoder, ics1, spec_coef1, hDecoder->frameLength);
+    apply_scalefactors(hDecoder, ics2, spec_coef2, hDecoder->frameLength);
+
+    /* deinterleave short block grouping */
+    if (ics1->window_sequence == EIGHT_SHORT_SEQUENCE)
+        quant_to_spec(ics1, spec_coef1, hDecoder->frameLength);
+    if (ics2->window_sequence == EIGHT_SHORT_SEQUENCE)
+        quant_to_spec(ics2, spec_coef2, hDecoder->frameLength);
+
+
+    /* pns decoding */
+    if (ics1->ms_mask_present)
+    {
+        pns_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength, 1, hDecoder->object_type);
+    } else {
+        pns_decode(ics1, NULL, spec_coef1, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+        pns_decode(ics2, NULL, spec_coef2, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+    }
+
+    /* mid/side decoding */
+    ms_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength);
+
+    /* intensity stereo decoding */
+    is_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength);
+
+#ifdef MAIN_DEC
+    /* MAIN object type prediction */
+    if (hDecoder->object_type == MAIN)
+    {
+        /* allocate the state only when needed */
+        if (hDecoder->pred_stat[cpe->channel] == NULL)
+        {
+            hDecoder->pred_stat[cpe->channel] = (pred_state*)malloc(hDecoder->frameLength * sizeof(pred_state));
+            reset_all_predictors(hDecoder->pred_stat[cpe->channel], hDecoder->frameLength);
+        }
+        if (hDecoder->pred_stat[cpe->paired_channel] == NULL)
+        {
+            hDecoder->pred_stat[cpe->paired_channel] = (pred_state*)malloc(hDecoder->frameLength * sizeof(pred_state));
+            reset_all_predictors(hDecoder->pred_stat[cpe->paired_channel], hDecoder->frameLength);
+        }
+
+        /* 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);
+
+        /* In addition, for scalefactor bands coded by perceptual
+           noise substitution the predictors belonging to the
+           corresponding spectral coefficients are reset.
+        */
+        pns_reset_pred_state(ics1, hDecoder->pred_stat[cpe->channel]);
+        pns_reset_pred_state(ics2, hDecoder->pred_stat[cpe->paired_channel]);
+    }
+#endif
+
+#ifdef LTP_DEC
+    if (is_ltp_ot(hDecoder->object_type))
+    {
+        ltp_info *ltp1 = &(ics1->ltp);
+        ltp_info *ltp2 = (cpe->common_window) ? &(ics2->ltp2) : &(ics2->ltp) ;
+#ifdef LD_DEC
+        if (hDecoder->object_type == LD)
+        {
+            if (ltp1->data_present)
+            {
+                if (ltp1->lag_update)
+                    hDecoder->ltp_lag[cpe->channel] = ltp1->lag;
+            }
+            ltp1->lag = hDecoder->ltp_lag[cpe->channel];
+            if (ltp2->data_present)
+            {
+                if (ltp2->lag_update)
+                    hDecoder->ltp_lag[cpe->paired_channel] = ltp2->lag;
+            }
+            ltp2->lag = hDecoder->ltp_lag[cpe->paired_channel];
+        }
+#endif
+
+        /* 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));
+        }
+        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));
+        }
+
+        /* long term prediction */
+        lt_prediction(ics1, ltp1, spec_coef1, hDecoder->lt_pred_stat[cpe->channel], hDecoder->fb,
+            ics1->window_shape, hDecoder->window_shape_prev[cpe->channel],
+            hDecoder->sf_index, hDecoder->object_type, hDecoder->frameLength);
+        lt_prediction(ics2, ltp2, spec_coef2, hDecoder->lt_pred_stat[cpe->paired_channel], hDecoder->fb,
+            ics2->window_shape, hDecoder->window_shape_prev[cpe->paired_channel],
+            hDecoder->sf_index, hDecoder->object_type, hDecoder->frameLength);
+    }
+#endif
+
+    /* tns decoding */
+    tns_decode_frame(ics1, &(ics1->tns), hDecoder->sf_index, hDecoder->object_type,
+        spec_coef1, hDecoder->frameLength);
+    tns_decode_frame(ics2, &(ics2->tns), hDecoder->sf_index, hDecoder->object_type,
+        spec_coef2, hDecoder->frameLength);
+
+    /* drc decoding */
+    if (hDecoder->drc->present)
+    {
+        if (!hDecoder->drc->exclude_mask[cpe->channel] || !hDecoder->drc->excluded_chns_present)
+            drc_decode(hDecoder->drc, spec_coef1);
+        if (!hDecoder->drc->exclude_mask[cpe->paired_channel] || !hDecoder->drc->excluded_chns_present)
+            drc_decode(hDecoder->drc, spec_coef2);
+    }
+
+    if (hDecoder->time_out[cpe->channel] == NULL)
+    {
+        hDecoder->time_out[cpe->channel] = (real_t*)malloc(hDecoder->frameLength*2*sizeof(real_t));
+        memset(hDecoder->time_out[cpe->channel], 0, hDecoder->frameLength*2*sizeof(real_t));
+    }
+    if (hDecoder->time_out[cpe->paired_channel] == NULL)
+    {
+        hDecoder->time_out[cpe->paired_channel] = (real_t*)malloc(hDecoder->frameLength*2*sizeof(real_t));
+        memset(hDecoder->time_out[cpe->paired_channel], 0, hDecoder->frameLength*2*sizeof(real_t));
+    }
+
+    /* filter bank */
+#ifdef SSR_DEC
+    if (hDecoder->object_type != SSR)
+    {
+#endif
+        ifilter_bank(hDecoder->fb, ics1->window_sequence, ics1->window_shape,
+            hDecoder->window_shape_prev[cpe->channel], spec_coef1,
+            hDecoder->time_out[cpe->channel], hDecoder->object_type, hDecoder->frameLength);
+        ifilter_bank(hDecoder->fb, ics2->window_sequence, ics2->window_shape,
+            hDecoder->window_shape_prev[cpe->paired_channel], spec_coef2,
+            hDecoder->time_out[cpe->paired_channel], hDecoder->object_type, hDecoder->frameLength);
+#ifdef SSR_DEC
+    } else {
+        if (hDecoder->ssr_overlap[cpe->channel] == NULL)
+        {
+            hDecoder->ssr_overlap[cpe->channel] = (real_t*)malloc(2*hDecoder->frameLength*sizeof(real_t));
+            memset(hDecoder->ssr_overlap[cpe->channel], 0, 2*hDecoder->frameLength*sizeof(real_t));
+        }
+        if (hDecoder->ssr_overlap[cpe->paired_channel] == NULL)
+        {
+            hDecoder->ssr_overlap[cpe->paired_channel] = (real_t*)malloc(2*hDecoder->frameLength*sizeof(real_t));
+            memset(hDecoder->ssr_overlap[cpe->paired_channel], 0, 2*hDecoder->frameLength*sizeof(real_t));
+        }
+        if (hDecoder->prev_fmd[cpe->channel] == NULL)
+        {
+            uint16_t k;
+            hDecoder->prev_fmd[cpe->channel] = (real_t*)malloc(2*hDecoder->frameLength*sizeof(real_t));
+            for (k = 0; k < 2*hDecoder->frameLength; k++)
+                hDecoder->prev_fmd[cpe->channel][k] = REAL_CONST(-1);
+        }
+        if (hDecoder->prev_fmd[cpe->paired_channel] == NULL)
+        {
+            uint16_t k;
+            hDecoder->prev_fmd[cpe->paired_channel] = (real_t*)malloc(2*hDecoder->frameLength*sizeof(real_t));
+            for (k = 0; k < 2*hDecoder->frameLength; k++)
+                hDecoder->prev_fmd[cpe->paired_channel][k] = REAL_CONST(-1);
+        }
+
+        ssr_decode(&(ics1->ssr), hDecoder->fb, ics1->window_sequence, ics1->window_shape,
+            hDecoder->window_shape_prev[cpe->channel], spec_coef1, hDecoder->time_out[cpe->channel],
+            hDecoder->ssr_overlap[cpe->channel], hDecoder->ipqf_buffer[cpe->channel],
+            hDecoder->prev_fmd[cpe->channel], hDecoder->frameLength);
+        ssr_decode(&(ics2->ssr), hDecoder->fb, ics2->window_sequence, ics2->window_shape,
+            hDecoder->window_shape_prev[cpe->paired_channel], spec_coef2, hDecoder->time_out[cpe->paired_channel],
+            hDecoder->ssr_overlap[cpe->paired_channel], hDecoder->ipqf_buffer[cpe->paired_channel],
+            hDecoder->prev_fmd[cpe->paired_channel], hDecoder->frameLength);
+    }
+#endif
+
+    /* save window shape for next frame */
+    hDecoder->window_shape_prev[cpe->channel] = ics1->window_shape;
+    hDecoder->window_shape_prev[cpe->paired_channel] = ics2->window_shape;
+
+#ifdef LTP_DEC
+    if (is_ltp_ot(hDecoder->object_type))
+    {
+        lt_update_state(hDecoder->lt_pred_stat[cpe->channel], hDecoder->time_out[cpe->channel],
+            hDecoder->time_out[cpe->channel]+hDecoder->frameLength, hDecoder->frameLength, hDecoder->object_type);
+        lt_update_state(hDecoder->lt_pred_stat[cpe->paired_channel], hDecoder->time_out[cpe->paired_channel],
+            hDecoder->time_out[cpe->paired_channel]+hDecoder->frameLength, hDecoder->frameLength,
+            hDecoder->object_type);
+    }
+#endif
 }
--- a/libfaad/specrec.h
+++ b/libfaad/specrec.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: specrec.h,v 1.15 2003/09/24 08:05:45 menno Exp $
+** $Id: specrec.h,v 1.16 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SPECREC_H__
@@ -35,13 +35,18 @@
 #include "syntax.h"
 
 uint8_t window_grouping_info(faacDecHandle hDecoder, ic_stream *ics);
-void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len);
-void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len);
-void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant,
-                        uint16_t frame_len);
+static void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len);
+static void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len);
+static void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant,
+                               uint16_t frame_len);
 #ifndef FIXED_POINT
 void build_tables(real_t *pow2_table);
 #endif
+
+void reconstruct_channel_pair(faacDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
+                              element *cpe, int16_t *spec_data1, int16_t *spec_data2);
+void reconstruct_single_channel(faacDecHandle hDecoder, ic_stream *ics, element *sce,
+                                int16_t *spec_data);
 
 #ifdef __cplusplus
 }
--- a/libfaad/ssr.c
+++ b/libfaad/ssr.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: ssr.c,v 1.5 2003/09/09 18:09:52 menno Exp $
+** $Id: ssr.c,v 1.6 2003/10/09 20:04:25 menno Exp $
 **/
 
 #include "common.h"
@@ -43,11 +43,8 @@
 {
     uint8_t band;
     uint16_t ssr_frame_len = frame_len/SSR_BANDS;
-    real_t time_tmp[2048];
-    real_t output[1024];
-
-    memset(output, 0, 1024*sizeof(real_t));
-    memset(time_tmp, 0, 2048*sizeof(real_t));
+    real_t time_tmp[2048] = {0};
+    real_t output[1024] = {0};
 
     for (band = 0; band < SSR_BANDS; band++)
     {
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: structs.h,v 1.16 2003/09/23 08:12:29 menno Exp $
+** $Id: structs.h,v 1.17 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __STRUCTS_H__
@@ -32,6 +32,7 @@
 extern "C" {
 #endif
 
+#include "cfft.h"
 #ifdef SBR_DEC
 #include "sbr_dec.h"
 #endif
@@ -50,14 +51,6 @@
     real_t VAR[2];
 } pred_state;
 
-typedef struct
-{
-    uint16_t n;
-    uint16_t ifac[15];
-    complex_t *work;
-    complex_t *tab;
-} cfft_info;
-
 typedef struct {
     uint16_t N;
     cfft_info *cfft;
@@ -377,7 +370,6 @@
 
     uint8_t downMatrix;
     uint8_t first_syn_ele;
-    uint8_t last_syn_ele;
     uint8_t has_lfe;
     uint8_t fr_channels;
     uint8_t fr_ch_ele;
@@ -429,6 +421,7 @@
     /* Program Config Element */
     uint8_t pce_set;
     program_config pce;
+    uint8_t element_id[MAX_CHANNELS];
     uint8_t channel_element[MAX_CHANNELS];
     uint8_t internal_channel[MAX_CHANNELS];
 
--- 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 Mpeg4AAClicense@nero.com.
 **
-** $Id: syntax.c,v 1.56 2003/09/30 12:43:05 menno Exp $
+** $Id: syntax.c,v 1.57 2003/10/09 20:04:25 menno Exp $
 **/
 
 /*
@@ -260,37 +260,28 @@
     return 0;
 }
 
-element *decode_sce_lfe(faacDecHandle hDecoder,
-                        faacDecFrameInfo *hInfo, bitfile *ld,
-                        real_t **spec_coef, uint8_t id_syn_ele)
+void decode_sce_lfe(faacDecHandle hDecoder,
+                    faacDecFrameInfo *hInfo, bitfile *ld,
+                    uint8_t id_syn_ele)
 {
-    element *ele;
     uint8_t channels = hDecoder->fr_channels;
+    uint8_t tag = 0;
 
     if (channels+1 > MAX_CHANNELS)
     {
         hInfo->error = 12;
-        return NULL;
+        return;
     }
     if (hDecoder->fr_ch_ele+1 > MAX_SYNTAX_ELEMENTS)
     {
         hInfo->error = 13;
-        return NULL;
+        return;
     }
 
-    spec_coef[channels]   = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
+    hInfo->error = single_lfe_channel_element(hDecoder, ld, channels, &tag);
 
-    ele = (element*)malloc(sizeof(element));
-    memset(ele, 0, sizeof(element));
-    ele->ele_id  = id_syn_ele;
-    ele->channel = channels;
-    ele->paired_channel = -1;
-
-    hInfo->error = single_lfe_channel_element(hDecoder, ele,
-        ld, spec_coef[channels]);
-
     if (hDecoder->pce_set)
-        hDecoder->internal_channel[hDecoder->pce.sce_channel[ele->element_instance_tag]] = channels;
+        hDecoder->internal_channel[hDecoder->pce.sce_channel[tag]] = channels;
     else
         hDecoder->internal_channel[channels] = channels;
 
@@ -298,47 +289,35 @@
         hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
     else /* LFE */
         hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
+    hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele;
 
     hDecoder->fr_channels++;
     hDecoder->fr_ch_ele++;
-
-    return ele;
 }
 
-element *decode_cpe(faacDecHandle hDecoder,
-                    faacDecFrameInfo *hInfo, bitfile *ld,
-                    real_t **spec_coef, uint8_t id_syn_ele)
+void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                uint8_t id_syn_ele)
 {
-    element *ele;
     uint8_t channels = hDecoder->fr_channels;
+    uint8_t tag = 0;
 
     if (channels+2 > MAX_CHANNELS)
     {
         hInfo->error = 12;
-        return NULL;
+        return;
     }
     if (hDecoder->fr_ch_ele+1 > MAX_SYNTAX_ELEMENTS)
     {
         hInfo->error = 13;
-        return NULL;
+        return;
     }
 
-    spec_coef[channels]   = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
-    spec_coef[channels+1] = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
+    hInfo->error = channel_pair_element(hDecoder, ld, channels, &tag);
 
-    ele = (element*)malloc(sizeof(element));
-    memset(ele, 0, sizeof(element));
-    ele->ele_id         = id_syn_ele;
-    ele->channel        = channels;
-    ele->paired_channel = channels+1;
-
-    hInfo->error = channel_pair_element(hDecoder, ele,
-        ld, spec_coef[channels], spec_coef[channels+1]);
-
     if (hDecoder->pce_set)
     {
-        hDecoder->internal_channel[hDecoder->pce.cpe_channel[ele->element_instance_tag]] = channels;
-        hDecoder->internal_channel[hDecoder->pce.cpe_channel[ele->element_instance_tag]+1] = channels+1;
+        hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]] = channels;
+        hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]+1] = channels+1;
     } else {
         hDecoder->internal_channel[channels] = channels;
         hDecoder->internal_channel[channels+1] = channels+1;
@@ -346,16 +325,14 @@
 
     hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
     hDecoder->channel_element[channels+1] = hDecoder->fr_ch_ele;
+    hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele;
 
     hDecoder->fr_channels += 2;
     hDecoder->fr_ch_ele++;
-
-    return ele;
 }
 
-element **raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
-                         bitfile *ld, element **elements,
-                         real_t **spec_coef, program_config *pce, drc_info *drc)
+void raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
+                    bitfile *ld, program_config *pce, drc_info *drc)
 {
     uint8_t id_syn_ele;
     uint8_t ch_ele = 0;
@@ -376,31 +353,29 @@
             switch (id_syn_ele) {
             case ID_SCE:
                 if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
-                hDecoder->last_syn_ele = id_syn_ele;
-                elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                    hInfo, ld, spec_coef, id_syn_ele);
+                decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
+                ch_ele++;
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_CPE:
                 if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
-                hDecoder->last_syn_ele = id_syn_ele;
-                elements[ch_ele++] = decode_cpe(hDecoder,
-                    hInfo, ld, spec_coef, id_syn_ele);
+                decode_cpe(hDecoder, hInfo, ld, id_syn_ele);
+                ch_ele++;
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_LFE:
                 hDecoder->has_lfe++;
-                elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                    hInfo, ld, spec_coef, id_syn_ele);
+                decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
+                ch_ele++;
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_CCE: /* not implemented yet, but skip the bits */
                 hInfo->error = coupling_channel_element(hDecoder, ld);
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_DSE:
                 data_stream_element(hDecoder, ld);
@@ -407,7 +382,7 @@
                 break;
             case ID_PCE:
                 if ((hInfo->error = program_config_element(pce, ld)) > 0)
-                    return elements;
+                    return;
                 hDecoder->pce_set = 1;
                 break;
             case ID_FIL:
@@ -417,7 +392,7 @@
                     , (ch_ele-1)
 #endif
                     )) > 0)
-                    return elements;
+                    return;
 #ifdef SBR_DEC
                 if (hDecoder->sbr_used[ch_ele-1])
                 {
@@ -435,74 +410,74 @@
         switch (hDecoder->channelConfiguration)
         {
         case 1:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 2:
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 3:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 4:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 5:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 6:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_LFE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_LFE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 7:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_LFE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            ch_ele++;
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_LFE);
+            ch_ele++;
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         default:
             hInfo->error = 7;
-            return elements;
+            return;
         }
 #if 0
         cnt = bits_to_decode() / 8;
@@ -522,30 +497,34 @@
         faad_byte_align(ld);
     }
 
-    return elements;
+    return;
 }
 
 /* Table 4.4.4 and */
 /* Table 4.4.9 */
-static uint8_t single_lfe_channel_element(faacDecHandle hDecoder,
-                                          element *sce, bitfile *ld,
-                                          real_t *spec_coef)
+static uint8_t single_lfe_channel_element(faacDecHandle hDecoder, bitfile *ld,
+                                          uint8_t channel, uint8_t *tag)
 {
     uint8_t retval = 0;
-    ic_stream *ics = &(sce->ics1);
-    int16_t spec_data[1024];
+    element sce = {0};
+    ic_stream *ics = &(sce.ics1);
+    int16_t spec_data[1024] = {0};
 #ifdef DRM
     uint8_t result;
 
     if (hDecoder->object_type != DRM_ER_LC)
 #endif
-    sce->element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
+    sce.element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
         DEBUGVAR(1,38,"single_lfe_channel_element(): element_instance_tag"));
 
+    *tag = sce.element_instance_tag;
+    sce.channel = channel;
+    sce.paired_channel = -1;
+
 #ifdef DRM
     if (hDecoder->object_type == DRM_ER_LC)
     {
-        individual_channel_stream(hDecoder, sce, ld, ics, 0, spec_data);
+        individual_channel_stream(hDecoder, &sce, ld, ics, 0, spec_data);
 
         if (ics->tns_data_present)
             tns_data(ics, &(ics->tns), ld);
@@ -571,49 +550,43 @@
     } else
 #endif
     {
-        retval = individual_channel_stream(hDecoder, sce, ld, ics, 0, spec_data);
+        retval = individual_channel_stream(hDecoder, &sce, ld, ics, 0, spec_data);
         if (retval > 0)
             return retval;
     }
 
-
     /* noiseless coding is done, spectral reconstruction is done now */
+    reconstruct_single_channel(hDecoder, ics, &sce, spec_data);
 
-    /* inverse quantization */
-    inverse_quantization(spec_coef, spec_data, hDecoder->frameLength);
-
-    /* apply scalefactors */
-    apply_scalefactors(hDecoder, ics, spec_coef, hDecoder->frameLength);
-
-    /* deinterleave short block grouping */
-    if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
-        quant_to_spec(ics, spec_coef, hDecoder->frameLength);
-
     return 0;
 }
 
 /* Table 4.4.5 */
-static uint8_t channel_pair_element(faacDecHandle hDecoder, element *cpe,
-                                    bitfile *ld,
-                                    real_t *spec_coef1, real_t *spec_coef2)
+static uint8_t channel_pair_element(faacDecHandle hDecoder, bitfile *ld,
+                                    uint8_t channels, uint8_t *tag)
 {
+    int16_t spec_data1[1024] = {0};
+    int16_t spec_data2[1024] = {0};
+    element cpe = {0};
+    ic_stream *ics1 = &(cpe.ics1);
+    ic_stream *ics2 = &(cpe.ics2);
     uint8_t result;
-    ic_stream *ics1 = &(cpe->ics1);
-    ic_stream *ics2 = &(cpe->ics2);
-    int16_t spec_data1[1024];
-    int16_t spec_data2[1024];
 
+    cpe.channel        = channels;
+    cpe.paired_channel = channels+1;
+
 #ifdef DRM
     if (hDecoder->object_type != DRM_ER_LC)
 #endif
-    cpe->element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
+    cpe.element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
         DEBUGVAR(1,39,"channel_pair_element(): element_instance_tag"));
+    *tag = cpe.element_instance_tag;
 
-    if ((cpe->common_window = faad_get1bit(ld
+    if ((cpe.common_window = faad_get1bit(ld
         DEBUGVAR(1,40,"channel_pair_element(): common_window"))) & 1)
     {
         /* both channels have common ics information */
-        if ((result = ics_info(hDecoder, ics1, ld, cpe->common_window)) > 0)
+        if ((result = ics_info(hDecoder, ics1, ld, cpe.common_window)) > 0)
             return result;
 
         ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
@@ -647,7 +620,7 @@
         ics1->ms_mask_present = 0;
     }
 
-    if ((result = individual_channel_stream(hDecoder, cpe, ld, ics1,
+    if ((result = individual_channel_stream(hDecoder, &cpe, ld, ics1,
         0, spec_data1)) > 0)
     {
         return result;
@@ -654,7 +627,7 @@
     }
 
 #ifdef ERROR_RESILIENCE
-    if (cpe->common_window && (hDecoder->object_type >= ER_OBJECT_START) &&
+    if (cpe.common_window && (hDecoder->object_type >= ER_OBJECT_START) &&
         (ics1->predictor_data_present))
     {
         if ((ics1->ltp2.data_present = faad_get1bit(ld
@@ -665,7 +638,7 @@
     }
 #endif
 
-    if ((result = individual_channel_stream(hDecoder, cpe, ld, ics2,
+    if ((result = individual_channel_stream(hDecoder, &cpe, ld, ics2,
         0, spec_data2)) > 0)
     {
         return result;
@@ -713,21 +686,8 @@
 #endif
 
     /* noiseless coding is done, spectral reconstruction is done now */
+    reconstruct_channel_pair(hDecoder, ics1, ics2, &cpe, spec_data1, spec_data2);
 
-    /* inverse quantization */
-    inverse_quantization(spec_coef1, spec_data1, hDecoder->frameLength);
-    inverse_quantization(spec_coef2, spec_data2, hDecoder->frameLength);
-
-    /* apply scalefactors */
-    apply_scalefactors(hDecoder, ics1, spec_coef1, hDecoder->frameLength);
-    apply_scalefactors(hDecoder, ics2, spec_coef2, hDecoder->frameLength);
-
-    /* deinterleave short block grouping */
-    if (ics1->window_sequence == EIGHT_SHORT_SEQUENCE)
-        quant_to_spec(ics1, spec_coef1, hDecoder->frameLength);
-    if (ics2->window_sequence == EIGHT_SHORT_SEQUENCE)
-        quant_to_spec(ics2, spec_coef2, hDecoder->frameLength);
-
     return 0;
 }
 
@@ -873,13 +833,10 @@
     uint8_t num_gain_element_lists = 0;
     uint8_t num_coupled_elements = 0;
 
-    element el_empty;
-    ic_stream ics_empty;
+    element el_empty = {0};
+    ic_stream ics_empty = {0};
     int16_t sh_data[1024];
 
-    memset(&el_empty, 0, sizeof(element));
-    memset(&ics_empty, 0, sizeof(ic_stream));
-
     c = faad_getbits(ld, LEN_TAG
         DEBUGVAR(1,900,"coupling_channel_element(): element_instance_tag"));
 
@@ -1028,6 +985,8 @@
             /* read in all the SBR data for processing later on */
             hDecoder->sbr[sbr_ele]->data = (uint8_t*)faad_getbitbuffer(ld, count*8);
             hDecoder->sbr[sbr_ele]->data_size = count;
+            /* save id of previous element, this sbr object belongs to that element */
+            hDecoder->sbr[sbr_ele]->id_aac = hDecoder->element_id[sbr_ele];
         } else {
             hDecoder->sbr_used[sbr_ele] = 0;
 #endif
@@ -1602,7 +1561,7 @@
     uint16_t nshort = hDecoder->frameLength/8;
 
     sp = spectral_data;
-    memset(sp, 0, hDecoder->frameLength*sizeof(int16_t));
+    /*memset(sp, 0, hDecoder->frameLength*sizeof(int16_t));*/
 
     for(g = 0; g < ics->num_window_groups; g++)
     {
--- a/libfaad/syntax.h
+++ b/libfaad/syntax.h
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: syntax.h,v 1.37 2003/09/24 19:55:34 menno Exp $
+** $Id: syntax.h,v 1.38 2003/10/09 20:04:25 menno Exp $
 **/
 
 #ifndef __SYNTAX_H__
@@ -109,15 +109,19 @@
 
 uint8_t adts_frame(adts_header *adts, bitfile *ld);
 void get_adif_header(adif_header *adif, bitfile *ld);
+void decode_sce_lfe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                    uint8_t id_syn_ele);
+void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                uint8_t id_syn_ele);
+void raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
+                    bitfile *ld, program_config *pce, drc_info *drc);
 
 
 /* static functions */
-static uint8_t single_lfe_channel_element(faacDecHandle hDecoder,
-                                          element *sce, bitfile *ld,
-                                          real_t *spec_coef);
-static uint8_t channel_pair_element(faacDecHandle hDecoder, element *cpe,
-                                    bitfile *ld,
-                                    real_t *spec_coef1, real_t *spec_coef2);
+static uint8_t single_lfe_channel_element(faacDecHandle hDecoder, bitfile *ld,
+                                          uint8_t channel, uint8_t *tag);
+static uint8_t channel_pair_element(faacDecHandle hDecoder, bitfile *ld,
+                                    uint8_t channel, uint8_t *tag);
 static uint8_t coupling_channel_element(faacDecHandle hDecoder, bitfile *ld);
 static uint16_t data_stream_element(faacDecHandle hDecoder, bitfile *ld);
 static uint8_t program_config_element(program_config *pce, bitfile *ld);