shithub: aacdec

Download patch

ref: 99a01ee867743997e40318c6456af79fdc77dea0
parent: cd48b77ea6f3675155ae07e4408e14e26b9d6f99
author: menno <menno>
date: Tue Dec 10 09:53:15 EST 2002

Various bugfixes
Cleanup of syntax.c

--- 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.43 2002/12/05 19:28:22 menno Exp $
+** $Id: decoder.c,v 1.44 2002/12/10 14:53:14 menno Exp $
 **/
 
 #include "common.h"
@@ -85,6 +85,7 @@
         hDecoder->time_out[i] = NULL;
 #ifdef SSR_DEC
         hDecoder->ssr_overlap[i] = NULL;
+        hDecoder->prev_fmd[i] = NULL;
 #endif
 #ifdef MAIN_DEC
         hDecoder->pred_stat[i] = NULL;
@@ -296,6 +297,7 @@
         if (hDecoder->time_out[i]) free(hDecoder->time_out[i]);
 #ifdef SSR_DEC
         if (hDecoder->ssr_overlap[i]) free(hDecoder->ssr_overlap[i]);
+        if (hDecoder->prev_fmd[i]) free(hDecoder->prev_fmd[i]);
 #endif
 #ifdef MAIN_DEC
         if (hDecoder->pred_stat[i]) free(hDecoder->pred_stat[i]);
@@ -332,7 +334,7 @@
     int32_t i;
     uint8_t ch;
     adts_header adts;
-    uint8_t channels, ch_ele;
+    uint8_t channels = 0, ch_ele = 0;
     bitfile *ld = (bitfile*)malloc(sizeof(bitfile));
 
     /* local copys of globals */
@@ -356,6 +358,7 @@
     real_t **time_out      =  hDecoder->time_out;
 #ifdef SSR_DEC
     real_t **ssr_overlap   =  hDecoder->ssr_overlap;
+    real_t **prev_fmd      =  hDecoder->prev_fmd;
 #endif
     fb_info *fb            =  hDecoder->fb;
     drc_info *drc          =  hDecoder->drc;
@@ -370,11 +373,11 @@
     int16_t *spec_data[MAX_CHANNELS];
     real_t *spec_coef[MAX_CHANNELS];
 
-    /* frame length is different for Low Delay AAC */
     uint16_t frame_len = hDecoder->frameLength;
 
     void *sample_buffer;
 
+
     memset(hInfo, 0, sizeof(faacDecFrameInfo));
 
     /* initialize the bitstream */
@@ -403,18 +406,19 @@
     dbg_count = 0;
 #endif
 
-    channels = 0;
-    ch_ele = 0;
     elements = syntax_elements;
 
     /* decode the complete bitstream */
     elements = raw_data_block(hDecoder, hInfo, ld, syntax_elements,
-        spec_data, spec_coef, &ch_ele, &channels, &pce, drc);
+        spec_data, spec_coef, &pce, drc);
 
     if (hInfo->error > 0)
         goto error;
 
+    ch_ele = hDecoder->fr_ch_ele;
+    channels = hDecoder->fr_channels;
 
+
     /* no more bit reading after this */
     faad_byte_align(ld);
     hInfo->bytesconsumed = bit2byte(faad_get_processed_bits(ld));
@@ -595,10 +599,17 @@
                 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], frame_len);
+                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 */
--- 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.19 2002/12/05 19:28:22 menno Exp $
+** $Id: decoder.h,v 1.20 2002/12/10 14:53:15 menno Exp $
 **/
 
 #ifndef __DECODER_H__
@@ -90,15 +90,14 @@
 element *decode_sce_lfe(faacDecHandle hDecoder,
                         faacDecFrameInfo *hInfo, bitfile *ld,
                         int16_t **spec_data, real_t **spec_coef,
-                        uint8_t channels, uint8_t id_syn_ele);
+                        uint8_t id_syn_ele);
 element *decode_cpe(faacDecHandle hDecoder,
                     faacDecFrameInfo *hInfo, bitfile *ld,
                     int16_t **spec_data, real_t **spec_coef,
-                    uint8_t channels, uint8_t id_syn_ele);
+                    uint8_t id_syn_ele);
 element **raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
                          bitfile *ld, element **elements,
                          int16_t **spec_data, real_t **spec_coef,
-                         uint8_t *out_ch_ele, uint8_t *out_channels,
                          program_config *pce, drc_info *drc);
 
 #ifdef _WIN32
--- a/libfaad/libfaad.vcproj
+++ b/libfaad/libfaad.vcproj
@@ -3,6 +3,7 @@
 	ProjectType="Visual C++"
 	Version="7.00"
 	Name="libfaad"
+	ProjectGUID="{AB39547E-6CAC-4E25-8BC4-C97EFC144800}"
 	SccProjectName=""
 	SccLocalPath="">
 	<Platforms>
@@ -105,18 +106,12 @@
 					Optimization="2"
 					GlobalOptimizations="0"
 					InlineFuncExpansion="1"
-					IntrinsicFuncs="1"
-					FavorSizeSpeed="1"
 					OmitFramePtrs="1"
-					OptimProc="2"
-					UseProcExt="0"
-					RequireProcExt="0"
-					Parallelization="0"
 					StringPooling="1"
 					RuntimeLibrary="0"
 					BufferSecurityCheck="1"
 					FunctionLevelLinking="1"
-					AllOptions="/c  /nologo /W3 /O2 /Ob1 /Oi /Ot /Oy /G6 /D &quot;NDEBUG&quot; /D &quot;WIN32&quot; /D &quot;_LIB&quot; /D &quot;FFTW_ENABLE_FLOAT&quot; /D &quot;_MBCS&quot; /GF /FD /EHsc /MT /GS /Gy /YX&quot;StdAfx.h&quot; /Fp&quot;.\Release/libfaad.pch&quot; /Fo&quot;.\Release/&quot; /Fd&quot;.\Release/&quot; /Gd"
+					AllOptions="/c  /nologo /W3 /O2 /Ob1 /Oy /D &quot;NDEBUG&quot; /D &quot;WIN32&quot; /D &quot;_LIB&quot; /D &quot;FFTW_ENABLE_FLOAT&quot; /D &quot;_MBCS&quot; /GF /FD /EHsc /MT /GS /Gy /YX&quot;StdAfx.h&quot; /Fp&quot;.\Release/libfaad.pch&quot; /Fo&quot;.\Release/&quot; /Fd&quot;.\Release/&quot; /Gd"
 					MSOriginalAdditionalOptions=""/>
 			</Tool>
 			<Tool
@@ -144,8 +139,6 @@
 				Culture="1043"/>
 			<Tool
 				Name="VCWebServiceProxyGeneratorTool"/>
-			<IntelOptions
-				CompilerName="0"/>
 		</Configuration>
 	</Configurations>
 	<Files>
--- a/libfaad/ssr.c
+++ b/libfaad/ssr.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: ssr.c,v 1.2 2002/12/02 20:27:59 menno Exp $
+** $Id: ssr.c,v 1.3 2002/12/10 14:53:15 menno Exp $
 **/
 
 #include "common.h"
@@ -32,7 +32,8 @@
 void ssr_decode(ssr_info *ssr, fb_info *fb, uint8_t window_sequence,
                 uint8_t window_shape, uint8_t window_shape_prev,
                 real_t *freq_in, real_t *time_out, real_t *overlap,
-                uint16_t frame_len)
+                real_t ipqf_buffer[SSR_BANDS][96/4],
+                real_t *prev_fmd, uint16_t frame_len)
 {
     uint8_t band;
     uint16_t ssr_frame_len = frame_len/SSR_BANDS;
@@ -65,27 +66,28 @@
             ssr_frame_len);
 
         /* gain control */
-        ssr_gain_control(ssr, time_tmp, output, overlap, band,
-            window_sequence, ssr_frame_len);
+        ssr_gain_control(ssr, time_tmp, output, overlap, prev_fmd,
+            band, window_sequence, ssr_frame_len);
     }
 
-#if 0
     /* inverse pqf to bring subbands together again */
-    ssr_ipqf(ssr_info *ssr, real_t *time_tmp);
-#endif
+    ssr_ipqf(ssr, output, time_out, ipqf_buffer, frame_len, SSR_BANDS);
 }
 
 static void ssr_gain_control(ssr_info *ssr, real_t *data, real_t *output,
-                             real_t *overlap, uint8_t band,
+                             real_t *overlap, real_t *prev_fmd, uint8_t band,
                              uint8_t window_sequence, uint16_t frame_len)
 {
     uint16_t i;
+    real_t gc_function[2*1024/SSR_BANDS];
 
     if (window_sequence != EIGHT_SHORT_SEQUENCE)
     {
-//        ssr_gc_function();
-//        for (i = 0; i < frame_len*2; i++)
-//          input[band * frame_len*2 + i] *= gc_function[i];
+        ssr_gc_function(ssr, &prev_fmd[band * frame_len*2],
+            gc_function, window_sequence, frame_len);
+
+        for (i = 0; i < frame_len*2; i++)
+            data[band * frame_len*2 + i] *= gc_function[i];
         for (i = 0; i < frame_len; i++)
         {
             output[band*frame_len + i] = overlap[band*frame_len + i] +
@@ -102,9 +104,12 @@
         {
             uint16_t frame_len8 = frame_len/8;
             uint16_t frame_len16 = frame_len/16;
-//            ssr_gc_function();
-//            for (i = 0; i < frame_len*2/8; i++)
-//                input[band*frame_len*2 + w*frame_len*2/8+j] *= gc_function[j];
+
+            ssr_gc_function(ssr, &prev_fmd[band*frame_len*2 + w*frame_len*2/8],
+                gc_function, window_sequence, frame_len);
+
+            for (i = 0; i < frame_len8*2; i++)
+                data[band*frame_len*2 + w*frame_len8*2+i] *= gc_function[i];
             for (i = 0; i < frame_len8; i++)
             {
                 overlap[band*frame_len + i + 7*frame_len16 + w*frame_len8] +=
@@ -123,10 +128,12 @@
     }
 }
 
-#if 0
-static void ssr_gc_function(ssr_info *ssr, real_t *prevFMD,
-                            real_t *gc_function, uint16_t frame_len)
+static void ssr_gc_function(ssr_info *ssr, real_t *prev_fmd,
+                            real_t *gc_function, uint8_t window_sequence,
+                            uint16_t frame_len)
 {
+    uint16_t i;
+    uint16_t len_area1, len_area2;
     int32_t aloc[10];
     real_t alev[10];
 
@@ -153,7 +160,10 @@
     /* decode bitstream information */
 
     /* build array M */
+
+
+    for (i = 0; i < frame_len*2; i++)
+        gc_function[i] = 1;
 }
-#endif
 
 #endif
--- a/libfaad/ssr.h
+++ b/libfaad/ssr.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: ssr.h,v 1.2 2002/12/02 20:28:02 menno Exp $
+** $Id: ssr.h,v 1.3 2002/12/10 14:53:15 menno Exp $
 **/
 
 #ifndef __SSR_H__
@@ -27,16 +27,22 @@
 #endif
 
 #define SSR_BANDS 4
+#define PQFTAPS 96
 
 void ssr_decode(ssr_info *ssr, fb_info *fb, uint8_t window_sequence,
                 uint8_t window_shape, uint8_t window_shape_prev,
                 real_t *freq_in, real_t *time_out, real_t *overlap,
-                uint16_t frame_len);
+                real_t ipqf_buffer[SSR_BANDS][96/4],
+                real_t *prev_fmd, uint16_t frame_len);
 
 
 static void ssr_gain_control(ssr_info *ssr, real_t *data, real_t *output,
-                             real_t *overlap, uint8_t band,
+                             real_t *overlap, real_t *prev_fmd, uint8_t band,
                              uint8_t window_sequence, uint16_t frame_len);
+static void ssr_gc_function(ssr_info *ssr, real_t *prev_fmd,
+                            real_t *gc_function, uint8_t window_sequence,
+                            uint16_t frame_len);
+
 
 #ifdef __cplusplus
 }
--- a/libfaad/ssr_ipqf.c
+++ b/libfaad/ssr_ipqf.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: ssr_ipqf.c,v 1.1 2002/11/28 18:48:30 menno Exp $
+** $Id: ssr_ipqf.c,v 1.2 2002/12/10 14:53:15 menno Exp $
 **/
 
 #include "common.h"
@@ -24,7 +24,159 @@
 
 #ifdef SSR_DEC
 
+#include "ssr.h"
 #include "ssr_ipqf.h"
 
+static real_t **app_pqfbuf;
+static real_t **pp_q0, **pp_t0, **pp_t1;
+
+void gc_set_protopqf(real_t *p_proto)
+{
+    int	j;
+    static real_t a_half[48] =
+    {
+        1.2206911375946939E-05,  1.7261986723798209E-05,  1.2300093657077942E-05,
+        -1.0833943097791965E-05, -5.7772498639901686E-05, -1.2764767618947719E-04,
+        -2.0965186675013334E-04, -2.8166673689263850E-04, -3.1234860429017460E-04,
+        -2.6738519958452353E-04, -1.1949424681824722E-04,  1.3965139412648678E-04,
+        4.8864136409185725E-04,  8.7044629275148344E-04,  1.1949430269934793E-03,
+        1.3519708175026700E-03,  1.2346314373964412E-03,  7.6953209114159191E-04,
+        -5.2242432579537141E-05, -1.1516092887213454E-03, -2.3538469841711277E-03,
+        -3.4033123072127277E-03, -4.0028551071986133E-03, -3.8745415659693259E-03,
+        -2.8321073426874310E-03, -8.5038892323704195E-04,  1.8856751185350931E-03,
+        4.9688741735340923E-03,  7.8056704536795926E-03,  9.7027909685901654E-03,
+        9.9960423120166159E-03,  8.2019366335594487E-03,  4.1642072876103365E-03,
+        -1.8364453822737758E-03, -9.0384863094167686E-03, -1.6241528177129844E-02,
+        -2.1939551286300665E-02, -2.4533179947088161E-02, -2.2591663337768787E-02,
+        -1.5122066420044672E-02, -1.7971713448186293E-03,  1.6903413428575379E-02,
+        3.9672315874127042E-02,  6.4487527248102796E-02,  8.8850025474701726E-02,
+        0.1101132906105560    ,  0.1258540205143761    ,  0.1342239368467012    
+    };
+
+    for (j = 0; j < 48; ++j)
+    {
+        p_proto[j] = p_proto[95-j] = a_half[j];
+    }
+}
+
+void gc_setcoef_eff_pqfsyn(int mm,
+                           int kk,
+                           real_t *p_proto,
+                           real_t ***ppp_q0,
+                           real_t ***ppp_t0,
+                           real_t ***ppp_t1)
+{
+    int	i, k, n;
+    real_t	w;
+
+    /* Set 1st Mul&Acc Coef's */
+    *ppp_q0 = (real_t **) calloc(mm, sizeof(real_t *));
+    for (n = 0; n < mm; ++n)
+    {
+        (*ppp_q0)[n] = (real_t *) calloc(mm, sizeof(real_t));
+    }
+    for (n = 0; n < mm/2; ++n)
+    {
+        for (i = 0; i < mm; ++i)
+        {
+            w = (2*i+1)*(2*n+1-mm)*M_PI/(4*mm);
+            (*ppp_q0)[n][i] = 2.0 * cos((real_t) w);
+
+            w = (2*i+1)*(2*(mm+n)+1-mm)*M_PI/(4*mm);
+            (*ppp_q0)[n + mm/2][i] = 2.0 * cos((real_t) w);
+        }
+    }
+
+    /* Set 2nd Mul&Acc Coef's */
+    *ppp_t0 = (real_t **) calloc(mm, sizeof(real_t *));
+    *ppp_t1 = (real_t **) calloc(mm, sizeof(real_t *));
+    for (n = 0; n < mm; ++n)
+    {
+        (*ppp_t0)[n] = (real_t *) calloc(kk, sizeof(real_t));
+        (*ppp_t1)[n] = (real_t *) calloc(kk, sizeof(real_t));
+    }
+    for (n = 0; n < mm; ++n)
+    {
+        for (k = 0; k < kk; ++k)
+        {
+            (*ppp_t0)[n][k] = mm * p_proto[2*k    *mm + n];
+            (*ppp_t1)[n][k] = mm * p_proto[(2*k+1)*mm + n];
+
+            if (k%2 != 0)
+            {
+                (*ppp_t0)[n][k] = -(*ppp_t0)[n][k];
+                (*ppp_t1)[n][k] = -(*ppp_t1)[n][k];
+            }
+        }
+    }
+}
+
+void ssr_ipqf(ssr_info *ssr, real_t *in_data, real_t *out_data,
+              real_t buffer[SSR_BANDS][96/4],
+              uint16_t frame_len, uint8_t bands)
+{
+    static int initFlag = 0;
+    real_t a_pqfproto[PQFTAPS];
+
+    int	i;
+
+    if (initFlag == 0)
+    {
+        gc_set_protopqf(a_pqfproto);
+        gc_setcoef_eff_pqfsyn(SSR_BANDS, PQFTAPS/(2*SSR_BANDS), a_pqfproto,
+            &pp_q0, &pp_t0, &pp_t1);
+        initFlag = 1;
+    }
+
+    for (i = 0; i < frame_len / SSR_BANDS; i++)
+    {
+        int l, n, k;
+        int mm = SSR_BANDS;
+        int kk = PQFTAPS/(2*SSR_BANDS);
+
+        for (n = 0; n < mm; n++)
+        {
+            for (k = 0; k < 2*kk-1; k++)
+            {
+                buffer[n][k] = buffer[n][k+1];
+            }
+        }
+
+        for (n = 0; n < mm; n++)
+        {
+            real_t acc = 0.0;
+            for (l = 0; l < mm; l++)
+            {
+                acc += pp_q0[n][l] * in_data[l*frame_len/SSR_BANDS + i];
+            }
+            buffer[n][2*kk-1] = acc;
+        }
+
+        for (n = 0; n < mm/2; n++)
+        {
+            real_t acc = 0.0;
+            for (k = 0; k < kk; k++)
+            {
+                acc += pp_t0[n][k] * buffer[n][2*kk-1-2*k];
+            }
+            for (k = 0; k < kk; ++k)
+            {
+                acc += pp_t1[n][k] * buffer[n + mm/2][2*kk-2-2*k];
+            }
+            out_data[i*SSR_BANDS + n] = acc;
+
+            acc = 0.0;
+            for (k = 0; k < kk; k++)
+            {
+                acc += pp_t0[mm-1-n][k] * buffer[n][2*kk-1-2*k];
+            }
+            for (k = 0; k < kk; k++)
+            {
+                acc -= pp_t1[mm-1-n][k] * buffer[n + mm/2][2*kk-2-2*k];
+            }
+            out_data[i*SSR_BANDS + mm-1-n] = acc;
+        }
+    }
+}
 
 #endif
--- a/libfaad/ssr_ipqf.h
+++ b/libfaad/ssr_ipqf.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: ssr_ipqf.h,v 1.1 2002/11/28 18:48:30 menno Exp $
+** $Id: ssr_ipqf.h,v 1.2 2002/12/10 14:53:15 menno Exp $
 **/
 
 #ifndef __SSR_IPQF_H__
@@ -26,6 +26,9 @@
 extern "C" {
 #endif
 
+void ssr_ipqf(ssr_info *ssr, real_t *in_data, real_t *out_data,
+              real_t buffer[SSR_BANDS][96/4],
+              uint16_t frame_len, uint8_t bands);
 
 
 #ifdef __cplusplus
--- a/libfaad/structs.h
+++ b/libfaad/structs.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: structs.h,v 1.2 2002/12/02 20:28:04 menno Exp $
+** $Id: structs.h,v 1.3 2002/12/10 14:53:15 menno Exp $
 **/
 
 #ifndef __STRUCTS_H__
@@ -311,6 +311,9 @@
 
     uint32_t frame;
 
+    uint8_t fr_channels;
+    uint8_t fr_ch_ele;
+
     void *sample_buffer;
 
     uint8_t window_shape_prev[MAX_CHANNELS];
@@ -324,6 +327,8 @@
 
 #ifdef SSR_DEC
     real_t *ssr_overlap[MAX_CHANNELS];
+    real_t *prev_fmd[MAX_CHANNELS];
+    real_t ipqf_buffer[MAX_CHANNELS][4][96/4];
 #endif
 
 #ifdef MAIN_DEC
--- 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.34 2002/12/05 19:28:22 menno Exp $
+** $Id: syntax.c,v 1.35 2002/12/10 14:53:15 menno Exp $
 **/
 
 /*
@@ -242,10 +242,22 @@
 element *decode_sce_lfe(faacDecHandle hDecoder,
                         faacDecFrameInfo *hInfo, bitfile *ld,
                         int16_t **spec_data, real_t **spec_coef,
-                        uint8_t channels, uint8_t id_syn_ele)
+                        uint8_t id_syn_ele)
 {
     element *ele;
+    uint8_t channels = hDecoder->fr_channels;
 
+    if (channels+1 >= MAX_CHANNELS)
+    {
+        hInfo->error = 12;
+        return NULL;
+    }
+    if (hDecoder->fr_ch_ele+1 >= MAX_SYNTAX_ELEMENTS)
+    {
+        hInfo->error = 13;
+        return NULL;
+    }
+
     spec_data[channels]   = (int16_t*)malloc(hDecoder->frameLength*sizeof(int16_t));
     spec_coef[channels]   = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
 
@@ -258,6 +270,9 @@
     hInfo->error = single_lfe_channel_element(hDecoder, ele,
         ld, spec_data[channels]);
 
+    hDecoder->fr_channels++;
+    hDecoder->fr_ch_ele++;
+
     return ele;
 }
 
@@ -264,10 +279,22 @@
 element *decode_cpe(faacDecHandle hDecoder,
                     faacDecFrameInfo *hInfo, bitfile *ld,
                     int16_t **spec_data, real_t **spec_coef,
-                    uint8_t channels, uint8_t id_syn_ele)
+                    uint8_t id_syn_ele)
 {
     element *ele;
+    uint8_t channels = hDecoder->fr_channels;
 
+    if (channels+2 >= MAX_CHANNELS)
+    {
+        hInfo->error = 12;
+        return NULL;
+    }
+    if (hDecoder->fr_ch_ele+1 >= MAX_SYNTAX_ELEMENTS)
+    {
+        hInfo->error = 13;
+        return NULL;
+    }
+
     spec_data[channels]   = (int16_t*)malloc(hDecoder->frameLength*sizeof(int16_t));
     spec_data[channels+1] = (int16_t*)malloc(hDecoder->frameLength*sizeof(int16_t));
     spec_coef[channels]   = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
@@ -282,42 +309,22 @@
     hInfo->error = channel_pair_element(hDecoder, ele,
         ld, spec_data[channels], spec_data[channels+1]);
 
+    hDecoder->fr_channels += 2;
+    hDecoder->fr_ch_ele++;
+
     return ele;
 }
 
-#define CHCHECK1 \
-    if (channels+1 >= MAX_CHANNELS) \
-    { \
-        hInfo->error = 12; \
-        goto return_on_error; \
-    } \
-    if (ch_ele+1 >= MAX_SYNTAX_ELEMENTS) \
-    { \
-        hInfo->error = 13; \
-        goto return_on_error; \
-    }
-#define CHCHECK2 \
-    if (channels+2 >= MAX_CHANNELS) \
-    { \
-        hInfo->error = 12; \
-        goto return_on_error; \
-    } \
-    if (ch_ele+1 >= MAX_SYNTAX_ELEMENTS) \
-    { \
-        hInfo->error = 13; \
-        goto return_on_error; \
-    }
-
 element **raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
                          bitfile *ld, element **elements,
                          int16_t **spec_data, real_t **spec_coef,
-                         uint8_t *out_ch_ele, uint8_t *out_channels,
                          program_config *pce, drc_info *drc)
 {
-    uint8_t id_syn_ele, ch_ele, channels;
+    uint8_t id_syn_ele;
+    uint8_t ch_ele = 0;
 
-    channels = 0;
-    ch_ele = 0;
+    hDecoder->fr_channels = 0;
+    hDecoder->fr_ch_ele = 0;
 
 #ifdef ERROR_RESILIENCE
     if (hDecoder->object_type < ER_OBJECT_START)
@@ -330,35 +337,30 @@
             switch (id_syn_ele) {
             case ID_SCE:
             case ID_LFE:
-                CHCHECK1;
-                elements[ch_ele] = decode_sce_lfe(hDecoder,
-                    hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-                ch_ele++; channels++;
+                elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                    hInfo, ld, spec_data, spec_coef, id_syn_ele);
                 if (hInfo->error > 0)
-                    goto return_on_error;
+                    return elements;
                 break;
             case ID_CPE:
-                CHCHECK2;
-                elements[ch_ele] = decode_cpe(hDecoder,
-                    hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-                channels += 2; ch_ele++;
+                elements[ch_ele++] = decode_cpe(hDecoder,
+                    hInfo, ld, spec_data, spec_coef, id_syn_ele);
                 if (hInfo->error > 0)
-                    goto return_on_error;
+                    return elements;
                 break;
             case ID_CCE: /* not implemented yet */
                 hInfo->error = 6;
-                goto return_on_error;
-                break;
+                return elements;
             case ID_DSE:
                 data_stream_element(ld);
                 break;
             case ID_PCE:
                 if ((hInfo->error = program_config_element(pce, ld)) > 0)
-                    goto return_on_error;
+                    return elements;
                 break;
             case ID_FIL:
                 if ((hInfo->error = fill_element(ld, drc)) > 0)
-                    goto return_on_error;
+                    return elements;
                 break;
             }
         }
@@ -368,155 +370,74 @@
         switch (hDecoder->channelConfiguration)
         {
         case 1:
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
             if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         case 2:
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
             if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         case 3:
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
             if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         case 4:
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
             if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
-            if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         case 5:
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
             if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         case 6:
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_LFE);
             if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_LFE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
-            if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         case 7:
-            id_syn_ele = ID_SCE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_SCE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_cpe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_CPE);
+            elements[ch_ele++] = decode_sce_lfe(hDecoder,
+                hInfo, ld, spec_data, spec_coef, ID_LFE);
             if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_CPE;
-            CHCHECK2;
-            elements[ch_ele] = decode_cpe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            channels += 2; ch_ele++;
-            if (hInfo->error > 0)
-                goto return_on_error;
-            id_syn_ele = ID_LFE;
-            CHCHECK1;
-            elements[ch_ele] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_data, spec_coef, channels, id_syn_ele);
-            ch_ele++; channels++;
-            if (hInfo->error > 0)
-                goto return_on_error;
+                return elements;
             break;
         default:
             hInfo->error = 7;
-            goto return_on_error;
+            return elements;
         }
 #if 0
         cnt = bits_to_decode() / 8;
@@ -527,10 +448,6 @@
 #endif
     }
 #endif
-
-return_on_error:
-    *out_ch_ele = ch_ele;
-    *out_channels = channels;
 
     return elements;
 }