shithub: aacdec

Download patch

ref: 5cef46a6c51d565622907fa49a38a16d0932a760
parent: fa46c1456ca95af03465b549c042a7d135b48766
author: menno <menno>
date: Thu Jun 13 07:03:28 EDT 2002

Included decoding capability of 960 sample frame sizes

--- a/frontend/main.c
+++ b/frontend/main.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: main.c,v 1.15 2002/05/30 17:55:08 menno Exp $
+** $Id: main.c,v 1.16 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifdef _WIN32
@@ -308,7 +308,7 @@
             if (buff)
             {
                 rc = AudioSpecificConfig(buff, &dummy32, &dummy8, &dummy8, &dummy8,
-                    &dummy8, &dummy8, &dummy8);
+                    &dummy8, &dummy8, &dummy8, &dummy8);
                 free(buff);
 
                 if (rc < 0)
--- a/include/faad.h
+++ b/include/faad.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: faad.h,v 1.6 2002/05/30 17:55:08 menno Exp $
+** $Id: faad.h,v 1.7 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifndef __AACDEC_H__
@@ -105,7 +105,8 @@
                                  unsigned char *object_type,
                                  unsigned char *aacSectionDataResilienceFlag,
                                  unsigned char *aacScalefactorDataResilienceFlag,
-                                 unsigned char *aacSpectralDataResilienceFlag);
+                                 unsigned char *aacSpectralDataResilienceFlag,
+                                 unsigned char *frameLengthFlag);
 
 #ifdef _WIN32
   #pragma pack(pop)
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: decoder.c,v 1.15 2002/05/30 18:31:51 menno Exp $
+** $Id: decoder.c,v 1.16 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include <stdlib.h>
@@ -65,6 +65,7 @@
     hDecoder->aacSectionDataResilienceFlag = 0;
     hDecoder->aacScalefactorDataResilienceFlag = 0;
     hDecoder->aacSpectralDataResilienceFlag = 0;
+    hDecoder->frameLength = 1024;
 
     hDecoder->frame = 0;
     hDecoder->sample_buffer = NULL;
@@ -84,7 +85,6 @@
     }
 
     init_drc(&hDecoder->drc, 1.0f, 1.0f);
-    filter_bank_init(&hDecoder->fb);
 #if IQ_TABLE_SIZE && POW_TABLE_SIZE
     build_tables(hDecoder->iq_table, hDecoder->pow2_table);
 #elif !POW_TABLE_SIZE
@@ -223,6 +223,14 @@
     }
     hDecoder->channelConfiguration = *channels;
 
+    /* must be done before frameLength is divided by 2 for LD */
+    filter_bank_init(&hDecoder->fb, hDecoder->frameLength);
+
+#ifdef LD_DEC
+    if (hDecoder->object_type == LD)
+        hDecoder->frameLength >>= 1;
+#endif
+
     if (can_decode_ot(hDecoder->object_type) < 0)
         return -1;
 
@@ -235,6 +243,7 @@
                             uint32_t *samplerate, uint8_t *channels)
 {
     int8_t rc;
+    uint8_t frameLengthFlag;
 
     hDecoder->adif_header_present = 0;
     hDecoder->adts_header_present = 0;
@@ -252,7 +261,8 @@
         &hDecoder->sf_index, &hDecoder->object_type,
         &hDecoder->aacSectionDataResilienceFlag,
         &hDecoder->aacScalefactorDataResilienceFlag,
-        &hDecoder->aacSpectralDataResilienceFlag);
+        &hDecoder->aacSpectralDataResilienceFlag,
+        &frameLengthFlag);
     if (hDecoder->object_type < 4)
         hDecoder->object_type--; /* For AAC differs from MPEG-4 */
     if (rc != 0)
@@ -260,7 +270,17 @@
         return rc;
     }
     hDecoder->channelConfiguration = *channels;
+    if (frameLengthFlag)
+        hDecoder->frameLength = 960;
 
+    /* must be done before frameLength is divided by 2 for LD */
+    filter_bank_init(&hDecoder->fb, hDecoder->frameLength);
+
+#ifdef LD_DEC
+    if (hDecoder->object_type == LD)
+        hDecoder->frameLength >>= 1;
+#endif
+
     return 0;
 }
 
@@ -298,7 +318,7 @@
     syntax_elements[ch_ele]->channel = channels; \
  \
     if ((hInfo->error = single_lfe_channel_element(syntax_elements[ch_ele], \
-        ld, spec_data[channels], sf_index, object_type, \
+        ld, spec_data[channels], sf_index, object_type, frame_len, \
         aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag, \
         aacSpectralDataResilienceFlag)) > 0) \
     { \
@@ -320,7 +340,7 @@
     syntax_elements[ch_ele]->channel = channels; \
  \
     if ((hInfo->error = single_lfe_channel_element(syntax_elements[ch_ele], \
-        ld, spec_data[channels], sf_index, object_type)) > 0) \
+        ld, spec_data[channels], sf_index, object_type, frame_len)) > 0) \
     { \
         /* to make sure everything gets deallocated */ \
         channels++; ch_ele++; \
@@ -346,7 +366,7 @@
  \
     if ((hInfo->error = channel_pair_element(syntax_elements[ch_ele], \
         ld, spec_data[channels], spec_data[channels+1], \
-        sf_index, object_type, \
+        sf_index, object_type, frame_len, \
         aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag, \
         aacSpectralDataResilienceFlag)) > 0) \
     { \
@@ -372,7 +392,7 @@
  \
     if ((hInfo->error = channel_pair_element(syntax_elements[ch_ele], \
         ld, spec_data[channels], spec_data[channels+1], \
-        sf_index, object_type)) > 0) \
+        sf_index, object_type, frame_len)) > 0) \
     { \
         /* to make sure everything gets deallocated */ \
         channels+=2; ch_ele++; \
@@ -430,11 +450,7 @@
     real_t *spec_coef[MAX_CHANNELS];
 
     /* frame length is different for Low Delay AAC */
-    uint16_t frame_len =
-#ifdef LD_DEC
-        (object_type == LD) ? 512 :
-#endif
-        1024;
+    uint16_t frame_len = hDecoder->frameLength;
 
     void *sample_buffer;
 
@@ -606,7 +622,7 @@
             frame_len);
 
         /* apply scalefactors */
-        apply_scalefactors(ics, spec_coef[ch], pow2_table);
+        apply_scalefactors(ics, spec_coef[ch], pow2_table, frame_len);
 
         /* deinterleave short block grouping */
         if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
@@ -644,14 +660,14 @@
 
         /* mid/side decoding */
         if (!right_channel)
-            ms_decode(ics, icsr, spec_coef[ch], spec_coef[pch]);
+            ms_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len);
 
         /* pns decoding */
-        pns_decode(ics, spec_coef[ch]);
+        pns_decode(ics, spec_coef[ch], frame_len);
 
         /* intensity stereo decoding */
         if (!right_channel)
-            is_decode(ics, icsr, spec_coef[ch], spec_coef[pch]);
+            is_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len);
 
 #ifdef MAIN_DEC
         /* MAIN object type prediction */
@@ -661,11 +677,11 @@
             if (pred_stat[ch] == NULL)
             {
                 pred_stat[ch] = malloc(frame_len * sizeof(pred_state));
-                reset_all_predictors(pred_stat[ch]);
-            }
+                reset_all_predictors(pred_stat[ch], frame_len);
+            }
 
             /* intra channel prediction */
-            ic_prediction(ics, spec_coef[ch], pred_stat[ch]);
+            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
@@ -712,7 +728,8 @@
 #endif
 
         /* tns decoding */
-        tns_decode_frame(ics, &(ics->tns), sf_index, object_type, spec_coef[ch]);
+        tns_decode_frame(ics, &(ics->tns), sf_index, object_type,
+            spec_coef[ch], frame_len);
 
         /* drc decoding */
         if (drc->present)
@@ -743,7 +760,7 @@
         /* filter bank */
         ifilter_bank(fb, ics->window_sequence, ics->window_shape,
             window_shape_prev[ch], spec_coef[ch], time_state[ch],
-            time_out[ch], object_type);
+            time_out[ch], object_type, frame_len);
         /* save window shape for next frame */
         window_shape_prev[ch] = ics->window_shape;
 
--- a/libfaad/decoder.h
+++ b/libfaad/decoder.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: decoder.h,v 1.6 2002/05/30 17:55:08 menno Exp $
+** $Id: decoder.h,v 1.7 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -74,6 +74,7 @@
     uint8_t aacSectionDataResilienceFlag;
     uint8_t aacScalefactorDataResilienceFlag;
     uint8_t aacSpectralDataResilienceFlag;
+    uint16_t frameLength;
 
     uint32_t frame;
 
--- a/libfaad/filtbank.c
+++ b/libfaad/filtbank.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: filtbank.c,v 1.8 2002/05/24 17:26:12 menno Exp $
+** $Id: filtbank.c,v 1.9 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include "common.h"
@@ -29,42 +29,46 @@
 #include "mdct.h"
 
 
-void filter_bank_init(fb_info *fb)
+void filter_bank_init(fb_info *fb, uint16_t frame_len)
 {
     uint16_t i;
+    uint16_t nshort = frame_len/8;
+#ifdef LD_DEC
+    uint16_t frame_len_ld = frame_len/2;
+#endif
 
     /* normal */
-    faad_mdct_init(&(fb->mdct256), 256);
-    faad_mdct_init(&(fb->mdct2048), 2048);
+    faad_mdct_init(&(fb->mdct256), 2*nshort);
+    faad_mdct_init(&(fb->mdct2048), 2*frame_len);
 
-    fb->long_window[0]  = malloc(BLOCK_LEN_LONG*sizeof(real_t));
-    fb->short_window[0] = malloc(BLOCK_LEN_SHORT*sizeof(real_t));
+    fb->long_window[0]  = malloc(frame_len*sizeof(real_t));
+    fb->short_window[0] = malloc(nshort*sizeof(real_t));
     fb->long_window[1]  = kbd_long;
     fb->short_window[1] = kbd_short;
 
     /* calculate the sine windows */
-    for (i = 0; i < BLOCK_LEN_LONG; i++)
-        fb->long_window[0][i] = (real_t)sin(M_PI / (2.0 * BLOCK_LEN_LONG) * (i + 0.5));
-    for (i = 0; i < BLOCK_LEN_SHORT; i++)
-        fb->short_window[0][i] = (real_t)sin(M_PI / (2.0 * BLOCK_LEN_SHORT) * (i + 0.5));
+    for (i = 0; i < frame_len; i++)
+        fb->long_window[0][i] = (real_t)sin(M_PI / (2.0 * frame_len) * (i + 0.5));
+    for (i = 0; i < nshort; i++)
+        fb->short_window[0][i] = (real_t)sin(M_PI / (2.0 * nshort) * (i + 0.5));
 
 #ifdef LD_DEC
     /* LD */
-    faad_mdct_init(&(fb->mdct1024), 1024);
+    faad_mdct_init(&(fb->mdct1024), frame_len_ld);
 
-    fb->ld_window[0] = malloc(BLOCK_LEN_LD*sizeof(real_t));
-    fb->ld_window[1] = malloc(BLOCK_LEN_LD*sizeof(real_t));
+    fb->ld_window[0] = malloc(frame_len_ld*sizeof(real_t));
+    fb->ld_window[1] = malloc(frame_len_ld*sizeof(real_t));
 
     /* calculate the sine windows */
-    for (i = 0; i < BLOCK_LEN_LD; i++)
-        fb->ld_window[0][i] = (real_t)sin(M_PI / (2.0 * BLOCK_LEN_LD) * (i + 0.5));
+    for (i = 0; i < frame_len_ld; i++)
+        fb->ld_window[0][i] = (real_t)sin(M_PI / (2.0 * frame_len_ld) * (i + 0.5));
 
     /* low overlap window */
-    for (i = 0; i < 3*(BLOCK_LEN_LD>>3); i++)
+    for (i = 0; i < 3*(frame_len_ld>>3); i++)
         fb->ld_window[1][i] = 0.0;
-    for (; i < 5*(BLOCK_LEN_LD>>3); i++)
-        fb->ld_window[1][i] = (real_t)sin((i-3*(BLOCK_LEN_LD>>3)+0.5) * M_PI / (BLOCK_LEN_LD>>1));
-    for (; i < BLOCK_LEN_LD; i++)
+    for (; i < 5*(frame_len_ld>>3); i++)
+        fb->ld_window[1][i] = (real_t)sin((i-3*(frame_len_ld>>3)+0.5) * M_PI / (frame_len_ld>>1));
+    for (; i < frame_len_ld; i++)
         fb->ld_window[1][i] = 1.0;
 #endif
 }
@@ -179,13 +183,16 @@
     switch (len)
     {
     case 2048:
+    case 1920:
         mdct = &(fb->mdct2048);
         break;
     case 256:
+    case 240:
         mdct = &(fb->mdct256);
         break;
 #ifdef LD_DEC
     case 1024:
+    case 960:
         mdct = &(fb->mdct1024);
         break;
 #endif
@@ -202,13 +209,16 @@
     switch (len)
     {
     case 2048:
+    case 1920:
         mdct = &(fb->mdct2048);
         break;
     case 256:
+    case 120:
         mdct = &(fb->mdct256);
         break;
 #ifdef LD_DEC
     case 1024:
+    case 960:
         mdct = &(fb->mdct1024);
         break;
 #endif
@@ -220,7 +230,7 @@
 
 void ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape,
                   uint8_t window_shape_prev, real_t *freq_in, real_t *time_buff,
-                  real_t *time_out, uint8_t object_type)
+                  real_t *time_out, uint8_t object_type, uint16_t frame_len)
 {
     real_t *o_buf, *transf_buf;
     real_t *obuf_temp;
@@ -233,12 +243,8 @@
 
     real_t *fp;
     int8_t win;
-    uint16_t nlong =
-#ifdef LD_DEC
-        (object_type == LD) ? 512 :
-#endif
-        1024;
-    uint16_t nshort = 128;
+    uint16_t nlong = frame_len;
+    uint16_t nshort = frame_len/8;
 
     uint16_t nflat_ls = (nlong-nshort)/2;
 
@@ -372,7 +378,7 @@
 /* only works for LTP -> no overlapping */
 void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape,
                      uint8_t window_shape_prev, real_t *in_data, real_t *out_mdct,
-                     uint8_t object_type)
+                     uint8_t object_type, uint16_t frame_len)
 {
     int8_t win;
     real_t *windowed_buf;
@@ -384,12 +390,8 @@
     real_t *window_short_prev;
     real_t *window_short_prev_ptr;
 
-    uint16_t nlong =
-#ifdef LD_DEC
-        (object_type == LD) ? 512 :
-#endif
-        1024;
-    uint16_t nshort = 128;
+    uint16_t nlong = frame_len;
+    uint16_t nshort = frame_len/8;
     uint16_t nflat_ls = (nlong-nshort)/2;
 
     windowed_buf = malloc(nlong*2*sizeof(real_t));
--- a/libfaad/filtbank.h
+++ b/libfaad/filtbank.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: filtbank.h,v 1.6 2002/04/07 21:26:04 menno Exp $
+** $Id: filtbank.h,v 1.7 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifndef __FILTBANK_H__
@@ -28,11 +28,7 @@
 
 #include "mdct.h"
 
-#define BLOCK_LEN_LONG  1024
-#define BLOCK_LEN_LD     512
-#define BLOCK_LEN_SHORT  128
 
-
 typedef struct
 {
     real_t *long_window[2];
@@ -48,7 +44,7 @@
     mdct_info mdct2048;
 } fb_info;
 
-void filter_bank_init(fb_info *fb);
+void filter_bank_init(fb_info *fb, uint16_t frame_len);
 void filter_bank_end(fb_info *fb);
 
 #ifdef LTP_DEC
@@ -58,7 +54,8 @@
                      uint8_t window_shape_prev,
                      real_t *in_data,
                      real_t *out_mdct,
-                     uint8_t object_type);
+                     uint8_t object_type,
+                     uint16_t frame_len);
 #endif
 
 void ifilter_bank(fb_info *fb,
@@ -68,7 +65,8 @@
                   real_t *freq_in,
                   real_t *time_buff,
                   real_t *time_out,
-                  uint8_t object_type);
+                  uint8_t object_type,
+                  uint16_t frame_len);
 
 #ifdef __cplusplus
 }
--- a/libfaad/ic_predict.c
+++ b/libfaad/ic_predict.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: ic_predict.c,v 1.5 2002/06/03 15:03:46 menno Exp $
+** $Id: ic_predict.c,v 1.6 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include "common.h"
@@ -131,16 +131,17 @@
     }
 }
 
-void reset_all_predictors(pred_state *state)
+void reset_all_predictors(pred_state *state, uint16_t frame_len)
 {
     uint16_t i;
 
-    for (i = 0; i < 1024; i++)
+    for (i = 0; i < frame_len; i++)
         reset_pred_state(&state[i]);
 }
 
 /* intra channel prediction */
-void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state)
+void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
+                   uint16_t frame_len)
 {
     uint8_t sfb;
     uint16_t bin;
@@ -147,7 +148,7 @@
 
     if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
     {
-        reset_all_predictors(state);
+        reset_all_predictors(state, frame_len);
     } else {
         for (sfb = 0; sfb < ics->pred.limit; sfb++)
         {
@@ -167,7 +168,7 @@
             if (ics->pred.predictor_reset)
             {
                 for (bin = ics->pred.predictor_reset_group_number - 1;
-                     bin < 1024; bin += 30)
+                     bin < frame_len; bin += 30)
                 {
                     reset_pred_state(&state[bin]);
                 }
--- a/libfaad/ic_predict.h
+++ b/libfaad/ic_predict.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: ic_predict.h,v 1.3 2002/03/16 13:38:37 menno Exp $
+** $Id: ic_predict.h,v 1.4 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifdef MAIN_DEC
@@ -42,8 +42,9 @@
 
 
 void pns_reset_pred_state(ic_stream *ics, pred_state *state);
-void reset_all_predictors(pred_state *state);
-void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state);
+void reset_all_predictors(pred_state *state, uint16_t frame_len);
+void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
+                   uint16_t frame_len);
 
 
 #ifdef __cplusplus
--- a/libfaad/is.c
+++ b/libfaad/is.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: is.c,v 1.5 2002/05/24 17:26:12 menno Exp $
+** $Id: is.c,v 1.6 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include "common.h"
@@ -24,12 +24,14 @@
 #include "syntax.h"
 #include "is.h"
 
-void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec)
+void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+               uint16_t frame_len)
 {
     uint8_t g, sfb, b;
     uint16_t i, k;
     real_t scale;
 
+    uint16_t nshort = frame_len/8;
     uint8_t group = 0;
 
     for (g = 0; g < icsr->num_window_groups; g++)
@@ -56,7 +58,7 @@
                        do not touch left channel */
                     for (i = icsr->swb_offset[sfb]; i < icsr->swb_offset[sfb+1]; i++)
                     {
-                        k = (group*128)+i;
+                        k = (group*nshort)+i;
                         r_spec[k] = MUL(l_spec[k], scale);
                     }
                 }
--- a/libfaad/is.h
+++ b/libfaad/is.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: is.h,v 1.3 2002/02/18 10:01:05 menno Exp $
+** $Id: is.h,v 1.4 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifndef __IS_H__
@@ -28,7 +28,8 @@
 
 #include "syntax.h"
 
-void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec);
+void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+               uint16_t frame_len);
 
 static INLINE int8_t is_intensity(ic_stream *ics, uint8_t group, uint8_t sfb)
 {
--- a/libfaad/lt_predict.c
+++ b/libfaad/lt_predict.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: lt_predict.c,v 1.5 2002/05/24 17:26:12 menno Exp $
+** $Id: lt_predict.c,v 1.6 2002/06/13 11:03:27 menno Exp $
 **/
 
 
@@ -64,9 +64,10 @@
             }
 
             filter_bank_ltp(fb, ics->window_sequence, win_shape, win_shape_prev,
-                x_est, X_est, object_type);
+                x_est, X_est, object_type, frame_len);
 
-            tns_encode_frame(ics, &(ics->tns), sr_index, object_type, X_est);
+            tns_encode_frame(ics, &(ics->tns), sr_index, object_type, X_est,
+                frame_len);
 
             for (sfb = 0; sfb < ltp->last_band; sfb++)
             {
--- a/libfaad/mp4.c
+++ b/libfaad/mp4.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: mp4.c,v 1.7 2002/05/30 18:31:51 menno Exp $
+** $Id: mp4.c,v 1.8 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include "common.h"
@@ -66,7 +66,7 @@
     0, /* ER TwinVQ */
     0, /* ER BSAC */
 #ifdef LD_DEC
-    1, /* ER AAC LD */     /* !!! Supported, but only with ER turned off !!! */
+    1, /* ER AAC LD */
 #else
     0, /* ER AAC LD */
 #endif
@@ -101,7 +101,8 @@
                                    uint8_t *object_type,
                                    uint8_t *aacSectionDataResilienceFlag,
                                    uint8_t *aacScalefactorDataResilienceFlag,
-                                   uint8_t *aacSpectralDataResilienceFlag)
+                                   uint8_t *aacSpectralDataResilienceFlag,
+                                   uint8_t *frameLengthFlag)
 {
     bitfile ld;
     uint8_t ObjectTypeIndex, SamplingFrequencyIndex, ChannelsConfiguration;
@@ -149,13 +150,15 @@
         return GASpecificConfig(&ld, channels, ObjectTypeIndex,
             aacSectionDataResilienceFlag,
             aacScalefactorDataResilienceFlag,
-            aacSpectralDataResilienceFlag);
+            aacSpectralDataResilienceFlag,
+            frameLengthFlag);
 #ifdef ERROR_RESILIENCE
     } else if (ObjectTypeIndex >= ER_OBJECT_START) { /* ER */
         uint8_t result = GASpecificConfig(&ld, channels, ObjectTypeIndex,
             aacSectionDataResilienceFlag,
             aacScalefactorDataResilienceFlag,
-            aacSpectralDataResilienceFlag);
+            aacSpectralDataResilienceFlag,
+            frameLengthFlag);
         uint8_t ep_config = (uint8_t)faad_getbits(&ld, 2
             DEBUGVAR(1,143,"parse_audio_decoder_specific_info(): epConfig"));
         if (ep_config != 0)
--- a/libfaad/mp4.h
+++ b/libfaad/mp4.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: mp4.h,v 1.4 2002/05/30 17:55:08 menno Exp $
+** $Id: mp4.h,v 1.5 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifndef __MP4_H__
@@ -35,7 +35,8 @@
                                    uint8_t *object_type,
                                    uint8_t *aacSectionDataResilienceFlag,
                                    uint8_t *aacScalefactorDataResilienceFlag,
-                                   uint8_t *aacSpectralDataResilienceFlag);
+                                   uint8_t *aacSpectralDataResilienceFlag,
+                                   uint8_t *frameLengthFlag);
 
 #ifdef __cplusplus
 }
--- a/libfaad/ms.c
+++ b/libfaad/ms.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: ms.c,v 1.2 2002/02/18 10:01:05 menno Exp $
+** $Id: ms.c,v 1.3 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include "common.h"
@@ -25,10 +25,12 @@
 #include "is.h"
 #include "pns.h"
 
-void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec)
+void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+               uint16_t frame_len)
 {
     uint8_t g, b, sfb;
     uint8_t group = 0;
+    uint16_t nshort = frame_len/8;
 
     uint16_t i, k;
     real_t tmp;
@@ -50,7 +52,7 @@
                     {
                         for (i = ics->swb_offset[sfb]; i < ics->swb_offset[sfb+1]; i++)
                         {
-                            k = (group*128) + i;
+                            k = (group*nshort) + i;
                             tmp = l_spec[k] - r_spec[k];
                             l_spec[k] = l_spec[k] + r_spec[k];
                             r_spec[k] = tmp;
--- a/libfaad/ms.h
+++ b/libfaad/ms.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: ms.h,v 1.2 2002/02/18 10:01:05 menno Exp $
+** $Id: ms.h,v 1.3 2002/06/13 11:03:27 menno Exp $
 **/
 
 #ifndef __MS_H__
@@ -26,7 +26,8 @@
 extern "C" {
 #endif
 
-void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec);
+void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+               uint16_t frame_len);
 
 #ifdef __cplusplus
 }
--- a/libfaad/pns.c
+++ b/libfaad/pns.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: pns.c,v 1.6 2002/05/24 17:26:12 menno Exp $
+** $Id: pns.c,v 1.7 2002/06/13 11:03:27 menno Exp $
 **/
 
 #include "common.h"
@@ -76,12 +76,13 @@
         spec[i] = MUL(spec[i], scale);
 }
 
-void pns_decode(ic_stream *ics, real_t *spec)
+void pns_decode(ic_stream *ics, real_t *spec, uint16_t frame_len)
 {
     uint8_t g, sfb, b;
     uint16_t size, offs;
 
     uint8_t group = 0;
+    uint16_t nshort = frame_len/8;
 
     for (g = 0; g < ics->num_window_groups; g++)
     {
@@ -109,7 +110,7 @@
                     size = ics->swb_offset[sfb+1] - offs;
 
                     /* Generate random vector */
-                    gen_rand_vector(&spec[(group*128)+offs],
+                    gen_rand_vector(&spec[(group*nshort)+offs],
                         ics->scale_factors[g][sfb], size);
                 }
             }
--- a/libfaad/pns.h
+++ b/libfaad/pns.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: pns.h,v 1.4 2002/02/18 10:01:05 menno Exp $
+** $Id: pns.h,v 1.5 2002/06/13 11:03:28 menno Exp $
 **/
 
 #ifndef __PNS_H__
@@ -33,7 +33,7 @@
 #define MEAN_NRG 1.537228e+18 /* (2^31)^2 / 3 */
 
 
-void pns_decode(ic_stream *ics, real_t *spec);
+void pns_decode(ic_stream *ics, real_t *spec, uint16_t frame_len);
 
 static INLINE int32_t random2();
 static void gen_rand_vector(real_t *spec, uint16_t scale_factor, uint16_t size);
--- a/libfaad/reordered_spectral_data.c
+++ b/libfaad/reordered_spectral_data.c
@@ -360,6 +360,7 @@
     
     uint8_t PCW_decoded=0;
     uint16_t segment_index=0, codeword_index=0;
+    uint16_t nshort = frame_len/8;
     
 
     memset (spectral_data, 0, frame_len*sizeof(uint16_t));
@@ -371,7 +372,7 @@
     
     sp_offset[0] = 0;
     for (g=1; g < ics->num_window_groups; g++) {
-    	sp_offset[g] = sp_offset[g-1] + 128*ics->window_group_length[g-1];
+    	sp_offset[g] = sp_offset[g-1] + nshort*ics->window_group_length[g-1];
     }
         
 	/* All data is sorted according to the codebook used */        
--- a/libfaad/specrec.c
+++ b/libfaad/specrec.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: specrec.c,v 1.7 2002/05/24 17:26:12 menno Exp $
+** $Id: specrec.c,v 1.8 2002/06/13 11:03:28 menno Exp $
 **/
 
 /*
@@ -49,7 +49,7 @@
     scale_factor_grouping and is needed to decode the spectral_data().
 */
 uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index,
-                             uint8_t object_type)
+                             uint8_t object_type, uint16_t frame_len)
 {
     uint8_t i, g;
 
@@ -76,18 +76,22 @@
 #ifdef LD_DEC
         if (object_type == LD)
         {
-            for (i = 0; i < ics->num_swb + 1; i++)
+            for (i = 0; i < ics->num_swb; i++)
             {
                 ics->sect_sfb_offset[0][i] = swb_offset_512_window[fs_index][i];
                 ics->swb_offset[i] = swb_offset_512_window[fs_index][i];
             }
+            ics->sect_sfb_offset[0][ics->num_swb] = frame_len;
+            ics->swb_offset[ics->num_swb] = frame_len;
         } else {
 #endif
-            for (i = 0; i < ics->num_swb + 1; i++)
+            for (i = 0; i < ics->num_swb; i++)
             {
                 ics->sect_sfb_offset[0][i] = swb_offset_1024_window[fs_index][i];
                 ics->swb_offset[i] = swb_offset_1024_window[fs_index][i];
             }
+            ics->sect_sfb_offset[0][ics->num_swb] = frame_len;
+            ics->swb_offset[ics->num_swb] = frame_len;
 #ifdef LD_DEC
         }
 #endif
@@ -98,8 +102,9 @@
         ics->window_group_length[ics->num_window_groups-1] = 1;
         ics->num_swb = num_swb_128_window[fs_index];
 
-        for (i = 0; i < ics->num_swb + 1; i++)
+        for (i = 0; i < ics->num_swb; i++)
             ics->swb_offset[i] = swb_offset_128_window[fs_index][i];
+        ics->swb_offset[ics->num_swb] = frame_len/8;
 
         for (i = 0; i < ics->num_windows-1; i++) {
             if (bit_set(ics->scale_factor_grouping, 6-i) == 0)
@@ -120,8 +125,13 @@
 
             for (i = 0; i < ics->num_swb; i++)
             {
-                width = swb_offset_128_window[fs_index][i+1] -
-                    swb_offset_128_window[fs_index][i];
+                if (i+1 == ics->num_swb)
+                {
+                    width = (frame_len/8) - swb_offset_128_window[fs_index][i];
+                } else {
+                    width = swb_offset_128_window[fs_index][i+1] -
+                        swb_offset_128_window[fs_index][i];
+                }
                 width *= ics->window_group_length[g];
                 ics->sect_sfb_offset[g][sect_sfb++] = offset;
                 offset += width;
@@ -295,12 +305,14 @@
         return (real_t)exp(LN2 * 0.25 * (scale_factor - 100));
 }
 
-void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table)
+void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
+                        uint16_t frame_len)
 {
     uint8_t g, sfb;
     uint16_t top;
     real_t *fp, scale;
     uint8_t groups = 0;
+    uint16_t nshort = frame_len/8;
 
     for (g = 0; g < ics->num_window_groups; g++)
     {
@@ -310,7 +322,7 @@
            long blocks only have 1 group, so that means 'groups' is
            always 0 for long blocks
         */
-        fp = x_invquant + (groups*128);
+        fp = x_invquant + (groups*nshort);
 
         for (sfb = 0; sfb < ics->max_sfb; sfb++)
         {
--- a/libfaad/specrec.h
+++ b/libfaad/specrec.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: specrec.h,v 1.4 2002/03/16 13:38:36 menno Exp $
+** $Id: specrec.h,v 1.5 2002/06/13 11:03:28 menno Exp $
 **/
 
 #ifndef __SPECREC_H__
@@ -34,12 +34,14 @@
 #define POW_TABLE_SIZE  200
 
 
-uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index, uint8_t object_type);
+uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index,
+                             uint8_t object_type, uint16_t frame_len);
 void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len);
 void build_tables(real_t *iq_table, real_t *pow2_table);
 void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table,
                           uint16_t frame_len);
-void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table);
+void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
+                        uint16_t frame_len);
 
 
 #ifdef __cplusplus
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: syntax.c,v 1.17 2002/06/13 08:00:27 menno Exp $
+** $Id: syntax.c,v 1.18 2002/06/13 11:03:28 menno Exp $
 **/
 
 /*
@@ -47,14 +47,15 @@
                          uint8_t object_type,
                          uint8_t *aacSectionDataResilienceFlag,
                          uint8_t *aacScalefactorDataResilienceFlag,
-                         uint8_t *aacSpectralDataResilienceFlag)
+                         uint8_t *aacSpectralDataResilienceFlag,
+                         uint8_t *frameLengthFlag)
 {
-    uint8_t frameLengthFlag, dependsOnCoreCoder, extensionFlag;
+    uint8_t dependsOnCoreCoder, extensionFlag;
     uint16_t coreCoderDelay;
     program_config pce;
 
     /* 1024 or 960 */
-    frameLengthFlag = faad_get1bit(ld
+    *frameLengthFlag = faad_get1bit(ld
         DEBUGVAR(1,138,"GASpecificConfig(): FrameLengthFlag"));
 
     dependsOnCoreCoder = faad_get1bit(ld
@@ -232,7 +233,8 @@
 /* Table 4.4.4 and */
 /* Table 4.4.9 */
 uint8_t single_lfe_channel_element(element *sce, bitfile *ld, int16_t *spec_data,
-                                   uint8_t sf_index, uint8_t object_type
+                                   uint8_t sf_index, uint8_t object_type,
+                                   uint16_t frame_len
 #ifdef ERROR_RESILIENCE
                                    ,uint8_t aacSectionDataResilienceFlag,
                                    uint8_t aacScalefactorDataResilienceFlag,
@@ -246,7 +248,7 @@
         DEBUGVAR(1,38,"single_lfe_channel_element(): element_instance_tag"));
 
     return individual_channel_stream(sce, ld, ics, 0, spec_data, sf_index,
-        object_type
+        object_type, frame_len
 #ifdef ERROR_RESILIENCE
         ,aacSectionDataResilienceFlag,
         aacScalefactorDataResilienceFlag,
@@ -257,7 +259,8 @@
 
 /* Table 4.4.5 */
 uint8_t channel_pair_element(element *cpe, bitfile *ld, int16_t *spec_data1,
-                             int16_t *spec_data2, uint8_t sf_index, uint8_t object_type
+                             int16_t *spec_data2, uint8_t sf_index, uint8_t object_type,
+                             uint16_t frame_len
 #ifdef ERROR_RESILIENCE
                              ,uint8_t aacSectionDataResilienceFlag,
                              uint8_t aacScalefactorDataResilienceFlag,
@@ -277,7 +280,7 @@
     {
         /* both channels have common ics information */
         if ((result = ics_info(ics1, ld, cpe->common_window, sf_index,
-            object_type)) > 0)
+            object_type, frame_len)) > 0)
             return result;
 
         ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
@@ -301,7 +304,7 @@
     }
 
     if ((result = individual_channel_stream(cpe, ld, ics1, 0, spec_data1,
-        sf_index, object_type
+        sf_index, object_type, frame_len
 #ifdef ERROR_RESILIENCE
         ,aacSectionDataResilienceFlag,
         aacScalefactorDataResilienceFlag,
@@ -310,7 +313,7 @@
         )) > 0)
         return result;
     if ((result = individual_channel_stream(cpe, ld, ics2, 0, spec_data2,
-        sf_index, object_type
+        sf_index, object_type, frame_len
 #ifdef ERROR_RESILIENCE
         ,aacSectionDataResilienceFlag,
         aacScalefactorDataResilienceFlag,
@@ -324,7 +327,7 @@
 
 /* Table 4.4.6 */
 static uint8_t ics_info(ic_stream *ics, bitfile *ld, uint8_t common_window,
-                    uint8_t sf_index, uint8_t object_type)
+                    uint8_t sf_index, uint8_t object_type, uint16_t frame_len)
 {
     /* ics->ics_reserved_bit = */ faad_get1bit(ld
         DEBUGVAR(1,43,"ics_info(): ics_reserved_bit"));
@@ -386,7 +389,7 @@
     }
 
     /* get the grouping information */
-    return window_grouping_info(ics, sf_index, object_type);
+    return window_grouping_info(ics, sf_index, object_type, frame_len);
 }
 
 /* Table 4.4.7 */
@@ -598,7 +601,7 @@
 static uint8_t individual_channel_stream(element *ele, bitfile *ld,
                                      ic_stream *ics, uint8_t scal_flag,
                                      int16_t *spec_data, uint8_t sf_index,
-                                     uint8_t object_type
+                                     uint8_t object_type, uint16_t frame_len
 #ifdef ERROR_RESILIENCE
                                      ,uint8_t aacSectionDataResilienceFlag,
                                      uint8_t aacScalefactorDataResilienceFlag,
@@ -607,11 +610,6 @@
                                      )
 {
     uint8_t result;
-    uint16_t frame_len =
-#ifdef LD_DEC
-        (object_type == LD) ? 512 :
-#endif
-        1024;
 
     ics->global_gain = (uint8_t)faad_getbits(ld, 8
         DEBUGVAR(1,67,"individual_channel_stream(): global_gain"));
@@ -619,7 +617,7 @@
     if (!ele->common_window && !scal_flag)
     {
         if ((result = ics_info(ics, ld, ele->common_window, sf_index,
-            object_type)) > 0)
+            object_type, frame_len)) > 0)
             return result;
     }
     section_data(ics, ld
@@ -1087,6 +1085,7 @@
     uint16_t k, p = 0;
     uint8_t groups = 0;
     uint8_t sect_cb;
+    uint16_t nshort = frame_len/8;
 
     sp = spectral_data;
     for (i = frame_len/16-1; i >= 0; --i)
@@ -1099,7 +1098,7 @@
 
     for(g = 0; g < ics->num_window_groups; g++)
     {
-        p = groups*128;
+        p = groups*nshort;
 
         for (i = 0; i < ics->num_sec[g]; i++)
         {
--- a/libfaad/syntax.h
+++ b/libfaad/syntax.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: syntax.h,v 1.12 2002/06/13 08:00:28 menno Exp $
+** $Id: syntax.h,v 1.13 2002/06/13 11:03:28 menno Exp $
 **/
 
 #ifndef __SYNTAX_H__
@@ -273,7 +273,8 @@
                          uint8_t object_type,
                          uint8_t *aacSectionDataResilienceFlag,
                          uint8_t *aacScalefactorDataResilienceFlag,
-                         uint8_t *aacSpectralDataResilienceFlag);
+                         uint8_t *aacSpectralDataResilienceFlag,
+                         uint8_t *frameLengthFlag);
 uint8_t raw_data_block(bitfile *ld, int16_t ***spec_data, real_t ***spec_coef,
                        element ***syntax_elements,
                        uint8_t *channels, uint8_t *ele, uint8_t *ch_ele,
@@ -280,7 +281,8 @@
                        uint16_t frame_len, uint8_t sf_index, uint8_t object_type,
                        drc_info *drc);
 uint8_t single_lfe_channel_element(element *sce, bitfile *ld, int16_t *spec_data,
-                                   uint8_t sf_index, uint8_t object_type
+                                   uint8_t sf_index, uint8_t object_type,
+                                   uint16_t frame_len
 #ifdef ERROR_RESILIENCE
                                    ,uint8_t aacSectionDataResilienceFlag,
                                    uint8_t aacScalefactorDataResilienceFlag,
@@ -288,7 +290,8 @@
 #endif
                                    );
 uint8_t channel_pair_element(element *cpe, bitfile *ld, int16_t *spec_data1,
-                             int16_t *spec_data2, uint8_t sf_index, uint8_t object_type
+                             int16_t *spec_data2, uint8_t sf_index, uint8_t object_type,
+                             uint16_t frame_len
 #ifdef ERROR_RESILIENCE
                              ,uint8_t aacSectionDataResilienceFlag,
                              uint8_t aacScalefactorDataResilienceFlag,
@@ -310,7 +313,7 @@
 static uint8_t individual_channel_stream(element *ele, bitfile *ld,
                                      ic_stream *ics, uint8_t scal_flag,
                                      int16_t *spec_data, uint8_t sf_index,
-                                     uint8_t object_type
+                                     uint8_t object_type, uint16_t frame_len
 #ifdef ERROR_RESILIENCE
                                      ,uint8_t aacSectionDataResilienceFlag,
                                      uint8_t aacScalefactorDataResilienceFlag,
@@ -317,8 +320,9 @@
                                      uint8_t aacSpectralDataResilienceFlag
 #endif
                                      );
-static uint8_t ics_info(ic_stream *ics, bitfile *ld,
-                    uint8_t common_window, uint8_t fs_index, uint8_t object_type);
+static uint8_t ics_info(ic_stream *ics, bitfile *ld, uint8_t common_window,
+                        uint8_t fs_index, uint8_t object_type,
+                        uint16_t frame_len);
 static void section_data(ic_stream *ics, bitfile *ld
 #ifdef ERROR_RESILIENCE
                          ,uint8_t aacSectionDataResilienceFlag
--- a/libfaad/tns.c
+++ b/libfaad/tns.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: tns.c,v 1.11 2002/05/30 18:31:51 menno Exp $
+** $Id: tns.c,v 1.12 2002/06/13 11:03:28 menno Exp $
 **/
 
 #include "common.h"
@@ -27,11 +27,12 @@
 
 /* TNS decoding for one channel and frame */
 void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
-                      uint8_t object_type, real_t *spec)
+                      uint8_t object_type, real_t *spec, uint16_t frame_len)
 {
     uint8_t w, f, tns_order;
     int8_t inc;
     uint16_t bottom, top, start, end, size;
+    uint16_t nshort = frame_len/8;
     real_t lpc[TNS_MAX_ORDER+1];
 
     if (!ics->tns_data_present)
@@ -69,7 +70,7 @@
                 inc = 1;
             }
 
-            tns_ar_filter(&spec[(w*128)+start], size, inc, lpc, tns_order);
+            tns_ar_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order);
         }
     }
 }
@@ -76,11 +77,12 @@
 
 /* TNS encoding for one channel and frame */
 void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
-                      uint8_t object_type, real_t *spec)
+                      uint8_t object_type, real_t *spec, uint16_t frame_len)
 {
     uint8_t w, f, tns_order;
     int8_t inc;
     uint16_t bottom, top, start, end, size;
+    uint16_t nshort = frame_len/8;
     real_t lpc[TNS_MAX_ORDER+1];
 
     if (!ics->tns_data_present)
@@ -118,7 +120,7 @@
                 inc = 1;
             }
 
-            tns_ma_filter(&spec[(w*128)+start], size, inc, lpc, tns_order);
+            tns_ma_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order);
         }
     }
 }
--- a/libfaad/tns.h
+++ b/libfaad/tns.h
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: tns.h,v 1.3 2002/02/25 19:58:33 menno Exp $
+** $Id: tns.h,v 1.4 2002/06/13 11:03:28 menno Exp $
 **/
 
 #ifndef __TNS_H__
@@ -31,9 +31,9 @@
 
     
 void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
-                      uint8_t object_type, real_t *spec);
+                      uint8_t object_type, real_t *spec, uint16_t frame_len);
 void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
-                      uint8_t object_type, real_t *spec);
+                      uint8_t object_type, real_t *spec, uint16_t frame_len);
 
 static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress,
                             uint8_t *coef, real_t *a);