shithub: aacdec

Download patch

ref: 3eb36590b9a63b1b719b0f3167c602d1f1bae049
parent: 9f66d4715e4ec93e00dd5cb88579d7f37b36ad0e
author: menno <menno>
date: Sat Apr 3 05:49:15 EST 2004

bugfix in SBR hf gen
better disabling of MAIN and LTP decoding
DRM API change

--- a/include/neaacdec.h
+++ b/include/neaacdec.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: neaacdec.h,v 1.3 2004/03/19 15:35:59 menno Exp $
+** $Id: neaacdec.h,v 1.4 2004/04/03 10:49:14 menno Exp $
 **/
 
 #ifndef __NEAACDEC_H__
@@ -215,7 +215,7 @@
                                unsigned long *samplerate, unsigned char *channels);
 
 /* Init the library for DRM */
-char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle hDecoder, unsigned long samplerate,
+char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, unsigned long samplerate,
                                  unsigned char channels);
 
 void NEAACDECAPI NeAACDecPostSeekReset(NeAACDecHandle hDecoder, long frame);
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.c
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: decoder.c,v 1.101 2004/03/19 15:35:35 menno Exp $
+** $Id: decoder.c,v 1.102 2004/04/03 10:49:14 menno Exp $
 **/
 
 #include "common.h"
@@ -392,89 +392,42 @@
 }
 
 #ifdef DRM
-int8_t NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle hDecoder, uint32_t samplerate,
+int8_t NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, uint32_t samplerate,
                                    uint8_t channels)
 {
-    uint8_t i;
-
     if (hDecoder == NULL)
         return 1; /* error */
 
+    NeAACDecClose(*hDecoder);
+
+    *hDecoder = NeAACDecOpen();
+
     /* Special object type defined for DRM */
-    hDecoder->config.defObjectType = DRM_ER_LC;
+    (*hDecoder)->config.defObjectType = DRM_ER_LC;
 
-    hDecoder->config.defSampleRate = samplerate;
+    (*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 */
+    (*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;
+    (*hDecoder)->frameLength = 960;
+    (*hDecoder)->sf_index = get_sr_index((*hDecoder)->config.defSampleRate);
+    (*hDecoder)->object_type = (*hDecoder)->config.defObjectType;
 
     if ((channels == DRMCH_STEREO) || (channels == DRMCH_SBR_STEREO))
-        hDecoder->channelConfiguration = 2;
+        (*hDecoder)->channelConfiguration = 2;
     else
-        hDecoder->channelConfiguration = 1;
+        (*hDecoder)->channelConfiguration = 1;
 
 #ifdef SBR_DEC
     if ((channels == DRMCH_MONO) || (channels == DRMCH_STEREO))
-        hDecoder->sbr_present_flag = 0;
+        (*hDecoder)->sbr_present_flag = 0;
     else
-        hDecoder->sbr_present_flag = 1;
+        (*hDecoder)->sbr_present_flag = 1;    
+#endif        
 
-    /* Reset sbr for new initialization */
-    sbrDecodeEnd(hDecoder->sbr[0]);
-    hDecoder->sbr[0] = NULL;
-#endif
-
-    if (hDecoder->fb) filter_bank_end(hDecoder->fb);
-    hDecoder->fb = NULL;
-
-    /* Take care of buffers */
-    if (hDecoder->sample_buffer) faad_free(hDecoder->sample_buffer);
-    hDecoder->sample_buffer = NULL;
-    hDecoder->alloced_channels = 0;
-
-    for (i = 0; i < MAX_CHANNELS; i++)
-    {
-        hDecoder->window_shape_prev[i] = 0;
-
-        if (hDecoder->time_out[i]) faad_free(hDecoder->time_out[i]);
-        hDecoder->time_out[i] = NULL;
-        if (hDecoder->fb_intermed[i]) faad_free(hDecoder->fb_intermed[i]);
-        hDecoder->fb_intermed[i] = NULL;
-#ifdef SSR_DEC
-        if (hDecoder->ssr_overlap[i]) faad_free(hDecoder->ssr_overlap[i]);
-        hDecoder->ssr_overlap[i] = NULL;
-        if (hDecoder->prev_fmd[i]) faad_free(hDecoder->prev_fmd[i]);
-        hDecoder->prev_fmd[i] = NULL;
-#endif
-#ifdef MAIN_DEC
-        if (hDecoder->pred_stat[i]) faad_free(hDecoder->pred_stat[i]);
-        hDecoder->pred_stat[i] = NULL;
-#endif
-#ifdef LTP_DEC
-        hDecoder->ltp_lag[i] = 0;
-        if (hDecoder->lt_pred_stat[i]) faad_free(hDecoder->lt_pred_stat[i]);
-        hDecoder->lt_pred_stat[i] = NULL;
-#endif
-    }
-
-    for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++)
-    {
-#ifdef SBR_DEC
-        if (hDecoder->sbr[i])
-            sbrDecodeEnd(hDecoder->sbr[i]);
-
-        hDecoder->sbr_alloced[i] = 0;
-#endif
-        hDecoder->element_alloced[i] = 0;
-        hDecoder->element_output_channels[i] = 0;
-    }
-
-    hDecoder->fb = filter_bank_init(hDecoder->frameLength);
+    (*hDecoder)->fb = filter_bank_init((*hDecoder)->frameLength);
 
     return 0;
 }
--- 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.40 2004/03/19 15:35:35 menno Exp $
+** $Id: decoder.h,v 1.41 2004/04/03 10:49:14 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -94,7 +94,7 @@
                                  uint32_t *samplerate, uint8_t *channels);
 
 /* Init the library for DRM */
-int8_t NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle hDecoder, uint32_t samplerate,
+int8_t NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, uint32_t samplerate,
                                    uint8_t channels);
 
 void NEAACDECAPI NeAACDecClose(NeAACDecHandle hDecoder);
--- a/libfaad/error.c
+++ b/libfaad/error.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: error.c,v 1.24 2004/03/10 19:45:41 menno Exp $
+** $Id: error.c,v 1.25 2004/04/03 10:49:14 menno Exp $
 **/
 
 #include "common.h"
@@ -54,6 +54,7 @@
     "Error in program_config_element",
     "First SBR frame is not the same as first AAC frame",
     "Unexpected fill element with SBR data",
-    "Not all elements were provided with SBR data"
+    "Not all elements were provided with SBR data",
+    "LTP decoding not available"
 };
 
--- a/libfaad/error.h
+++ b/libfaad/error.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: error.h,v 1.18 2004/03/10 19:45:41 menno Exp $
+** $Id: error.h,v 1.19 2004/04/03 10:49:14 menno Exp $
 **/
 
 #ifndef __ERROR_H__
@@ -32,7 +32,7 @@
 extern "C" {
 #endif
 
-#define NUM_ERROR_MESSAGES 26
+#define NUM_ERROR_MESSAGES 27
 extern char *err_msg[];
 
 #ifdef __cplusplus
--- a/libfaad/is.c
+++ b/libfaad/is.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: is.c,v 1.21 2004/02/26 09:29:27 menno Exp $
+** $Id: is.c,v 1.24 2004/09/04 14:56:28 menno Exp $
 **/
 
 #include "common.h"
@@ -66,6 +66,7 @@
             {
                 if (is_intensity(icsr, g, sfb))
                 {
+#ifdef MAIN_DEC
                     /* For scalefactor bands coded in intensity stereo the
                        corresponding predictors in the right channel are
                        switched to "off".
@@ -72,6 +73,7 @@
                      */
                     ics->pred.prediction_used[sfb] = 0;
                     icsr->pred.prediction_used[sfb] = 0;
+#endif
 
 #ifndef FIXED_POINT
                     scale = (real_t)pow(0.5, (0.25*icsr->scale_factors[g][sfb]));
--- a/libfaad/pns.c
+++ b/libfaad/pns.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: pns.c,v 1.31 2004/03/27 11:14:49 menno Exp $
+** $Id: pns.c,v 1.34 2004/09/04 14:56:28 menno Exp $
 **/
 
 #include "common.h"
@@ -184,6 +184,7 @@
             {
                 if (is_noise(ics_left, g, sfb))
                 {
+#ifdef LTP_DEC
                     /* Simultaneous use of LTP and PNS is not prevented in the
                        syntax. If both LTP, and PNS are enabled on the same
                        scalefactor band, PNS takes precedence, and no prediction
@@ -191,11 +192,14 @@
                     */
                     ics_left->ltp.long_used[sfb] = 0;
                     ics_left->ltp2.long_used[sfb] = 0;
+#endif
 
+#ifdef MAIN_DEC
                     /* For scalefactor bands coded using PNS the corresponding
                        predictors are switched to "off".
                     */
                     ics_left->pred.prediction_used[sfb] = 0;
+#endif
 
                     offs = ics_left->swb_offset[sfb];
                     size = ics_left->swb_offset[sfb+1] - offs;
@@ -237,9 +241,13 @@
                                     spec_left[(group*nshort) + offs + c];
                             }
                         } else /*if (ics_left->ms_mask_present == 0)*/ {
+#ifdef LTP_DEC
                             ics_right->ltp.long_used[sfb] = 0;
                             ics_right->ltp2.long_used[sfb] = 0;
+#endif
+#ifdef MAIN_DEC
                             ics_right->pred.prediction_used[sfb] = 0;
+#endif
 
                             offs = ics_right->swb_offset[sfb];
                             size = ics_right->swb_offset[sfb+1] - offs;
--- a/libfaad/ps_dec.c
+++ b/libfaad/ps_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: ps_dec.c,v 1.3 2004/03/27 11:14:49 menno Exp $
+** $Id: ps_dec.c,v 1.4 2004/04/03 10:49:14 menno Exp $
 **/
 
 #include "common.h"
@@ -250,6 +250,61 @@
     }
 }
 
+/* complex filter, size 4 */
+static void channel_filter4(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
+                            qmf_t *buffer, qmf_t **X_hybrid)
+{
+    uint8_t i;
+    real_t input_re1[2], input_re2[2], input_im1[2], input_im2[2];
+
+    for (i = 0; i < frame_len; i++)
+    {
+        input_re1[0] = -MUL_F(filter[2], (QMF_RE(buffer[i+2]) + QMF_RE(buffer[i+10]))) +
+            MUL_F(filter[6], QMF_RE(buffer[i+6]));
+        input_re1[1] = MUL_F(FRAC_CONST(-0.70710678118655),
+            (MUL_F(filter[1], (QMF_RE(buffer[i+1]) + QMF_RE(buffer[i+11]))) +
+            MUL_F(filter[3], (QMF_RE(buffer[i+3]) + QMF_RE(buffer[i+9]))) -
+            MUL_F(filter[5], (QMF_RE(buffer[i+5]) + QMF_RE(buffer[i+7])))));
+
+        input_im1[0] = MUL_F(filter[0], (QMF_IM(buffer[i+0]) - QMF_IM(buffer[i+12]))) -
+            MUL_F(filter[4], (QMF_IM(buffer[i+4]) - QMF_IM(buffer[i+8])));
+        input_im1[1] = MUL_F(FRAC_CONST(0.70710678118655),
+            (MUL_F(filter[1], (QMF_IM(buffer[i+1]) - QMF_IM(buffer[i+11]))) -
+            MUL_F(filter[3], (QMF_IM(buffer[i+3]) - QMF_IM(buffer[i+9]))) -
+            MUL_F(filter[5], (QMF_IM(buffer[i+5]) - QMF_IM(buffer[i+7])))));
+
+        input_re2[0] = MUL_F(filter[0], (QMF_RE(buffer[i+0]) - QMF_RE(buffer[i+12]))) -
+            MUL_F(filter[4], (QMF_RE(buffer[i+4]) - QMF_RE(buffer[i+8])));
+        input_re2[1] = MUL_F(FRAC_CONST(0.70710678118655),
+            (MUL_F(filter[1], (QMF_RE(buffer[i+1]) - QMF_RE(buffer[i+11]))) -
+            MUL_F(filter[3], (QMF_RE(buffer[i+3]) - QMF_RE(buffer[i+9]))) -
+            MUL_F(filter[5], (QMF_RE(buffer[i+5]) - QMF_RE(buffer[i+7])))));
+
+        input_im2[0] = -MUL_F(filter[2], (QMF_IM(buffer[i+2]) + QMF_IM(buffer[i+10]))) +
+            MUL_F(filter[6], QMF_IM(buffer[i+6]));
+        input_im2[1] = MUL_F(FRAC_CONST(-0.70710678118655),
+            (MUL_F(filter[1], (QMF_IM(buffer[i+1]) + QMF_IM(buffer[i+11]))) +
+            MUL_F(filter[3], (QMF_IM(buffer[i+3]) + QMF_IM(buffer[i+9]))) -
+            MUL_F(filter[5], (QMF_IM(buffer[i+5]) + QMF_IM(buffer[i+7])))));
+
+        /* q == 0 */
+        QMF_RE(X_hybrid[i][0]) =  input_re1[0] + input_re1[1] + input_im1[0] + input_im1[1];
+        QMF_IM(X_hybrid[i][0]) = -input_re2[0] - input_re2[1] + input_im2[0] + input_im2[1];
+
+        /* q == 1 */
+        QMF_RE(X_hybrid[i][1]) =  input_re1[0] - input_re1[1] - input_im1[0] + input_im1[1];
+        QMF_IM(X_hybrid[i][1]) =  input_re2[0] - input_re2[1] + input_im2[0] - input_im2[1];
+
+        /* q == 2 */
+        QMF_RE(X_hybrid[i][2]) =  input_re1[0] - input_re1[1] + input_im1[0] - input_im1[1];
+        QMF_IM(X_hybrid[i][2]) = -input_re2[0] + input_re2[1] + input_im2[0] - input_im2[1];
+
+        /* q == 3 */
+        QMF_RE(X_hybrid[i][3]) =  input_re1[0] + input_re1[1] - input_im1[0] - input_im1[1];
+        QMF_IM(X_hybrid[i][3]) =  input_re2[0] + input_re2[1] + input_im2[0] + input_im2[1];
+    }
+}
+
 static void INLINE DCT3_4_unscaled(real_t *y, real_t *x)
 {
     real_t f0, f1, f2, f3, f4, f5, f6, f7, f8;
@@ -341,6 +396,71 @@
     }
 }
 
+static void INLINE DCT3_6_unscaled(real_t *y, real_t *x)
+{
+    real_t f0, f1, f2, f3, f4, f5, f6, f7;
+
+    f0 = MUL_F(x[3], FRAC_CONST(0.70710678118655));
+    f1 = x[0] + f0;
+    f2 = x[0] - f0;
+    f3 = MUL_F((x[1] - x[5]), FRAC_CONST(0.70710678118655));
+    f4 = MUL_F(x[2], FRAC_CONST(0.86602540378444)) + MUL_F(x[4], FRAC_CONST(0.5));
+    f5 = f4 - x[4];
+    f6 = MUL_F(x[1], FRAC_CONST(0.96592582628907)) + MUL_F(x[5], FRAC_CONST(0.25881904510252));
+    f7 = f6 - f3;
+    y[0] = f1 + f6 + f4;
+    y[1] = f2 + f3 - x[4];
+    y[2] = f7 + f2 - f5;
+    y[3] = f1 - f7 - f5;
+    y[4] = f1 - f3 - x[4];
+    y[5] = f2 - f6 + f4;
+}
+
+/* complex filter, size 12 */
+static void channel_filter12(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
+                             qmf_t *buffer, qmf_t **X_hybrid)
+{
+    uint8_t i, n;
+    real_t input_re1[6], input_re2[6], input_im1[6], input_im2[6];
+    real_t out_re1[6], out_re2[6], out_im1[6], out_im2[6];
+
+    for (i = 0; i < frame_len; i++)
+    {
+        for (n = 0; n < 6; n++)
+        {
+            if (n == 0)
+            {
+                input_re1[0] = filter[6] * QMF_RE(buffer[6+i]);
+                input_re2[0] = filter[6] * QMF_IM(buffer[6+i]);
+            } else {
+                input_re1[6-n] = filter[n] * (QMF_RE(buffer[n+i]) + QMF_RE(buffer[12-n+i]));
+                input_re2[6-n] = filter[n] * (QMF_IM(buffer[n+i]) + QMF_IM(buffer[12-n+i]));
+            }
+            input_im2[n] = filter[n] * (QMF_RE(buffer[n+i]) - QMF_RE(buffer[12-n+i]));
+            input_im1[n] = filter[n] * (QMF_IM(buffer[n+i]) - QMF_IM(buffer[12-n+i]));
+        }
+
+        DCT3_6_unscaled(out_re1, input_re1);
+        DCT3_6_unscaled(out_re2, input_re2);
+
+        DCT3_6_unscaled(out_im1, input_im1);
+        DCT3_6_unscaled(out_im2, input_im2);
+
+        for (n = 0; n < 6; n += 2)
+        {
+            QMF_RE(X_hybrid[i][n]) = out_re1[n] - out_im1[n];
+            QMF_IM(X_hybrid[i][n]) = out_re2[n] + out_im2[n];
+            QMF_RE(X_hybrid[i][n+1]) = out_re1[n+1] + out_im1[n+1];
+            QMF_IM(X_hybrid[i][n+1]) = out_re2[n+1] - out_im2[n+1];
+
+            QMF_RE(X_hybrid[i][10-n]) = out_re1[n+1] - out_im1[n+1];
+            QMF_IM(X_hybrid[i][10-n]) = out_re2[n+1] + out_im2[n+1];
+            QMF_RE(X_hybrid[i][11-n]) = out_re1[n] + out_im1[n];
+            QMF_IM(X_hybrid[i][11-n]) = out_re2[n] - out_im2[n];
+        }
+    }
+}
+
 /* Hybrid analysis: further split up QMF subbands
  * to improve frequency resolution
  */
@@ -371,17 +491,21 @@
         switch(resolution[band])
         {
         case 2:
+            /* Type B real filter, Q[p] = 2 */
             channel_filter2(hyb, hyb->frame_len, p2_13_20, hyb->work, hyb->temp);
             break;
         case 4:
-            channel_filter2(hyb, hyb->frame_len, p4_13_34, hyb->work, hyb->temp);
+            /* Type A complex filter, Q[p] = 4 */
+            channel_filter4(hyb, hyb->frame_len, p4_13_34, hyb->work, hyb->temp);
             break;
         case 8:
+            /* Type A complex filter, Q[p] = 8 */
             channel_filter8(hyb, hyb->frame_len, (use34) ? p8_13_34 : p8_13_20,
                 hyb->work, hyb->temp);
             break;
         case 12:
-            channel_filter2(hyb, hyb->frame_len, p12_13_34, hyb->work, hyb->temp);
+            /* Type A complex filter, Q[p] = 12 */
+            channel_filter12(hyb, hyb->frame_len, p12_13_34, hyb->work, hyb->temp);
             break;
         }
 
@@ -1420,6 +1544,11 @@
             }
         }
     }
+}
+
+void ps_free(ps_info *ps)
+{
+    faad_free(ps);
 }
 
 ps_info *ps_init(uint8_t sr_index)
--- a/libfaad/ps_dec.h
+++ b/libfaad/ps_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: ps_dec.h,v 1.1 2004/03/10 19:53:40 menno Exp $
+** $Id: ps_dec.h,v 1.2 2004/04/03 10:49:14 menno Exp $
 **/
 
 #ifndef __PS_DEC_H__
@@ -133,6 +133,8 @@
 
 /* ps_dec.c */
 ps_info *ps_init(uint8_t sr_index);
+void ps_free(ps_info *ps);
+
 uint8_t ps_decode(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]);
 
 
--- 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.33 2004/03/27 11:14:49 menno Exp $
+** $Id: sbr_dec.c,v 1.34 2004/04/03 10:49:15 menno Exp $
 **/
 
 
@@ -159,6 +159,16 @@
             if (sbr->G_temp_prev[1][j]) faad_free(sbr->G_temp_prev[1][j]);
             if (sbr->Q_temp_prev[1][j]) faad_free(sbr->Q_temp_prev[1][j]);
         }
+
+#ifdef PS_DEC
+        if (sbr->ps != NULL) 
+            ps_free(sbr->ps);
+#endif
+
+#ifdef DRM_PS
+        if (sbr->drm_ps != NULL)
+            drm_ps_free(sbr->drm_ps);
+#endif
 
         faad_free(sbr);
     }
--- a/libfaad/sbr_dec.h
+++ b/libfaad/sbr_dec.h
@@ -1,19 +1,19 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
 ** Copyright (C) 2003-2004 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_dec.h,v 1.29 2004/03/27 11:14:49 menno Exp $
+** $Id: sbr_dec.h,v 1.30 2004/04/03 10:49:15 menno Exp $
 **/
 
 #ifndef __SBR_DEC_H__
@@ -46,7 +46,7 @@
 
 typedef struct {
     real_t *x;
-	int16_t x_index;
+    int16_t x_index;
     uint8_t channels;
 } qmfa_info;
 
@@ -160,7 +160,6 @@
     qmf_t Xcodec[2][MAX_NTSRHFG][32];
 
 #ifdef DRM
-	uint8_t bs_dataextra;
     uint8_t Is_DRM_SBR;
 #ifdef DRM_PS
     drm_ps_info *drm_ps;
@@ -167,10 +166,10 @@
 #endif
 #endif
 
-	uint8_t numTimeSlotsRate;
-	uint8_t numTimeSlots;
-	uint8_t tHFGen;
-	uint8_t tHFAdj;
+    uint8_t numTimeSlotsRate;
+    uint8_t numTimeSlots;
+    uint8_t tHFGen;
+    uint8_t tHFAdj;
 
 #ifdef PS_DEC
     ps_info *ps;
@@ -221,9 +220,9 @@
 sbr_info *sbrDecodeInit(uint16_t framelength, uint8_t id_aac,
                         uint32_t sample_rate, uint8_t downSampledSBR
 #ifdef DRM
-						, uint8_t IsDRM
+                        , uint8_t IsDRM
 #endif
-						);
+                        );
 void sbrDecodeEnd(sbr_info *sbr);
 
 uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_chan,
--- 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.15 2004/03/19 10:37:55 menno Exp $
+** $Id: sbr_hfgen.c,v 1.16 2004/04/03 10:49:15 menno Exp $
 **/
 
 /* High Frequency generation */
@@ -67,7 +67,6 @@
     uint8_t first = sbr->t_E[ch][0];
     uint8_t last = sbr->t_E[ch][sbr->L_E[ch]];
 
-
     calc_chirp_factors(sbr, ch);
 
     for (i = first; i < last; i++)
@@ -568,7 +567,7 @@
     uint8_t odd, sb;
     uint8_t msb = sbr->k0;
     uint8_t usb = sbr->kx;
-    uint8_t goalSbTab[] = { 21, 23, 43, 46, 64, 85, 93, 128, 0, 0, 0 };
+    uint8_t goalSbTab[] = { 21, 23, 32, 43, 46, 64, 85, 93, 128, 0, 0, 0 };
     /* (uint8_t)(2.048e6/sbr->sample_rate + 0.5); */
     uint8_t goalSb = goalSbTab[get_sr_index(sbr->sample_rate)];
 
--- a/libfaad/sbr_syntax.c
+++ b/libfaad/sbr_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: sbr_syntax.c,v 1.29 2004/03/19 10:37:55 menno Exp $
+** $Id: sbr_syntax.c,v 1.30 2004/04/03 10:49:15 menno Exp $
 **/
 
 #include "common.h"
@@ -231,6 +231,11 @@
 #endif
     {
         num_sbr_bits = (uint16_t)faad_get_processed_bits(ld) - num_sbr_bits;
+
+        /* check if we read more bits then were available for sbr */
+        if (8*cnt < num_sbr_bits)
+            return 1;
+
         /* -4 does not apply, bs_extension_type is re-read in this function */
         num_align_bits = 8*cnt /*- 4*/ - num_sbr_bits;
 
@@ -390,6 +395,7 @@
 
     sbr->bs_extended_data = faad_get1bit(ld
         DEBUGVAR(1,224,"sbr_single_channel_element(): bs_extended_data[0]"));
+
     if (sbr->bs_extended_data)
     {
         uint16_t nr_bits_left;
@@ -404,10 +410,18 @@
         nr_bits_left = 8 * cnt;
         while (nr_bits_left > 7)
         {
+            uint16_t tmp_nr_bits = 0;
+
             sbr->bs_extension_id = (uint8_t)faad_getbits(ld, 2
                 DEBUGVAR(1,227,"sbr_single_channel_element(): bs_extension_id"));
-            nr_bits_left -= 2;
-            nr_bits_left -= sbr_extension(ld, sbr, sbr->bs_extension_id, nr_bits_left);
+            tmp_nr_bits += 2;
+            tmp_nr_bits += sbr_extension(ld, sbr, sbr->bs_extension_id, nr_bits_left);
+
+            /* check if the data read is bigger than the number of available bits */
+            if (tmp_nr_bits > nr_bits_left)
+                return 1;
+
+            nr_bits_left -= tmp_nr_bits;
         }
 
         /* Corrigendum */
@@ -552,10 +566,18 @@
         nr_bits_left = 8 * cnt;
         while (nr_bits_left > 7)
         {
+            uint16_t tmp_nr_bits = 0;
+
             sbr->bs_extension_id = (uint8_t)faad_getbits(ld, 2
                 DEBUGVAR(1,236,"sbr_channel_pair_element(): bs_extension_id"));
-            nr_bits_left -= 2;
-            nr_bits_left -= sbr_extension(ld, sbr, sbr->bs_extension_id, nr_bits_left);
+            tmp_nr_bits += 2;
+            tmp_nr_bits += sbr_extension(ld, sbr, sbr->bs_extension_id, nr_bits_left);
+
+            /* check if the data read is bigger than the number of available bits */
+            if (tmp_nr_bits > nr_bits_left)
+                return 1;
+
+            nr_bits_left -= tmp_nr_bits;
         }
 
         /* Corrigendum */
--- 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.48 2004/03/19 10:37:55 menno Exp $
+** $Id: specrec.c,v 1.49 2004/04/03 10:49:15 menno Exp $
 **/
 
 /*
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include "specrec.h"
+#include "filtbank.h"
 #include "syntax.h"
 #include "iq_table.h"
 #include "ms.h"
--- 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.37 2004/03/27 11:14:49 menno Exp $
+** $Id: structs.h,v 1.40 2004/07/31 15:48:57 menno Exp $
 **/
 
 #ifndef __STRUCTS_H__
@@ -182,6 +182,7 @@
     program_config pce[16];
 } adif_header;
 
+#ifdef LTP_DEC
 typedef struct
 {
     uint8_t last_band;
@@ -194,7 +195,9 @@
     uint8_t short_lag_present[8];
     uint8_t short_lag[8];
 } ltp_info;
+#endif
 
+#ifdef MAIN_DEC
 typedef struct
 {
     uint8_t limit;
@@ -202,6 +205,7 @@
     uint8_t predictor_reset_group_number;
     uint8_t prediction_used[MAX_SFB];
 } pred_info;
+#endif
 
 typedef struct
 {
@@ -268,9 +272,13 @@
 
     pulse_info pul;
     tns_info tns;
+#ifdef MAIN_DEC
     pred_info pred;
+#endif
+#ifdef LTP_DEC
     ltp_info ltp;
     ltp_info ltp2;
+#endif
 #ifdef SSR_DEC
     ssr_info ssr;
 #endif
--- 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.77 2004/03/19 10:37:55 menno Exp $
+** $Id: syntax.c,v 1.78 2004/04/03 10:49:15 menno Exp $
 **/
 
 /*
@@ -85,7 +85,9 @@
 static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count);
 static uint8_t pulse_data(ic_stream *ics, pulse_info *pul, bitfile *ld);
 static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld);
+#ifdef LTP_DEC
 static uint8_t ltp_data(NeAACDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld);
+#endif
 static uint8_t adts_fixed_header(adts_header *adts, bitfile *ld);
 static void adts_variable_header(adts_header *adts, bitfile *ld);
 static void adts_error_check(adts_header *adts, bitfile *ld);
@@ -641,13 +643,20 @@
 #ifdef ERROR_RESILIENCE
         if ((hDecoder->object_type >= ER_OBJECT_START) && (ics1->predictor_data_present))
         {
-            if ((ics1->ltp.data_present = faad_get1bit(ld
-                DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1)
+            if ((
+#ifdef LTP_DEC
+                ics1->ltp.data_present =
+#endif
+                faad_get1bit(ld DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1)
             {
+#ifdef LTP_DEC
                 if ((result = ltp_data(hDecoder, ics1, &(ics1->ltp), ld)) > 0)
                 {
                     return result;
                 }
+#else
+                return 26;
+#endif
             }
         }
 #endif
@@ -667,13 +676,20 @@
     if (cpe.common_window && (hDecoder->object_type >= ER_OBJECT_START) &&
         (ics1->predictor_data_present))
     {
-        if ((ics1->ltp2.data_present = faad_get1bit(ld
-            DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1)
+        if ((
+#ifdef LTP_DEC
+            ics1->ltp2.data_present =
+#endif
+            faad_get1bit(ld DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1)
         {
+#ifdef LTP_DEC
             if ((result = ltp_data(hDecoder, ics1, &(ics1->ltp2), ld)) > 0)
             {
                 return result;
             }
+#else
+            return 26;
+#endif
         }
     }
 #endif
@@ -751,19 +767,29 @@
             {
                 uint8_t sfb;
 
-                ics->pred.limit = min(ics->max_sfb, max_pred_sfb(hDecoder->sf_index));
+                uint8_t limit = min(ics->max_sfb, max_pred_sfb(hDecoder->sf_index));
+#ifdef MAIN_DEC
+                ics->pred.limit = limit;
+#endif
 
-                if ((ics->pred.predictor_reset = faad_get1bit(ld
-                    DEBUGVAR(1,53,"ics_info(): pred.predictor_reset"))) & 1)
+                if ((
+#ifdef MAIN_DEC
+                    ics->pred.predictor_reset =
+#endif
+                    faad_get1bit(ld DEBUGVAR(1,53,"ics_info(): pred.predictor_reset"))) & 1)
                 {
-                    ics->pred.predictor_reset_group_number = (uint8_t)faad_getbits(ld, 5
-                        DEBUGVAR(1,54,"ics_info(): pred.predictor_reset_group_number"));
+#ifdef MAIN_DEC
+                    ics->pred.predictor_reset_group_number =
+#endif
+                        (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,54,"ics_info(): pred.predictor_reset_group_number"));
                 }
 
-                for (sfb = 0; sfb < ics->pred.limit; sfb++)
+                for (sfb = 0; sfb < limit; sfb++)
                 {
-                    ics->pred.prediction_used[sfb] = faad_get1bit(ld
-                        DEBUGVAR(1,55,"ics_info(): pred.prediction_used"));
+#ifdef MAIN_DEC
+                    ics->pred.prediction_used[sfb] =
+#endif
+                        faad_get1bit(ld DEBUGVAR(1,55,"ics_info(): pred.prediction_used"));
                 }
             }
 #ifdef LTP_DEC
@@ -1358,13 +1384,20 @@
                 diff_control_data_lr();
         } else {
 #endif
-            if ((ics->ltp.data_present = faad_get1bit(ld
-                DEBUGVAR(1,310,"aac_scalable_main_header(): ltp.data_present"))) & 1)
+            if ((
+#ifdef LTP_DEC
+                ics->ltp.data_present =
+#endif
+                faad_get1bit(ld DEBUGVAR(1,310,"aac_scalable_main_header(): ltp.data_present"))) & 1)
             {
+#ifdef LTP_DEC
                 if ((retval = ltp_data(hDecoder, ics, &(ics->ltp), ld)) > 0)
                 {
                     return retval;
                 }
+#else
+                return 26;
+#endif
             }
 #if 0
         }